From 3d04dd40c74b1daebb0d1b549494732e5e543da2 Mon Sep 17 00:00:00 2001 From: Manoj Kumar Date: Tue, 15 Jul 2025 17:36:28 +0530 Subject: [PATCH 1/2] add vmId in usageVolume --- .../java/com/cloud/storage/dao/VolumeDao.java | 2 + .../com/cloud/storage/dao/VolumeDaoImpl.java | 14 +++++ .../upgrade/dao/Upgrade41930to41940.java | 60 +++++++++++++++++++ .../java/com/cloud/usage/UsageVolumeVO.java | 11 +++- .../cloud/usage/dao/UsageVolumeDaoImpl.java | 15 ++--- .../META-INF/db/schema-41930to41940.sql | 22 +++++++ .../com/cloud/usage/UsageManagerImpl.java | 7 ++- .../cloud/usage/parser/VolumeUsageParser.java | 24 +++++--- 8 files changed, 137 insertions(+), 18 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/schema/src/main/java/com/cloud/storage/dao/VolumeDao.java b/engine/schema/src/main/java/com/cloud/storage/dao/VolumeDao.java index 8e3bbf68dea7..477a69c8d2fd 100644 --- a/engine/schema/src/main/java/com/cloud/storage/dao/VolumeDao.java +++ b/engine/schema/src/main/java/com/cloud/storage/dao/VolumeDao.java @@ -158,4 +158,6 @@ public interface VolumeDao extends GenericDao, StateDao listByIds(List ids); VolumeVO findOneByIScsiName(String iScsiName); + + Long getInstanceIdByVolumeId(long volumeId); } diff --git a/engine/schema/src/main/java/com/cloud/storage/dao/VolumeDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/VolumeDaoImpl.java index 9907af76769f..2dd3f98c38ad 100644 --- a/engine/schema/src/main/java/com/cloud/storage/dao/VolumeDaoImpl.java +++ b/engine/schema/src/main/java/com/cloud/storage/dao/VolumeDaoImpl.java @@ -67,6 +67,7 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol protected final SearchBuilder RootDiskStateSearch; private final SearchBuilder storeAndInstallPathSearch; private final SearchBuilder volumeIdSearch; + private final SearchBuilder instanceIdByVolumeIdSearch; protected GenericSearchBuilder CountByAccount; protected GenericSearchBuilder primaryStorageSearch; protected GenericSearchBuilder primaryStorageSearch2; @@ -494,6 +495,11 @@ public VolumeDaoImpl() { poolAndPathSearch.and("poolId", poolAndPathSearch.entity().getPoolId(), Op.EQ); poolAndPathSearch.and("path", poolAndPathSearch.entity().getPath(), Op.EQ); poolAndPathSearch.done(); + + instanceIdByVolumeIdSearch = createSearchBuilder(); + instanceIdByVolumeIdSearch.selectFields(instanceIdByVolumeIdSearch.entity().getInstanceId()); + instanceIdByVolumeIdSearch.and("id", instanceIdByVolumeIdSearch.entity().getId(), Op.EQ); + instanceIdByVolumeIdSearch.done(); } @Override @@ -847,4 +853,12 @@ public VolumeVO findOneByIScsiName(String iScsiName) { sc.setParameters("iScsiName", iScsiName); return findOneIncludingRemovedBy(sc); } + + @Override + public Long getInstanceIdByVolumeId(long volumeId) { + SearchCriteria sc = instanceIdByVolumeIdSearch.create(); + sc.setParameters("id", volumeId); + List volumes = search(sc, null); + return volumes.isEmpty() ? null : volumes.get(0).getInstanceId(); + } } 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..094f8d79e06d 100644 --- a/engine/schema/src/main/java/com/cloud/usage/UsageVolumeVO.java +++ b/engine/schema/src/main/java/com/cloud/usage/UsageVolumeVO.java @@ -67,16 +67,21 @@ public class UsageVolumeVO implements InternalIdentity { @Temporal(value = TemporalType.TIMESTAMP) private Date deleted = null; + @Column(name = "vm_instance_id") + private long vmInstanceId; + 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 vmInstanceId, 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.vmInstanceId = vmInstanceId; this.size = size; this.created = created; this.deleted = deleted; @@ -126,4 +131,8 @@ public void setDeleted(Date deleted) { public long getVolumeId() { return volumeId; } + + public long getVmInstanceId() { + return vmInstanceId; + } } 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 0c35c118006b..3b3576cb071f 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 @@ -40,13 +40,13 @@ public class UsageVolumeDaoImpl extends GenericDaoBase impl 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_instance_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_instance_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_instance_id, size, created, deleted " + "FROM usage_volume " + "WHERE (deleted IS NULL) OR (created BETWEEN ? AND ?) OR " + " (deleted BETWEEN ? AND ?) OR ((created <= ?) AND (deleted >= ?))"; public UsageVolumeDaoImpl() { @@ -152,11 +152,12 @@ public List getUsageRecords(Long accountId, Long domainId, Date s if (tId == 0) { tId = null; } - long size = Long.valueOf(rs.getLong(7)); + Long vmId = rs.getLong(7); + 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); @@ -165,7 +166,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(); 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..d1695f60ea9c --- /dev/null +++ b/engine/schema/src/main/resources/META-INF/db/schema-41930to41940.sql @@ -0,0 +1,22 @@ +-- 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 +--; +ALTER TABLE `cloud`.`usage_event` ADD COLUMN `vm_instance_id` bigint unsigned DEFAULT NULL; +ALTER TABLE `cloud_usage`.`usage_volume` ADD COLUMN `vm_instance_id` bigint unsigned DEFAULT NULL; diff --git a/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java b/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java index cc129a9ec5e4..dcd1cedac86b 100644 --- a/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java +++ b/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java @@ -33,6 +33,7 @@ import java.util.concurrent.TimeUnit; import com.cloud.network.Network; +import com.cloud.storage.dao.VolumeDao; import com.cloud.usage.dao.UsageNetworksDao; import com.cloud.usage.parser.NetworksUsageParser; import com.cloud.network.vpc.Vpc; @@ -180,6 +181,8 @@ public class UsageManagerImpl extends ManagerBase implements UsageManager, Runna @Inject private UsageVpcDao usageVpcDao; + @Inject + private VolumeDao volumeDao; private String _version = null; private final Calendar _jobExecTime = Calendar.getInstance(); @@ -1573,7 +1576,9 @@ private void createVolumeHelperEvent(UsageEventVO event) { s_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); + Long vmId = volumeDao.getInstanceIdByVolumeId(volId); + UsageVolumeVO volumeVO = new UsageVolumeVO(volId, event.getZoneId(), event.getAccountId(), acct.getDomainId(), + event.getOfferingId(), event.getTemplateId(), vmId, event.getSize(), event.getCreateDate(), null); _usageVolumeDao.persist(volumeVO); } else if (EventTypes.EVENT_VOLUME_DELETE.equals(event.getType())) { SearchCriteria sc = _usageVolumeDao.createSearchCriteria(); 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 79ed8bcbb943..454e013f6ad7 100644 --- a/usage/src/main/java/com/cloud/usage/parser/VolumeUsageParser.java +++ b/usage/src/main/java/com/cloud/usage/parser/VolumeUsageParser.java @@ -86,10 +86,11 @@ public static boolean parse(AccountVO account, Date startDate, Date endDate) { Long doId = usageVol.getDiskOfferingId(); long zoneId = usageVol.getZoneId(); Long templateId = usageVol.getTemplateId(); + Long instanceId = usageVol.getVmInstanceId(); long size = usageVol.getSize(); String key = volId + "-" + doId + "-" + size; - diskOfferingMap.put(key, new VolInfo(volId, zoneId, doId, templateId, size)); + diskOfferingMap.put(key, new VolInfo(volId, zoneId, doId, templateId, instanceId, size)); Date volCreateDate = usageVol.getCreated(); Date volDeleteDate = usageVol.getDeleted(); @@ -120,8 +121,8 @@ public static boolean parse(AccountVO account, Date startDate, Date endDate) { // Only create a usage record if we have a runningTime of bigger than zero. 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()); + createUsageRecord(UsageTypes.VOLUME, useTime, startDate, endDate, account, info.getVolumeId(), + info.getZoneId(), info.getDiskOfferingId(), info.getTemplateId(), info.getInstanceId(), info.getSize()); } } @@ -140,8 +141,8 @@ private static void updateVolUsageData(Map> usageDataMa usageDataMap.put(key, volUsageInfo); } - private static void createUsageRecord(int type, long runningTime, Date startDate, Date endDate, AccountVO account, long volId, long zoneId, Long doId, - Long templateId, long size) { + private static void createUsageRecord(int type, long runningTime, Date startDate, Date endDate, AccountVO account, + long volId, long zoneId, Long doId, Long templateId, Long instanceId, long size) { // Our smallest increment is hourly for now if (s_logger.isDebugEnabled()) { s_logger.debug("Total running time " + runningTime + "ms"); @@ -165,9 +166,8 @@ private static void createUsageRecord(int type, long runningTime, Date startDate } else if (doId != null) { usageDesc += " (DiskOffering: " + doId + ")"; } - - UsageVO usageRecord = new UsageVO(zoneId, account.getId(), account.getDomainId(), usageDesc, usageDisplay + " Hrs", type, new Double(usage), null, null, doId, templateId, volId, - size, startDate, endDate); + UsageVO usageRecord = new UsageVO(zoneId, account.getId(), account.getDomainId(), usageDesc,usageDisplay + " Hrs", + type, new Double(usage), instanceId,null, doId, templateId, volId, size, startDate, endDate); s_usageDao.persist(usageRecord); } @@ -176,13 +176,15 @@ private static class VolInfo { private long zoneId; private Long diskOfferingId; private Long templateId; + private Long instanceId; private long size; - public VolInfo(long volId, long zoneId, Long diskOfferingId, Long templateId, long size) { + public VolInfo(long volId, long zoneId, Long diskOfferingId, Long templateId, Long instanceId, long size) { this.volId = volId; this.zoneId = zoneId; this.diskOfferingId = diskOfferingId; this.templateId = templateId; + this.instanceId = instanceId; this.size = size; } @@ -202,6 +204,10 @@ public Long getTemplateId() { return templateId; } + public Long getInstanceId() { + return instanceId; + } + public long getSize() { return size; } From fd73e76a3a2d435831c8bb899a59b7b62c77b6cc Mon Sep 17 00:00:00 2001 From: Manoj Kumar Date: Wed, 16 Jul 2025 17:27:40 +0530 Subject: [PATCH 2/2] modify UsageEventVO --- .../src/main/java/com/cloud/event/UsageEventVO.java | 11 +++++++++++ 1 file changed, 11 insertions(+) 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..261339a8372e 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_instance_id") + private long vmInstanceId; + public UsageEventVO() { } @@ -248,4 +251,12 @@ public void setVirtualSize(Long virtualSize) { this.virtualSize = virtualSize; } + public long getVmInstanceId() { + return vmInstanceId; + } + + public void setVmInstanceId(long vmInstanceId) { + this.vmInstanceId = vmInstanceId; + } + }