From 36c4f3df2a59e3adc59a170bf85118138daf9c30 Mon Sep 17 00:00:00 2001 From: Abhisar Sinha <63767682+abh1sar@users.noreply.github.com> Date: Fri, 29 Aug 2025 03:03:51 +0530 Subject: [PATCH 1/7] Track volume usage data at vm granularity as well. --- .../java/com/cloud/event/UsageEventUtils.java | 12 ++ .../orchestration/VolumeOrchestrator.java | 4 +- .../java/com/cloud/event/UsageEventVO.java | 22 +++ .../cloud/event/dao/UsageEventDaoImpl.java | 8 +- .../upgrade/dao/Upgrade41930to41940.java | 60 +++++++ .../java/com/cloud/usage/UsageVolumeVO.java | 14 +- .../cloud/usage/dao/UsageStorageDaoImpl.java | 2 + .../com/cloud/usage/dao/UsageVolumeDao.java | 6 +- .../cloud/usage/dao/UsageVolumeDaoImpl.java | 87 ++++----- .../META-INF/db/schema-41930to41940.sql | 27 +++ .../java/com/cloud/api/ApiResponseHelper.java | 3 + .../java/com/cloud/hypervisor/KVMGuru.java | 6 + .../cloud/storage/VolumeApiServiceImpl.java | 15 +- .../storage/listener/VolumeStateListener.java | 2 +- .../java/com/cloud/vm/UserVmManagerImpl.java | 6 +- .../storage/VolumeApiServiceImplTest.java | 8 +- .../com/cloud/usage/UsageManagerImpl.java | 168 ++++++++++-------- .../cloud/usage/parser/VolumeUsageParser.java | 23 ++- 18 files changed, 320 insertions(+), 153 deletions(-) create mode 100644 engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade41930to41940.java create mode 100644 engine/schema/src/main/resources/META-INF/db/schema-41930to41940.sql diff --git a/engine/components-api/src/main/java/com/cloud/event/UsageEventUtils.java b/engine/components-api/src/main/java/com/cloud/event/UsageEventUtils.java index 94fbb7a80af8..1c88c7df124c 100644 --- a/engine/components-api/src/main/java/com/cloud/event/UsageEventUtils.java +++ b/engine/components-api/src/main/java/com/cloud/event/UsageEventUtils.java @@ -94,6 +94,14 @@ public static void publishUsageEvent(String usageType, long accountId, long zone } + public static void publishUsageEvent(String usageType, long accountId, long zoneId, long resourceId, String resourceName, Long offeringId, Long templateId, + Long size, String entityType, String entityUUID, Long vmId, boolean displayResource) { + if (displayResource) { + saveUsageEvent(usageType, accountId, zoneId, resourceId, offeringId, templateId, size, vmId, resourceName); + } + publishUsageEvent(usageType, accountId, zoneId, entityType, entityUUID); + } + public static void publishUsageEvent(String usageType, long accountId, long zoneId, long resourceId, String resourceName, Long offeringId, Long templateId, Long size, Long virtualSize, String entityType, String entityUUID, Map details) { saveUsageEvent(usageType, accountId, zoneId, resourceId, resourceName, offeringId, templateId, size, virtualSize, details); @@ -202,6 +210,10 @@ public static void saveUsageEvent(String usageType, long accountId, long zoneId, s_usageEventDao.persist(new UsageEventVO(usageType, accountId, zoneId, vmId, securityGroupId)); } + public static void saveUsageEvent(String usageType, long accountId, long zoneId, long resourceId, Long offeringId, Long templateId, Long size, Long vmId, String resourceName) { + s_usageEventDao.persist(new UsageEventVO(usageType, accountId, zoneId, resourceId, offeringId, templateId, size, vmId, resourceName)); + } + private static void publishUsageEvent(String usageEventType, Long accountId, Long zoneId, String resourceType, String resourceUUID) { String configKey = "publish.usage.events"; String value = s_configDao.getValue(configKey); diff --git a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java index ba50d5ff9fac..f14c07e97e6f 100644 --- a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java +++ b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java @@ -900,7 +900,7 @@ public DiskProfile allocateRawVolume(Type type, String name, DiskOffering offeri // Save usage event and update resource count for user vm volumes if (vm.getType() == VirtualMachine.Type.User) { UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), offering.getId(), null, size, - Volume.class.getName(), vol.getUuid(), vol.isDisplayVolume()); + Volume.class.getName(), vol.getUuid(), vol.getInstanceId(), vol.isDisplayVolume()); _resourceLimitMgr.incrementVolumeResourceCount(vm.getAccountId(), vol.isDisplayVolume(), vol.getSize(), offering); } DiskProfile diskProfile = toDiskProfile(vol, offering); @@ -980,7 +980,7 @@ private DiskProfile allocateTemplatedVolume(Type type, String name, DiskOffering } UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), offeringId, vol.getTemplateId(), size, - Volume.class.getName(), vol.getUuid(), vol.isDisplayVolume()); + Volume.class.getName(), vol.getUuid(), vol.getInstanceId(), vol.isDisplayVolume()); _resourceLimitMgr.incrementVolumeResourceCount(vm.getAccountId(), vol.isDisplayVolume(), vol.getSize(), offering); } diff --git a/engine/schema/src/main/java/com/cloud/event/UsageEventVO.java b/engine/schema/src/main/java/com/cloud/event/UsageEventVO.java index 3fc9fda94873..41ecec0c7fb8 100644 --- a/engine/schema/src/main/java/com/cloud/event/UsageEventVO.java +++ b/engine/schema/src/main/java/com/cloud/event/UsageEventVO.java @@ -75,6 +75,9 @@ public enum DynamicParameters { @Column(name = "virtual_size") private Long virtualSize; + @Column(name = "vm_id") + private Long vmId; + public UsageEventVO() { } @@ -143,6 +146,18 @@ public UsageEventVO(String usageType, long accountId, long zoneId, long vmId, lo this.offeringId = securityGroupId; } + public UsageEventVO(String usageType, long accountId, long zoneId, long resourceId, Long offeringId, Long templateId, Long size, Long vmId, String resourceName) { + this.type = usageType; + this.accountId = accountId; + this.zoneId = zoneId; + this.resourceId = resourceId; + this.offeringId = offeringId; + this.templateId = templateId; + this.size = size; + this.vmId = vmId; + this.resourceName = resourceName; + } + @Override public long getId() { return id; @@ -248,4 +263,11 @@ public void setVirtualSize(Long virtualSize) { this.virtualSize = virtualSize; } + public Long getVmId() { + return vmId; + } + + public void setVmId(Long vmId) { + this.vmId = vmId; + } } diff --git a/engine/schema/src/main/java/com/cloud/event/dao/UsageEventDaoImpl.java b/engine/schema/src/main/java/com/cloud/event/dao/UsageEventDaoImpl.java index fdef509da5bd..bce9c474e2d2 100644 --- a/engine/schema/src/main/java/com/cloud/event/dao/UsageEventDaoImpl.java +++ b/engine/schema/src/main/java/com/cloud/event/dao/UsageEventDaoImpl.java @@ -45,11 +45,11 @@ public class UsageEventDaoImpl extends GenericDaoBase implem private final SearchBuilder latestEventsSearch; private final SearchBuilder IpeventsSearch; private static final String COPY_EVENTS = - "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) " - + "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 <= ? "; + "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) " + + "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 <= ? "; private static final String COPY_ALL_EVENTS = - "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) " - + "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 <= ?"; + "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) " + + "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 <= ?"; private static final String COPY_EVENT_DETAILS = "INSERT INTO cloud_usage.usage_event_details (id, usage_event_id, name, value) " + "SELECT id, usage_event_id, name, value FROM cloud.usage_event_details vmevtDetails WHERE vmevtDetails.usage_event_id > ? and vmevtDetails.usage_event_id <= ? "; private static final String COPY_ALL_EVENT_DETAILS = "INSERT INTO cloud_usage.usage_event_details (id, usage_event_id, name, value) " diff --git a/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade41930to41940.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade41930to41940.java new file mode 100644 index 000000000000..5e2b3344c0a7 --- /dev/null +++ b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade41930to41940.java @@ -0,0 +1,60 @@ +// 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 com.cloud.upgrade.dao; + +import java.io.InputStream; +import java.sql.Connection; + +import com.cloud.utils.exception.CloudRuntimeException; + +public class Upgrade41930to41940 implements DbUpgrade { + + @Override + public String[] getUpgradableVersionRange() { + return new String[]{"4.19.3.0", "4.19.4.0"}; + } + + @Override + public String getUpgradedVersion() { + return "4.19.4.0"; + } + + @Override + public boolean supportsRollingUpgrade() { + return false; + } + + @Override + public InputStream[] getPrepareScripts() { + final String scriptFile = "META-INF/db/schema-41930to41940.sql"; + final InputStream script = Thread.currentThread().getContextClassLoader().getResourceAsStream(scriptFile); + if (script == null) { + throw new CloudRuntimeException("Unable to find " + scriptFile); + } + + return new InputStream[]{script}; + } + + @Override + public void performDataMigration(Connection conn) { + } + + @Override + public InputStream[] getCleanupScripts() { + return new InputStream[0]; + } +} diff --git a/engine/schema/src/main/java/com/cloud/usage/UsageVolumeVO.java b/engine/schema/src/main/java/com/cloud/usage/UsageVolumeVO.java index 96abd2d69c08..6d5315e33464 100644 --- a/engine/schema/src/main/java/com/cloud/usage/UsageVolumeVO.java +++ b/engine/schema/src/main/java/com/cloud/usage/UsageVolumeVO.java @@ -59,6 +59,9 @@ public class UsageVolumeVO implements InternalIdentity { @Column(name = "size") private long size; + @Column(name = "vm_id") + private Long vmId; + @Column(name = "created") @Temporal(value = TemporalType.TIMESTAMP) private Date created = null; @@ -70,13 +73,14 @@ public class UsageVolumeVO implements InternalIdentity { protected UsageVolumeVO() { } - public UsageVolumeVO(long id, long zoneId, long accountId, long domainId, Long diskOfferingId, Long templateId, long size, Date created, Date deleted) { + public UsageVolumeVO(long id, long zoneId, long accountId, long domainId, Long diskOfferingId, Long templateId, Long vmId, long size, Date created, Date deleted) { this.volumeId = id; this.zoneId = zoneId; this.accountId = accountId; this.domainId = domainId; this.diskOfferingId = diskOfferingId; this.templateId = templateId; + this.vmId = vmId; this.size = size; this.created = created; this.deleted = deleted; @@ -126,4 +130,12 @@ public void setDeleted(Date deleted) { public long getVolumeId() { return volumeId; } + + public Long getVmId() { + return vmId; + } + + public void setVmId(Long vmId) { + this.vmId = vmId; + } } diff --git a/engine/schema/src/main/java/com/cloud/usage/dao/UsageStorageDaoImpl.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageStorageDaoImpl.java index 1da533493997..f863cd1e3a35 100644 --- a/engine/schema/src/main/java/com/cloud/usage/dao/UsageStorageDaoImpl.java +++ b/engine/schema/src/main/java/com/cloud/usage/dao/UsageStorageDaoImpl.java @@ -57,6 +57,7 @@ public UsageStorageDaoImpl() { IdSearch.and("accountId", IdSearch.entity().getAccountId(), SearchCriteria.Op.EQ); IdSearch.and("id", IdSearch.entity().getEntityId(), SearchCriteria.Op.EQ); IdSearch.and("type", IdSearch.entity().getStorageType(), SearchCriteria.Op.EQ); + IdSearch.and("deleted", IdSearch.entity().getDeleted(), SearchCriteria.Op.NULL); IdSearch.done(); IdZoneSearch = createSearchBuilder(); @@ -74,6 +75,7 @@ public List listById(long accountId, long id, int type) { sc.setParameters("accountId", accountId); sc.setParameters("id", id); sc.setParameters("type", type); + sc.setParameters("deleted", null); return listBy(sc, null); } diff --git a/engine/schema/src/main/java/com/cloud/usage/dao/UsageVolumeDao.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageVolumeDao.java index 09590b739930..05287240f254 100644 --- a/engine/schema/src/main/java/com/cloud/usage/dao/UsageVolumeDao.java +++ b/engine/schema/src/main/java/com/cloud/usage/dao/UsageVolumeDao.java @@ -23,9 +23,7 @@ import com.cloud.utils.db.GenericDao; public interface UsageVolumeDao extends GenericDao { - public void removeBy(long userId, long id); - - public void update(UsageVolumeVO usage); - public List getUsageRecords(Long accountId, Long domainId, Date startDate, Date endDate, boolean limit, int page); + + List listByVolumeId(long volumeId, long accountId); } diff --git a/engine/schema/src/main/java/com/cloud/usage/dao/UsageVolumeDaoImpl.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageVolumeDaoImpl.java index 4662a6f26ce8..2f80ec835077 100644 --- a/engine/schema/src/main/java/com/cloud/usage/dao/UsageVolumeDaoImpl.java +++ b/engine/schema/src/main/java/com/cloud/usage/dao/UsageVolumeDaoImpl.java @@ -18,81 +18,47 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; -import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.TimeZone; -import com.cloud.exception.CloudException; +import javax.annotation.PostConstruct; + +import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.usage.UsageVolumeVO; import com.cloud.utils.DateUtil; import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.TransactionLegacy; @Component public class UsageVolumeDaoImpl extends GenericDaoBase implements UsageVolumeDao { - protected static final String REMOVE_BY_USERID_VOLID = "DELETE FROM usage_volume WHERE account_id = ? AND volume_id = ?"; - protected static final String UPDATE_DELETED = "UPDATE usage_volume SET deleted = ? WHERE account_id = ? AND volume_id = ? and deleted IS NULL"; - 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 " + 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 " + "FROM usage_volume " + "WHERE account_id = ? AND ((deleted IS NULL) OR (created BETWEEN ? AND ?) OR " + " (deleted BETWEEN ? AND ?) OR ((created <= ?) AND (deleted >= ?)))"; - 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 " + 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 " + "FROM usage_volume " + "WHERE domain_id = ? AND ((deleted IS NULL) OR (created BETWEEN ? AND ?) OR " + " (deleted BETWEEN ? AND ?) OR ((created <= ?) AND (deleted >= ?)))"; - 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 " + 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 " + "FROM usage_volume " + "WHERE (deleted IS NULL) OR (created BETWEEN ? AND ?) OR " + " (deleted BETWEEN ? AND ?) OR ((created <= ?) AND (deleted >= ?))"; + private SearchBuilder volumeSearch; public UsageVolumeDaoImpl() { } - @Override - public void removeBy(long accountId, long volId) { - TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); - try { - txn.start(); - try(PreparedStatement pstmt = txn.prepareStatement(REMOVE_BY_USERID_VOLID);) { - if (pstmt != null) { - pstmt.setLong(1, accountId); - pstmt.setLong(2, volId); - pstmt.executeUpdate(); - } - }catch (SQLException e) { - throw new CloudException("Error removing usageVolumeVO:"+e.getMessage(), e); - } - txn.commit(); - } catch (Exception e) { - txn.rollback(); - logger.warn("Error removing usageVolumeVO:"+e.getMessage(), e); - } finally { - txn.close(); - } - } - - @Override - public void update(UsageVolumeVO usage) { - TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); - PreparedStatement pstmt = null; - try { - txn.start(); - if (usage.getDeleted() != null) { - pstmt = txn.prepareAutoCloseStatement(UPDATE_DELETED); - pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), usage.getDeleted())); - pstmt.setLong(2, usage.getAccountId()); - pstmt.setLong(3, usage.getVolumeId()); - pstmt.executeUpdate(); - } - txn.commit(); - } catch (Exception e) { - txn.rollback(); - logger.warn("Error updating UsageVolumeVO", e); - } finally { - txn.close(); - } + @PostConstruct + protected void init() { + volumeSearch = createSearchBuilder(); + volumeSearch.and("accountId", volumeSearch.entity().getAccountId(), SearchCriteria.Op.EQ); + volumeSearch.and("volumeId", volumeSearch.entity().getVolumeId(), SearchCriteria.Op.EQ); + volumeSearch.and("deleted", volumeSearch.entity().getDeleted(), SearchCriteria.Op.NULL); + volumeSearch.done(); } @Override @@ -150,11 +116,15 @@ public List getUsageRecords(Long accountId, Long domainId, Date s if (tId == 0) { tId = null; } - long size = Long.valueOf(rs.getLong(7)); + Long vmId = Long.valueOf(rs.getLong(7)); + if (vmId == 0) { + vmId = null; + } + long size = Long.valueOf(rs.getLong(8)); Date createdDate = null; Date deletedDate = null; - String createdTS = rs.getString(8); - String deletedTS = rs.getString(9); + String createdTS = rs.getString(9); + String deletedTS = rs.getString(10); if (createdTS != null) { createdDate = DateUtil.parseDateString(s_gmtTimeZone, createdTS); @@ -163,7 +133,7 @@ public List getUsageRecords(Long accountId, Long domainId, Date s deletedDate = DateUtil.parseDateString(s_gmtTimeZone, deletedTS); } - usageRecords.add(new UsageVolumeVO(vId, zoneId, acctId, dId, doId, tId, size, createdDate, deletedDate)); + usageRecords.add(new UsageVolumeVO(vId, zoneId, acctId, dId, doId, tId, vmId, size, createdDate, deletedDate)); } } catch (Exception e) { txn.rollback(); @@ -174,4 +144,13 @@ public List getUsageRecords(Long accountId, Long domainId, Date s return usageRecords; } + + @Override + public List listByVolumeId(long volumeId, long accountId) { + SearchCriteria sc = volumeSearch.create(); + sc.setParameters("accountId", accountId); + sc.setParameters("volumeId", volumeId); + sc.setParameters("deleted", null); + return listBy(sc); + } } diff --git a/engine/schema/src/main/resources/META-INF/db/schema-41930to41940.sql b/engine/schema/src/main/resources/META-INF/db/schema-41930to41940.sql new file mode 100644 index 000000000000..d43e4e8ee5a1 --- /dev/null +++ b/engine/schema/src/main/resources/META-INF/db/schema-41930to41940.sql @@ -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. + +--; +-- Schema upgrade from 4.19.3.0 to 4.19.4.0 +--; + +-- Add vm_id column to usage_event table for volume usage events +ALTER TABLE `cloud`.`usage_event` ADD COLUMN `vm_id` bigint unsigned NULL COMMENT 'VM ID associated with volume usage events'; +ALTER TABLE `cloud_usage`.`usage_event` ADD COLUMN `vm_id` bigint unsigned NULL COMMENT 'VM ID associated with volume usage events'; + +-- Add vm_id column to cloud_usage.usage_volume table +ALTER TABLE `cloud_usage`.`usage_volume` ADD COLUMN `vm_id` bigint unsigned NULL COMMENT 'VM ID associated with the volume usage'; diff --git a/server/src/main/java/com/cloud/api/ApiResponseHelper.java b/server/src/main/java/com/cloud/api/ApiResponseHelper.java index 64d6e8b6929d..39efec0b7e6c 100644 --- a/server/src/main/java/com/cloud/api/ApiResponseHelper.java +++ b/server/src/main/java/com/cloud/api/ApiResponseHelper.java @@ -4330,6 +4330,9 @@ public UsageRecordResponse createUsageResponse(Usage usageRecord, Map t // For the Resize Volume Event, this publishes an event with an incorrect disk offering ID, so do nothing for now } else { UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), vol.getDiskOfferingId(), null, vol.getSize(), - Volume.class.getName(), vol.getUuid(), vol.isDisplayVolume()); + Volume.class.getName(), vol.getUuid(), instanceId, vol.isDisplayVolume()); } } else if (transition.getToState() == State.Destroy && vol.getVolumeType() != Volume.Type.ROOT) { //Do not Publish Usage Event for ROOT Disk as it would have been published already while destroying a VM UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index cd7d198eb611..7739f714d1ef 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -2402,6 +2402,8 @@ protected void recoverRootVolume(VolumeVO volume, Long vmId) { if (Volume.State.Destroy.equals(volume.getState())) { _volumeService.recoverVolume(volume.getId()); _volsDao.attachVolume(volume.getId(), vmId, ROOT_DEVICE_ID); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_ATTACH, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), + volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(), volume.getUuid(), vmId, volume.isDisplay()); } else { _volumeService.publishVolumeCreationUsageEvent(volume); } @@ -8090,7 +8092,7 @@ protected void updateVolumesOwner(final List volumes, Account oldAccou logger.trace("Generating a create volume event for volume [{}].", volume); UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), - volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(), volume.getUuid(), volume.isDisplayVolume()); + volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(), volume.getUuid(), volume.getInstanceId(), volume.isDisplayVolume()); } } @@ -8863,6 +8865,8 @@ public Pair doInTransaction(final TransactionStatus status) th handleManagedStorage(vm, root); _volsDao.attachVolume(newVol.getId(), vmId, newVol.getDeviceId()); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_ATTACH, newVol.getAccountId(), newVol.getDataCenterId(), newVol.getId(), newVol.getName(), + newVol.getDiskOfferingId(), newVol.getTemplateId(), newVol.getSize(), Volume.class.getName(), newVol.getUuid(), vmId, newVol.isDisplay()); // Detach, destroy and create the usage event for the old root volume. _volsDao.detachVolume(root.getId()); diff --git a/server/src/test/java/com/cloud/storage/VolumeApiServiceImplTest.java b/server/src/test/java/com/cloud/storage/VolumeApiServiceImplTest.java index 79be3695fbde..0575b430ef10 100644 --- a/server/src/test/java/com/cloud/storage/VolumeApiServiceImplTest.java +++ b/server/src/test/java/com/cloud/storage/VolumeApiServiceImplTest.java @@ -1545,7 +1545,7 @@ public void publishVolumeCreationUsageEventTestNullDiskOfferingId() { volumeApiServiceImpl.publishVolumeCreationUsageEvent(volumeVoMock); usageEventUtilsMocked.verify(() -> UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volumeVoMock.getAccountId(), volumeVoMock.getDataCenterId(), volumeVoMock.getId(), volumeVoMock.getName(), - null, volumeVoMock.getTemplateId(), volumeVoMock.getSize(), Volume.class.getName(), volumeVoMock.getUuid(), volumeVoMock.isDisplay())); + null, volumeVoMock.getTemplateId(), volumeVoMock.getSize(), Volume.class.getName(), volumeVoMock.getUuid(), volumeVoMock.getInstanceId(), volumeVoMock.isDisplay())); } } @@ -1558,7 +1558,7 @@ public void publishVolumeCreationUsageEventTestNullDiskOfferingVo() { volumeApiServiceImpl.publishVolumeCreationUsageEvent(volumeVoMock); usageEventUtilsMocked.verify(() -> UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volumeVoMock.getAccountId(), volumeVoMock.getDataCenterId(), volumeVoMock.getId(), volumeVoMock.getName(), - null, volumeVoMock.getTemplateId(), volumeVoMock.getSize(), Volume.class.getName(), volumeVoMock.getUuid(), volumeVoMock.isDisplay())); + null, volumeVoMock.getTemplateId(), volumeVoMock.getSize(), Volume.class.getName(), volumeVoMock.getUuid(), volumeVoMock.getInstanceId(), volumeVoMock.isDisplay())); } } @@ -1573,7 +1573,7 @@ public void publishVolumeCreationUsageEventTestDiskOfferingVoTypeNotDisk() { volumeApiServiceImpl.publishVolumeCreationUsageEvent(volumeVoMock); usageEventUtilsMocked.verify(() -> UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volumeVoMock.getAccountId(), volumeVoMock.getDataCenterId(), volumeVoMock.getId(), volumeVoMock.getName(), - null, volumeVoMock.getTemplateId(), volumeVoMock.getSize(), Volume.class.getName(), volumeVoMock.getUuid(), volumeVoMock.isDisplay())); + null, volumeVoMock.getTemplateId(), volumeVoMock.getSize(), Volume.class.getName(), volumeVoMock.getUuid(), volumeVoMock.getInstanceId(), volumeVoMock.isDisplay())); } } @@ -1589,7 +1589,7 @@ public void publishVolumeCreationUsageEventTestOfferingIdNotNull() { volumeApiServiceImpl.publishVolumeCreationUsageEvent(volumeVoMock); usageEventUtilsMocked.verify(() -> UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volumeVoMock.getAccountId(), volumeVoMock.getDataCenterId(), volumeVoMock.getId(), volumeVoMock.getName(), - offeringMockId, volumeVoMock.getTemplateId(), volumeVoMock.getSize(), Volume.class.getName(), volumeVoMock.getUuid(), volumeVoMock.isDisplay())); + offeringMockId, volumeVoMock.getTemplateId(), volumeVoMock.getSize(), Volume.class.getName(), volumeVoMock.getUuid(), volumeVoMock.getInstanceId(), volumeVoMock.isDisplay())); } } diff --git a/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java b/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java index 49d799997162..b20da617a77f 100644 --- a/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java +++ b/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java @@ -1008,7 +1008,12 @@ private boolean isIPEvent(String eventType) { private boolean isVolumeEvent(String eventType) { return eventType != null && - (eventType.equals(EventTypes.EVENT_VOLUME_CREATE) || eventType.equals(EventTypes.EVENT_VOLUME_DELETE) || eventType.equals(EventTypes.EVENT_VOLUME_RESIZE) || eventType.equals(EventTypes.EVENT_VOLUME_UPLOAD)); + (eventType.equals(EventTypes.EVENT_VOLUME_CREATE) || + eventType.equals(EventTypes.EVENT_VOLUME_DELETE) || + eventType.equals(EventTypes.EVENT_VOLUME_RESIZE) || + eventType.equals(EventTypes.EVENT_VOLUME_UPLOAD) || + eventType.equals(EventTypes.EVENT_VOLUME_ATTACH) || + eventType.equals(EventTypes.EVENT_VOLUME_DETACH)); } private boolean isTemplateEvent(String eventType) { @@ -1424,92 +1429,113 @@ private void createIPHelperEvent(UsageEventVO event) { } } + private void deleteExistingSecondaryStorageUsageForVolume(long volId, long accountId, Date deletedDate) { + List storageVOs = _usageStorageDao.listById(accountId, volId, StorageTypes.VOLUME); + for (UsageStorageVO storageVO : storageVOs) { + s_logger.debug(String.format("Setting the volume with id: {} to 'deleted' in the usage_storage table for account: {}.", volId, accountId)); + storageVO.setDeleted(deletedDate); + _usageStorageDao.update(storageVO); + } + } + + private void deleteExistingInstanceVolumeUsage(long volId, long accountId, Date deletedDate) { + List volumesVOs = _usageVolumeDao.listByVolumeId(volId, accountId); + for (UsageVolumeVO volumesVO : volumesVOs) { + if (volumesVO.getVmId() != null) { + s_logger.debug(String.format("Setting the volume with id: {} for instance id: {} to 'deleted' in the usage_volume table for account {}.", + volumesVO.getVolumeId(), volumesVO.getVmId(), accountId)); + volumesVO.setDeleted(deletedDate); + _usageVolumeDao.update(volumesVO.getId(), volumesVO); + } + } + } + + private void deleteExistingVolumeUsage(long volId, long accountId, Date deletedDate) { + List volumesVOs = _usageVolumeDao.listByVolumeId(volId, accountId); + for (UsageVolumeVO volumesVO : volumesVOs) { + s_logger.debug(String.format("Setting the volume with id: {} to 'deleted' in the usage_storage table for account: {}.", volId, accountId)); + volumesVO.setDeleted(deletedDate); + _usageVolumeDao.update(volumesVO.getId(), volumesVO); + } + } + private void createVolumeHelperEvent(UsageEventVO event) { long volId = event.getResourceId(); + Account acct = _accountDao.findByIdIncludingRemoved(event.getAccountId()); + List volumesVOs; + UsageVolumeVO volumeVO; - if (EventTypes.EVENT_VOLUME_CREATE.equals(event.getType())) { - //For volumes which are 'attached' successfully, set the 'deleted' column in the usage_storage table, + switch (event.getType()) { + case EventTypes.EVENT_VOLUME_CREATE: + //For volumes which are 'attached' successfully from uploaded state, set the 'deleted' column in the usage_storage table, //so that the secondary storage should stop accounting and only primary will be accounted. - SearchCriteria sc = _usageStorageDao.createSearchCriteria(); - sc.addAnd("entityId", SearchCriteria.Op.EQ, volId); - sc.addAnd("storageType", SearchCriteria.Op.EQ, StorageTypes.VOLUME); - List volumesVOs = _usageStorageDao.search(sc, null); - if (volumesVOs != null) { - if (volumesVOs.size() == 1) { - logger.debug("Setting the volume with id: " + volId + " to 'deleted' in the usage_storage table."); - volumesVOs.get(0).setDeleted(event.getCreateDate()); - _usageStorageDao.update(volumesVOs.get(0)); - } - } - } - if (EventTypes.EVENT_VOLUME_CREATE.equals(event.getType()) || EventTypes.EVENT_VOLUME_RESIZE.equals(event.getType())) { - SearchCriteria sc = _usageVolumeDao.createSearchCriteria(); - sc.addAnd("accountId", SearchCriteria.Op.EQ, event.getAccountId()); - sc.addAnd("volumeId", SearchCriteria.Op.EQ, volId); - sc.addAnd("deleted", SearchCriteria.Op.NULL); - List volumesVOs = _usageVolumeDao.search(sc, null); + deleteExistingSecondaryStorageUsageForVolume(volId, event.getAccountId(), event.getCreateDate()); + + volumesVOs = _usageVolumeDao.listByVolumeId(volId, event.getAccountId()); if (volumesVOs.size() > 0) { //This is a safeguard to avoid double counting of volumes. logger.error("Found duplicate usage entry for volume: " + volId + " assigned to account: " + event.getAccountId() + "; marking as deleted..."); + deleteExistingVolumeUsage(volId, event.getAccountId(), event.getCreateDate()); } - //an entry exists if it is a resize volume event. marking the existing deleted and creating a new one in the case of resize. - for (UsageVolumeVO volumesVO : volumesVOs) { - if (logger.isDebugEnabled()) { - logger.debug("deleting volume: " + volumesVO.getId() + " from account: " + volumesVO.getAccountId()); - } - volumesVO.setDeleted(event.getCreateDate()); - _usageVolumeDao.update(volumesVO); - } - if (logger.isDebugEnabled()) { - logger.debug("create volume with id : " + volId + " for account: " + event.getAccountId()); - } - Account acct = _accountDao.findByIdIncludingRemoved(event.getAccountId()); - UsageVolumeVO volumeVO = new UsageVolumeVO(volId, event.getZoneId(), event.getAccountId(), acct.getDomainId(), event.getOfferingId(), event.getTemplateId(), event.getSize(), event.getCreateDate(), null); + + logger.debug(String.format("Creating a new entry in usage_volume for volume with id: {} for account: {}", volId, event.getVmId(), event.getAccountId())); + volumeVO = new UsageVolumeVO(volId, event.getZoneId(), event.getAccountId(), acct.getDomainId(), event.getOfferingId(), event.getTemplateId(), null, event.getSize(), event.getCreateDate(), null); _usageVolumeDao.persist(volumeVO); - } else if (EventTypes.EVENT_VOLUME_DELETE.equals(event.getType())) { - SearchCriteria sc = _usageVolumeDao.createSearchCriteria(); - sc.addAnd("accountId", SearchCriteria.Op.EQ, event.getAccountId()); - sc.addAnd("volumeId", SearchCriteria.Op.EQ, volId); - sc.addAnd("deleted", SearchCriteria.Op.NULL); - List volumesVOs = _usageVolumeDao.search(sc, null); - if (volumesVOs.size() > 1) { - logger.warn("More that one usage entry for volume: " + volId + " assigned to account: " + event.getAccountId() + "; marking them all as deleted..."); - } - for (UsageVolumeVO volumesVO : volumesVOs) { - if (logger.isDebugEnabled()) { - logger.debug("deleting volume: " + volumesVO.getId() + " from account: " + volumesVO.getAccountId()); - } - volumesVO.setDeleted(event.getCreateDate()); // there really shouldn't be more than one - _usageVolumeDao.update(volumesVO); - } - } else if (EventTypes.EVENT_VOLUME_UPLOAD.equals(event.getType())) { - //For Upload event add an entry to the usage_storage table. - SearchCriteria sc = _usageStorageDao.createSearchCriteria(); - sc.addAnd("accountId", SearchCriteria.Op.EQ, event.getAccountId()); - sc.addAnd("entityId", SearchCriteria.Op.EQ, volId); - sc.addAnd("storageType", SearchCriteria.Op.EQ, StorageTypes.VOLUME); - sc.addAnd("deleted", SearchCriteria.Op.NULL); - List volumesVOs = _usageStorageDao.search(sc, null); - if (volumesVOs.size() > 0) { - //This is a safeguard to avoid double counting of volumes. - logger.error("Found duplicate usage entry for volume: " + volId + " assigned to account: " + event.getAccountId() + "; marking as deleted..."); + if (event.getVmId() != null) { + volumeVO = new UsageVolumeVO(volId, event.getZoneId(), event.getAccountId(), acct.getDomainId(), event.getOfferingId(), event.getTemplateId(), event.getVmId(), event.getSize(), event.getCreateDate(), null); + _usageVolumeDao.persist(volumeVO); } - for (UsageStorageVO volumesVO : volumesVOs) { - if (logger.isDebugEnabled()) { - logger.debug("deleting volume: " + volumesVO.getId() + " from account: " + volumesVO.getAccountId()); + break; + + case EventTypes.EVENT_VOLUME_RESIZE: + volumesVOs = _usageVolumeDao.listByVolumeId(volId, event.getAccountId()); + for (UsageVolumeVO volumesVO : volumesVOs) { + String delete_msg = String.format("Setting the volume with id: {} to 'deleted' in the usage_storage table for account: {}.", volId, event.getAccountId()); + String create_msg = String.format("Creating a new entry in usage_volume for volume with id: {} after resize for account: {}", volId, event.getAccountId()); + Long vmId = null; + if (vmId != null) { + vmId = volumesVO.getVmId(); + delete_msg = String.format("Setting the volume with id: {} for instance id: {} to 'deleted' in the usage_storage table for account: {}.", + volId, vmId, event.getAccountId()); + create_msg = String.format("Creating a new entry in usage_volume for volume with id: {} and instance id: {} after resize for account: {}", + volId, vmId, event.getAccountId()); } + logger.debug(delete_msg); volumesVO.setDeleted(event.getCreateDate()); - _usageStorageDao.update(volumesVO); - } + _usageVolumeDao.update(volumesVO.getId(), volumesVO); - if (logger.isDebugEnabled()) { - logger.debug("create volume with id : " + volId + " for account: " + event.getAccountId()); + logger.debug(create_msg); + volumeVO = new UsageVolumeVO(volId, event.getZoneId(), event.getAccountId(), acct.getDomainId(), event.getOfferingId(), event.getTemplateId(), vmId, event.getSize(), event.getCreateDate(), null); + _usageVolumeDao.persist(volumeVO); } - Account acct = _accountDao.findByIdIncludingRemoved(event.getAccountId()); - UsageStorageVO volumeVO = new UsageStorageVO(volId, event.getZoneId(), event.getAccountId(), acct.getDomainId(), StorageTypes.VOLUME, event.getTemplateId(), event.getSize(), event.getCreateDate(), null); - _usageStorageDao.persist(volumeVO); + break; + + case EventTypes.EVENT_VOLUME_DELETE: + deleteExistingVolumeUsage(volId, event.getAccountId(), event.getCreateDate()); + break; + + case EventTypes.EVENT_VOLUME_ATTACH: + deleteExistingInstanceVolumeUsage(event.getResourceId(), event.getAccountId(), event.getCreateDate()); + + logger.debug(String.format("Creating a new entry in usage_volume for volume with id: {}, and instance id: {} for account: {}", + volId, event.getVmId(), event.getAccountId())); + volumeVO = new UsageVolumeVO(volId, event.getZoneId(), event.getAccountId(), acct.getDomainId(), event.getOfferingId(), event.getTemplateId(), event.getVmId(), event.getSize(), event.getCreateDate(), null); + _usageVolumeDao.persist(volumeVO); + break; + + case EventTypes.EVENT_VOLUME_DETACH: + deleteExistingInstanceVolumeUsage(event.getResourceId(), event.getAccountId(), event.getCreateDate()); + break; + + case EventTypes.EVENT_VOLUME_UPLOAD: + deleteExistingSecondaryStorageUsageForVolume(volId, event.getAccountId(), event.getCreateDate()); + + logger.debug(String.format("Creating a new entry in usage_storage for volume with id : {} for account: {}", volId, event.getAccountId())); + UsageStorageVO storageVO = new UsageStorageVO(volId, event.getZoneId(), event.getAccountId(), acct.getDomainId(), StorageTypes.VOLUME, event.getTemplateId(), event.getSize(), event.getCreateDate(), null); + _usageStorageDao.persist(storageVO); + break; } } diff --git a/usage/src/main/java/com/cloud/usage/parser/VolumeUsageParser.java b/usage/src/main/java/com/cloud/usage/parser/VolumeUsageParser.java index e834b713d420..0210b899e8c9 100644 --- a/usage/src/main/java/com/cloud/usage/parser/VolumeUsageParser.java +++ b/usage/src/main/java/com/cloud/usage/parser/VolumeUsageParser.java @@ -73,12 +73,13 @@ protected boolean parse(AccountVO account, Date startDate, Date endDate) { for (UsageVolumeVO usageVol : usageUsageVols) { long volId = usageVol.getVolumeId(); Long doId = usageVol.getDiskOfferingId(); + Long vmId = usageVol.getVmId(); long zoneId = usageVol.getZoneId(); Long templateId = usageVol.getTemplateId(); long size = usageVol.getSize(); - String key = volId + "-" + doId + "-" + size; + String key = volId + "-" + doId + "-" + vmId + "-" + size; - diskOfferingMap.put(key, new VolInfo(volId, zoneId, doId, templateId, size)); + diskOfferingMap.put(key, new VolInfo(volId, zoneId, doId, templateId, size, vmId)); Date volCreateDate = usageVol.getCreated(); Date volDeleteDate = usageVol.getDeleted(); @@ -110,7 +111,7 @@ protected boolean parse(AccountVO account, Date startDate, Date endDate) { if (useTime > 0L) { VolInfo info = diskOfferingMap.get(volIdKey); createUsageRecord(UsageTypes.VOLUME, useTime, startDate, endDate, account, info.getVolumeId(), info.getZoneId(), info.getDiskOfferingId(), - info.getTemplateId(), info.getSize()); + info.getTemplateId(), info.getVmId(), info.getSize()); } } @@ -130,7 +131,7 @@ private void updateVolUsageData(Map> usageDataMap, Stri } private void createUsageRecord(int type, long runningTime, Date startDate, Date endDate, AccountVO account, long volId, long zoneId, Long doId, - Long templateId, long size) { + Long templateId, Long vmId, long size) { // Our smallest increment is hourly for now logger.debug("Total running time {} ms", runningTime); @@ -152,7 +153,11 @@ private void createUsageRecord(int type, long runningTime, Date startDate, Date usageDesc += " (DiskOffering: " + doId + ")"; } - UsageVO usageRecord = new UsageVO(zoneId, account.getId(), account.getDomainId(), usageDesc, usageDisplay + " Hrs", type, new Double(usage), null, null, doId, templateId, volId, + if (vmId != null) { + usageDesc += " (VM: " + vmId + ")"; + } + + UsageVO usageRecord = new UsageVO(zoneId, account.getId(), account.getDomainId(), usageDesc, usageDisplay + " Hrs", type, new Double(usage), vmId, null, doId, templateId, volId, size, startDate, endDate); usageDao.persist(usageRecord); } @@ -163,13 +168,15 @@ private static class VolInfo { private Long diskOfferingId; private Long templateId; private long size; + private Long vmId; - public VolInfo(long volId, long zoneId, Long diskOfferingId, Long templateId, long size) { + public VolInfo(long volId, long zoneId, Long diskOfferingId, Long templateId, long size, Long vmId) { this.volId = volId; this.zoneId = zoneId; this.diskOfferingId = diskOfferingId; this.templateId = templateId; this.size = size; + this.vmId = vmId; } public long getZoneId() { @@ -191,5 +198,9 @@ public Long getTemplateId() { public long getSize() { return size; } + + public Long getVmId() { + return vmId; + } } } From 3ba0d966df199504935753e5063a11813c882894 Mon Sep 17 00:00:00 2001 From: Abhisar Sinha <63767682+abh1sar@users.noreply.github.com> Date: Fri, 29 Aug 2025 03:15:35 +0530 Subject: [PATCH 2/7] fix UT and schema --- .../src/main/resources/META-INF/db/schema-41930to41940.sql | 6 +++--- .../src/test/java/com/cloud/vm/UserVmManagerImplTest.java | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/engine/schema/src/main/resources/META-INF/db/schema-41930to41940.sql b/engine/schema/src/main/resources/META-INF/db/schema-41930to41940.sql index d43e4e8ee5a1..75d38c15afa3 100644 --- a/engine/schema/src/main/resources/META-INF/db/schema-41930to41940.sql +++ b/engine/schema/src/main/resources/META-INF/db/schema-41930to41940.sql @@ -20,8 +20,8 @@ --; -- Add vm_id column to usage_event table for volume usage events -ALTER TABLE `cloud`.`usage_event` ADD COLUMN `vm_id` bigint unsigned NULL COMMENT 'VM ID associated with volume usage events'; -ALTER TABLE `cloud_usage`.`usage_event` ADD COLUMN `vm_id` bigint unsigned NULL COMMENT 'VM ID associated with volume usage events'; +CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.usage_event','vm_id', 'bigint UNSIGNED NULL COMMENT "VM ID associated with volume usage events"'); +CALL `cloud_usage`.`IDEMPOTENT_ADD_COLUMN`('cloud_usage.usage_event','vm_id', 'bigint UNSIGNED NULL COMMENT "VM ID associated with volume usage events"'); -- Add vm_id column to cloud_usage.usage_volume table -ALTER TABLE `cloud_usage`.`usage_volume` ADD COLUMN `vm_id` bigint unsigned NULL COMMENT 'VM ID associated with the volume usage'; +CALL `cloud_usage`.`IDEMPOTENT_ADD_COLUMN`('cloud_usage.usage_volume','vm_id', 'bigint UNSIGNED NULL COMMENT "VM ID associated with the volume usage"'); diff --git a/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java b/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java index e1efd87dcd8b..4618fa56ebf0 100644 --- a/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java +++ b/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java @@ -449,6 +449,7 @@ public class UserVmManagerImplTest { private DiskOfferingVO largerDisdkOffering = prepareDiskOffering(10l * GiB_TO_BYTES, 2l, 10L, 20L); Class expectedInvalidParameterValueException = InvalidParameterValueException.class; Class expectedCloudRuntimeException = CloudRuntimeException.class; + private MockedStatic usageEventUtilsMocked; @Before public void beforeTest() { @@ -472,11 +473,13 @@ public void beforeTest() { lenient().doNothing().when(resourceLimitMgr).decrementResourceCount(anyLong(), any(Resource.ResourceType.class), anyLong()); Mockito.when(virtualMachineProfile.getId()).thenReturn(vmId); + usageEventUtilsMocked = Mockito.mockStatic(UsageEventUtils.class); } @After public void afterTest() { CallContext.unregister(); + usageEventUtilsMocked.close(); } @Test From 025ae71699d3e68d7a0c37d823d8de7a481e8bba Mon Sep 17 00:00:00 2001 From: Abhisar Sinha <63767682+abh1sar@users.noreply.github.com> Date: Tue, 9 Sep 2025 13:23:41 +0530 Subject: [PATCH 3/7] Schema change and UT fix --- .../upgrade/dao/Upgrade41930to41940.java | 60 ------------------- .../cloud/usage/dao/UsageVolumeDaoImpl.java | 1 - .../META-INF/db/schema-41930to41940.sql | 27 --------- .../META-INF/db/schema-42100to42200.sql | 7 +++ .../com/cloud/vm/UserVmManagerImplTest.java | 11 ++-- .../com/cloud/usage/UsageManagerImpl.java | 6 +- 6 files changed, 15 insertions(+), 97 deletions(-) delete mode 100644 engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade41930to41940.java delete mode 100644 engine/schema/src/main/resources/META-INF/db/schema-41930to41940.sql diff --git a/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade41930to41940.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade41930to41940.java deleted file mode 100644 index 5e2b3344c0a7..000000000000 --- a/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade41930to41940.java +++ /dev/null @@ -1,60 +0,0 @@ -// 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 com.cloud.upgrade.dao; - -import java.io.InputStream; -import java.sql.Connection; - -import com.cloud.utils.exception.CloudRuntimeException; - -public class Upgrade41930to41940 implements DbUpgrade { - - @Override - public String[] getUpgradableVersionRange() { - return new String[]{"4.19.3.0", "4.19.4.0"}; - } - - @Override - public String getUpgradedVersion() { - return "4.19.4.0"; - } - - @Override - public boolean supportsRollingUpgrade() { - return false; - } - - @Override - public InputStream[] getPrepareScripts() { - final String scriptFile = "META-INF/db/schema-41930to41940.sql"; - final InputStream script = Thread.currentThread().getContextClassLoader().getResourceAsStream(scriptFile); - if (script == null) { - throw new CloudRuntimeException("Unable to find " + scriptFile); - } - - return new InputStream[]{script}; - } - - @Override - public void performDataMigration(Connection conn) { - } - - @Override - public InputStream[] getCleanupScripts() { - return new InputStream[0]; - } -} diff --git a/engine/schema/src/main/java/com/cloud/usage/dao/UsageVolumeDaoImpl.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageVolumeDaoImpl.java index 2f80ec835077..095070feac1c 100644 --- a/engine/schema/src/main/java/com/cloud/usage/dao/UsageVolumeDaoImpl.java +++ b/engine/schema/src/main/java/com/cloud/usage/dao/UsageVolumeDaoImpl.java @@ -26,7 +26,6 @@ import javax.annotation.PostConstruct; -import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.usage.UsageVolumeVO; diff --git a/engine/schema/src/main/resources/META-INF/db/schema-41930to41940.sql b/engine/schema/src/main/resources/META-INF/db/schema-41930to41940.sql deleted file mode 100644 index 75d38c15afa3..000000000000 --- a/engine/schema/src/main/resources/META-INF/db/schema-41930to41940.sql +++ /dev/null @@ -1,27 +0,0 @@ --- 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. - ---; --- Schema upgrade from 4.19.3.0 to 4.19.4.0 ---; - --- Add vm_id column to usage_event table for volume usage events -CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.usage_event','vm_id', 'bigint UNSIGNED NULL COMMENT "VM ID associated with volume usage events"'); -CALL `cloud_usage`.`IDEMPOTENT_ADD_COLUMN`('cloud_usage.usage_event','vm_id', 'bigint UNSIGNED NULL COMMENT "VM ID associated with volume usage events"'); - --- Add vm_id column to cloud_usage.usage_volume table -CALL `cloud_usage`.`IDEMPOTENT_ADD_COLUMN`('cloud_usage.usage_volume','vm_id', 'bigint UNSIGNED NULL COMMENT "VM ID associated with the volume usage"'); diff --git a/engine/schema/src/main/resources/META-INF/db/schema-42100to42200.sql b/engine/schema/src/main/resources/META-INF/db/schema-42100to42200.sql index cf3fe2ed7726..9369041d60a6 100644 --- a/engine/schema/src/main/resources/META-INF/db/schema-42100to42200.sql +++ b/engine/schema/src/main/resources/META-INF/db/schema-42100to42200.sql @@ -21,3 +21,10 @@ -- Increase length of scripts_version column to 128 due to md5sum to sha512sum change CALL `cloud`.`IDEMPOTENT_CHANGE_COLUMN`('cloud.domain_router', 'scripts_version', 'scripts_version', 'VARCHAR(128)'); + +-- Add vm_id column to usage_event table for volume usage events +CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.usage_event','vm_id', 'bigint UNSIGNED NULL COMMENT "VM ID associated with volume usage events"'); +CALL `cloud_usage`.`IDEMPOTENT_ADD_COLUMN`('cloud_usage.usage_event','vm_id', 'bigint UNSIGNED NULL COMMENT "VM ID associated with volume usage events"'); + +-- Add vm_id column to cloud_usage.usage_volume table +CALL `cloud_usage`.`IDEMPOTENT_ADD_COLUMN`('cloud_usage.usage_volume','vm_id', 'bigint UNSIGNED NULL COMMENT "VM ID associated with the volume usage"'); diff --git a/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java b/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java index 4618fa56ebf0..f49b1277aca2 100644 --- a/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java +++ b/server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java @@ -449,7 +449,6 @@ public class UserVmManagerImplTest { private DiskOfferingVO largerDisdkOffering = prepareDiskOffering(10l * GiB_TO_BYTES, 2l, 10L, 20L); Class expectedInvalidParameterValueException = InvalidParameterValueException.class; Class expectedCloudRuntimeException = CloudRuntimeException.class; - private MockedStatic usageEventUtilsMocked; @Before public void beforeTest() { @@ -473,13 +472,11 @@ public void beforeTest() { lenient().doNothing().when(resourceLimitMgr).decrementResourceCount(anyLong(), any(Resource.ResourceType.class), anyLong()); Mockito.when(virtualMachineProfile.getId()).thenReturn(vmId); - usageEventUtilsMocked = Mockito.mockStatic(UsageEventUtils.class); } @After public void afterTest() { CallContext.unregister(); - usageEventUtilsMocked.close(); } @Test @@ -1105,10 +1102,12 @@ public void testResetVMUserDataSuccessResetWithUserdataId() { public void recoverRootVolumeTestDestroyState() { Mockito.doReturn(Volume.State.Destroy).when(volumeVOMock).getState(); - userVmManagerImpl.recoverRootVolume(volumeVOMock, vmId); + try (MockedStatic ignored = Mockito.mockStatic(UsageEventUtils.class)) { + userVmManagerImpl.recoverRootVolume(volumeVOMock, vmId); - Mockito.verify(volumeApiService).recoverVolume(volumeVOMock.getId()); - Mockito.verify(volumeDaoMock).attachVolume(volumeVOMock.getId(), vmId, UserVmManagerImpl.ROOT_DEVICE_ID); + Mockito.verify(volumeApiService).recoverVolume(volumeVOMock.getId()); + Mockito.verify(volumeDaoMock).attachVolume(volumeVOMock.getId(), vmId, UserVmManagerImpl.ROOT_DEVICE_ID); + } } @Test(expected = InvalidParameterValueException.class) diff --git a/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java b/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java index b20da617a77f..b3c2b016d094 100644 --- a/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java +++ b/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java @@ -1432,7 +1432,7 @@ private void createIPHelperEvent(UsageEventVO event) { private void deleteExistingSecondaryStorageUsageForVolume(long volId, long accountId, Date deletedDate) { List storageVOs = _usageStorageDao.listById(accountId, volId, StorageTypes.VOLUME); for (UsageStorageVO storageVO : storageVOs) { - s_logger.debug(String.format("Setting the volume with id: {} to 'deleted' in the usage_storage table for account: {}.", volId, accountId)); + logger.debug(String.format("Setting the volume with id: {} to 'deleted' in the usage_storage table for account: {}.", volId, accountId)); storageVO.setDeleted(deletedDate); _usageStorageDao.update(storageVO); } @@ -1442,7 +1442,7 @@ private void deleteExistingInstanceVolumeUsage(long volId, long accountId, Date List volumesVOs = _usageVolumeDao.listByVolumeId(volId, accountId); for (UsageVolumeVO volumesVO : volumesVOs) { if (volumesVO.getVmId() != null) { - s_logger.debug(String.format("Setting the volume with id: {} for instance id: {} to 'deleted' in the usage_volume table for account {}.", + logger.debug(String.format("Setting the volume with id: {} for instance id: {} to 'deleted' in the usage_volume table for account {}.", volumesVO.getVolumeId(), volumesVO.getVmId(), accountId)); volumesVO.setDeleted(deletedDate); _usageVolumeDao.update(volumesVO.getId(), volumesVO); @@ -1453,7 +1453,7 @@ private void deleteExistingInstanceVolumeUsage(long volId, long accountId, Date private void deleteExistingVolumeUsage(long volId, long accountId, Date deletedDate) { List volumesVOs = _usageVolumeDao.listByVolumeId(volId, accountId); for (UsageVolumeVO volumesVO : volumesVOs) { - s_logger.debug(String.format("Setting the volume with id: {} to 'deleted' in the usage_storage table for account: {}.", volId, accountId)); + logger.debug(String.format("Setting the volume with id: {} to 'deleted' in the usage_storage table for account: {}.", volId, accountId)); volumesVO.setDeleted(deletedDate); _usageVolumeDao.update(volumesVO.getId(), volumesVO); } From 73374fd5e07ce09a8c6453f51bc6f28389a3d52e Mon Sep 17 00:00:00 2001 From: Abhisar Sinha <63767682+abh1sar@users.noreply.github.com> Date: Thu, 25 Sep 2025 15:13:41 +0530 Subject: [PATCH 4/7] remove extra eof line in schema-42100to42200.sql --- .../src/main/resources/META-INF/db/schema-42100to42200.sql | 1 - 1 file changed, 1 deletion(-) diff --git a/engine/schema/src/main/resources/META-INF/db/schema-42100to42200.sql b/engine/schema/src/main/resources/META-INF/db/schema-42100to42200.sql index 68f7abe72408..dffbd804af6a 100644 --- a/engine/schema/src/main/resources/META-INF/db/schema-42100to42200.sql +++ b/engine/schema/src/main/resources/META-INF/db/schema-42100to42200.sql @@ -35,4 +35,3 @@ CALL `cloud_usage`.`IDEMPOTENT_ADD_COLUMN`('cloud_usage.usage_volume','vm_id', ' -- Add the column cross_zone_instance_creation to cloud.backup_repository. if enabled it means that new Instance can be created on all Zones from Backups on this Repository. CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.backup_repository', 'cross_zone_instance_creation', 'TINYINT(1) DEFAULT NULL COMMENT ''Backup Repository can be used for disaster recovery on another zone'''); - From 736d9b4e330154dffa6f4c3147f8c9f772e6d6d8 Mon Sep 17 00:00:00 2001 From: Abhisar Sinha <63767682+abh1sar@users.noreply.github.com> Date: Tue, 30 Sep 2025 18:19:14 +0530 Subject: [PATCH 5/7] address review comments in UsageManagerImpl --- .../com/cloud/usage/UsageManagerImpl.java | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java b/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java index b3c2b016d094..86e6d785ba8d 100644 --- a/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java +++ b/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java @@ -1432,7 +1432,7 @@ private void createIPHelperEvent(UsageEventVO event) { private void deleteExistingSecondaryStorageUsageForVolume(long volId, long accountId, Date deletedDate) { List storageVOs = _usageStorageDao.listById(accountId, volId, StorageTypes.VOLUME); for (UsageStorageVO storageVO : storageVOs) { - logger.debug(String.format("Setting the volume with id: {} to 'deleted' in the usage_storage table for account: {}.", volId, accountId)); + logger.debug("Setting the volume with id: {} to 'deleted' in the usage_storage table for account: {}.", volId, accountId); storageVO.setDeleted(deletedDate); _usageStorageDao.update(storageVO); } @@ -1442,8 +1442,8 @@ private void deleteExistingInstanceVolumeUsage(long volId, long accountId, Date List volumesVOs = _usageVolumeDao.listByVolumeId(volId, accountId); for (UsageVolumeVO volumesVO : volumesVOs) { if (volumesVO.getVmId() != null) { - logger.debug(String.format("Setting the volume with id: {} for instance id: {} to 'deleted' in the usage_volume table for account {}.", - volumesVO.getVolumeId(), volumesVO.getVmId(), accountId)); + logger.debug("Setting the volume with id: {} for instance id: {} to 'deleted' in the usage_volume table for account {}.", + volumesVO.getVolumeId(), volumesVO.getVmId(), accountId); volumesVO.setDeleted(deletedDate); _usageVolumeDao.update(volumesVO.getId(), volumesVO); } @@ -1453,7 +1453,7 @@ private void deleteExistingInstanceVolumeUsage(long volId, long accountId, Date private void deleteExistingVolumeUsage(long volId, long accountId, Date deletedDate) { List volumesVOs = _usageVolumeDao.listByVolumeId(volId, accountId); for (UsageVolumeVO volumesVO : volumesVOs) { - logger.debug(String.format("Setting the volume with id: {} to 'deleted' in the usage_storage table for account: {}.", volId, accountId)); + logger.debug("Setting the volume with id: {} to 'deleted' in the usage_volume table for account: {}.", volId, accountId); volumesVO.setDeleted(deletedDate); _usageVolumeDao.update(volumesVO.getId(), volumesVO); } @@ -1479,7 +1479,7 @@ private void createVolumeHelperEvent(UsageEventVO event) { deleteExistingVolumeUsage(volId, event.getAccountId(), event.getCreateDate()); } - logger.debug(String.format("Creating a new entry in usage_volume for volume with id: {} for account: {}", volId, event.getVmId(), event.getAccountId())); + logger.debug("Creating a new entry in usage_volume for volume with id: {} for account: {}", volId, event.getAccountId()); volumeVO = new UsageVolumeVO(volId, event.getZoneId(), event.getAccountId(), acct.getDomainId(), event.getOfferingId(), event.getTemplateId(), null, event.getSize(), event.getCreateDate(), null); _usageVolumeDao.persist(volumeVO); @@ -1494,10 +1494,9 @@ private void createVolumeHelperEvent(UsageEventVO event) { for (UsageVolumeVO volumesVO : volumesVOs) { String delete_msg = String.format("Setting the volume with id: {} to 'deleted' in the usage_storage table for account: {}.", volId, event.getAccountId()); String create_msg = String.format("Creating a new entry in usage_volume for volume with id: {} after resize for account: {}", volId, event.getAccountId()); - Long vmId = null; + Long vmId = volumesVO.getVmId(); if (vmId != null) { - vmId = volumesVO.getVmId(); - delete_msg = String.format("Setting the volume with id: {} for instance id: {} to 'deleted' in the usage_storage table for account: {}.", + delete_msg = String.format("Setting the volume with id: {} for instance id: {} to 'deleted' in the usage_volume table for account: {}.", volId, vmId, event.getAccountId()); create_msg = String.format("Creating a new entry in usage_volume for volume with id: {} and instance id: {} after resize for account: {}", volId, vmId, event.getAccountId()); @@ -1519,8 +1518,8 @@ private void createVolumeHelperEvent(UsageEventVO event) { case EventTypes.EVENT_VOLUME_ATTACH: deleteExistingInstanceVolumeUsage(event.getResourceId(), event.getAccountId(), event.getCreateDate()); - logger.debug(String.format("Creating a new entry in usage_volume for volume with id: {}, and instance id: {} for account: {}", - volId, event.getVmId(), event.getAccountId())); + logger.debug("Creating a new entry in usage_volume for volume with id: {}, and instance id: {} for account: {}", + volId, event.getVmId(), event.getAccountId()); volumeVO = new UsageVolumeVO(volId, event.getZoneId(), event.getAccountId(), acct.getDomainId(), event.getOfferingId(), event.getTemplateId(), event.getVmId(), event.getSize(), event.getCreateDate(), null); _usageVolumeDao.persist(volumeVO); break; @@ -1532,7 +1531,7 @@ private void createVolumeHelperEvent(UsageEventVO event) { case EventTypes.EVENT_VOLUME_UPLOAD: deleteExistingSecondaryStorageUsageForVolume(volId, event.getAccountId(), event.getCreateDate()); - logger.debug(String.format("Creating a new entry in usage_storage for volume with id : {} for account: {}", volId, event.getAccountId())); + logger.debug("Creating a new entry in usage_storage for volume with id : {} for account: {}", volId, event.getAccountId()); UsageStorageVO storageVO = new UsageStorageVO(volId, event.getZoneId(), event.getAccountId(), acct.getDomainId(), StorageTypes.VOLUME, event.getTemplateId(), event.getSize(), event.getCreateDate(), null); _usageStorageDao.persist(storageVO); break; From 072645bb31a37fb93909094c8a1bd10e28e67cdb Mon Sep 17 00:00:00 2001 From: Abhisar Sinha <63767682+abh1sar@users.noreply.github.com> Date: Tue, 30 Sep 2025 18:42:12 +0530 Subject: [PATCH 6/7] fix String.format in UsageManagerImpl --- usage/src/main/java/com/cloud/usage/UsageManagerImpl.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java b/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java index 86e6d785ba8d..c65e6b295a98 100644 --- a/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java +++ b/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java @@ -1492,13 +1492,13 @@ private void createVolumeHelperEvent(UsageEventVO event) { case EventTypes.EVENT_VOLUME_RESIZE: volumesVOs = _usageVolumeDao.listByVolumeId(volId, event.getAccountId()); for (UsageVolumeVO volumesVO : volumesVOs) { - String delete_msg = String.format("Setting the volume with id: {} to 'deleted' in the usage_storage table for account: {}.", volId, event.getAccountId()); - String create_msg = String.format("Creating a new entry in usage_volume for volume with id: {} after resize for account: {}", volId, event.getAccountId()); + String delete_msg = String.format("Setting the volume with id: %s to 'deleted' in the usage_storage table for account: %s.", volId, event.getAccountId()); + String create_msg = String.format("Creating a new entry in usage_volume for volume with id: %s after resize for account: %s", volId, event.getAccountId()); Long vmId = volumesVO.getVmId(); if (vmId != null) { - delete_msg = String.format("Setting the volume with id: {} for instance id: {} to 'deleted' in the usage_volume table for account: {}.", + delete_msg = String.format("Setting the volume with id: %s for instance id: %s to 'deleted' in the usage_volume table for account: %s.", volId, vmId, event.getAccountId()); - create_msg = String.format("Creating a new entry in usage_volume for volume with id: {} and instance id: {} after resize for account: {}", + create_msg = String.format("Creating a new entry in usage_volume for volume with id: %s and instance id: %s after resize for account: %s", volId, vmId, event.getAccountId()); } logger.debug(delete_msg); From 76706f5d194558d58c33457b5d95cfb696f992dd Mon Sep 17 00:00:00 2001 From: Abhisar Sinha <63767682+abh1sar@users.noreply.github.com> Date: Wed, 1 Oct 2025 11:56:46 +0530 Subject: [PATCH 7/7] Update usage/src/main/java/com/cloud/usage/UsageManagerImpl.java Co-authored-by: Vishesh <8760112+vishesh92@users.noreply.github.com> --- usage/src/main/java/com/cloud/usage/UsageManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java b/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java index c65e6b295a98..864ad35c9229 100644 --- a/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java +++ b/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java @@ -1492,7 +1492,7 @@ private void createVolumeHelperEvent(UsageEventVO event) { case EventTypes.EVENT_VOLUME_RESIZE: volumesVOs = _usageVolumeDao.listByVolumeId(volId, event.getAccountId()); for (UsageVolumeVO volumesVO : volumesVOs) { - String delete_msg = String.format("Setting the volume with id: %s to 'deleted' in the usage_storage table for account: %s.", volId, event.getAccountId()); + String delete_msg = String.format("Setting the volume with id: %s to 'deleted' in the usage_volume table for account: %s.", volId, event.getAccountId()); String create_msg = String.format("Creating a new entry in usage_volume for volume with id: %s after resize for account: %s", volId, event.getAccountId()); Long vmId = volumesVO.getVmId(); if (vmId != null) {