From bfc08715cc8553e8a7192cf58b5a699d9778b021 Mon Sep 17 00:00:00 2001 From: Nicolas Vazquez Date: Tue, 20 Aug 2019 10:20:23 -0300 Subject: [PATCH] Display VM snapshot tags on usage records (#3560) * Refactor usage helper tables to include VM snapshot id * Fix resource type and resource id while listing usage records * Add defensive checks --- .../java/com/cloud/event/UsageEventUtils.java | 30 ++++++++++++++ .../java/com/cloud/event/UsageEventVO.java | 2 +- .../cloud/usage/UsageSnapshotOnPrimaryVO.java | 13 +++++- .../com/cloud/usage/UsageVMSnapshotVO.java | 13 +++++- .../usage/dao/UsageVMSnapshotDaoImpl.java | 17 ++++++-- .../dao/UsageVMSnapshotOnPrimaryDaoImpl.java | 9 ++++- .../META-INF/db/schema-41200to41300.sql | 4 ++ .../vmsnapshot/DefaultVMSnapshotStrategy.java | 14 ++++++- .../java/com/cloud/api/ApiResponseHelper.java | 40 ++++++++++++++++--- .../com/cloud/usage/UsageManagerImpl.java | 16 ++++++++ .../parser/VMSanpshotOnPrimaryParser.java | 10 ++--- .../usage/parser/VMSnapshotUsageParser.java | 12 +++--- 12 files changed, 152 insertions(+), 28 deletions(-) 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 69892d60b72..b583065f21e 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 @@ -25,6 +25,7 @@ import java.util.Map; import javax.annotation.PostConstruct; import javax.inject.Inject; +import org.apache.commons.collections.MapUtils; import org.apache.log4j.Logger; import org.springframework.beans.factory.NoSuchBeanDefinitionException; @@ -69,6 +70,12 @@ public class UsageEventUtils { s_configDao = configDao; } + public static void publishUsageEvent(String usageType, long accountId, long zoneId, long resourceId, String resourceName, Long offeringId, Long templateId, + Long size, String entityType, String entityUUID, Map details) { + saveUsageEvent(usageType, accountId, zoneId, resourceId, resourceName, offeringId, templateId, size, details); + 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, String entityType, String entityUUID) { saveUsageEvent(usageType, accountId, zoneId, resourceId, resourceName, offeringId, templateId, size); @@ -84,6 +91,12 @@ public class UsageEventUtils { } + 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); + 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) { saveUsageEvent(usageType, accountId, zoneId, resourceId, resourceName, offeringId, templateId, size, virtualSize); @@ -142,11 +155,28 @@ public class UsageEventUtils { s_usageEventDao.persist(new UsageEventVO(usageType, accountId, zoneId, resourceId, resourceName, offeringId, templateId, size)); } + public static void saveUsageEvent(String usageType, long accountId, long zoneId, long resourceId, String resourceName, Long offeringId, Long templateId, Long size, Map details) { + UsageEventVO usageEventVO = new UsageEventVO(usageType, accountId, zoneId, resourceId, resourceName, offeringId, templateId, size); + s_usageEventDao.persist(usageEventVO); + if (MapUtils.isNotEmpty(details)) { + s_usageEventDao.saveDetails(usageEventVO.getId(), details); + } + } + public static void saveUsageEvent(String usageType, long accountId, long zoneId, long resourceId, String resourceName, Long offeringId, Long templateId, Long size, Long virtualSize) { s_usageEventDao.persist(new UsageEventVO(usageType, accountId, zoneId, resourceId, resourceName, offeringId, templateId, size, virtualSize)); } + public static void saveUsageEvent(String usageType, long accountId, long zoneId, long resourceId, String resourceName, Long offeringId, Long templateId, Long size, + Long virtualSize, Map details) { + UsageEventVO usageEventVO = new UsageEventVO(usageType, accountId, zoneId, resourceId, resourceName, offeringId, templateId, size, virtualSize); + s_usageEventDao.persist(usageEventVO); + if (MapUtils.isNotEmpty(details)) { + s_usageEventDao.saveDetails(usageEventVO.getId(), details); + } + } + public static void saveUsageEvent(String usageType, long accountId, long zoneId, long resourceId, String resourceName) { s_usageEventDao.persist(new UsageEventVO(usageType, accountId, zoneId, resourceId, resourceName)); } 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 c83bdcb8c02..3fc9fda9487 100644 --- a/engine/schema/src/main/java/com/cloud/event/UsageEventVO.java +++ b/engine/schema/src/main/java/com/cloud/event/UsageEventVO.java @@ -31,7 +31,7 @@ import com.cloud.utils.db.GenericDao; @Table(name = "usage_event") public class UsageEventVO implements UsageEvent { public enum DynamicParameters { - cpuSpeed, cpuNumber, memory + cpuSpeed, cpuNumber, memory, vmSnapshotId }; @Id diff --git a/engine/schema/src/main/java/com/cloud/usage/UsageSnapshotOnPrimaryVO.java b/engine/schema/src/main/java/com/cloud/usage/UsageSnapshotOnPrimaryVO.java index 74f944b9ece..54544a27f44 100644 --- a/engine/schema/src/main/java/com/cloud/usage/UsageSnapshotOnPrimaryVO.java +++ b/engine/schema/src/main/java/com/cloud/usage/UsageSnapshotOnPrimaryVO.java @@ -66,6 +66,9 @@ public class UsageSnapshotOnPrimaryVO implements InternalIdentity { @Column(name = "virtualsize") private Long virtualSize; + @Column(name = "vm_snapshot_id") + private Long vmSnapshotId; + protected UsageSnapshotOnPrimaryVO() { } @@ -136,10 +139,18 @@ public class UsageSnapshotOnPrimaryVO implements InternalIdentity { return this.id; } + public Long getVmSnapshotId() { + return vmSnapshotId; + } + + public void setVmSnapshotId(Long vmSnapshotId) { + this.vmSnapshotId = vmSnapshotId; + } + @Override public String toString() { return "UsageSnapshotOnPrimaryVO [id=" + id + ", zoneId=" + zoneId + ", accountId=" + accountId + ", domainId=" + domainId + ", vmId=" + vmId + ", name=" + name - + ", snapshotType=" + snapshotType + ", physicalSize=" + physicalSize + ", created=" + created + ", deleted=" + deleted + ", virtualSize=" + virtualSize + "]"; + + ", snapshotType=" + snapshotType + ", physicalSize=" + physicalSize + ", created=" + created + ", deleted=" + deleted + ", virtualSize=" + virtualSize + ", vmSnapshotId=" + vmSnapshotId + "]"; } } diff --git a/engine/schema/src/main/java/com/cloud/usage/UsageVMSnapshotVO.java b/engine/schema/src/main/java/com/cloud/usage/UsageVMSnapshotVO.java index 05a1b29c6f3..0fce5e80e4f 100644 --- a/engine/schema/src/main/java/com/cloud/usage/UsageVMSnapshotVO.java +++ b/engine/schema/src/main/java/com/cloud/usage/UsageVMSnapshotVO.java @@ -60,6 +60,9 @@ public class UsageVMSnapshotVO implements InternalIdentity { @Temporal(value = TemporalType.TIMESTAMP) private Date processed; + @Column(name = "vm_snapshot_id") + private Long vmSnapshotId; + protected UsageVMSnapshotVO() { } @@ -120,10 +123,18 @@ public class UsageVMSnapshotVO implements InternalIdentity { return this.id; } + public Long getVmSnapshotId() { + return vmSnapshotId; + } + + public void setVmSnapshotId(Long vmSnapshotId) { + this.vmSnapshotId = vmSnapshotId; + } + @Override public String toString() { return "UsageVMSnapshotVO [id=" + id + ", zoneId=" + zoneId + ", accountId=" + accountId + ", domainId=" + domainId + ", vmId=" + vmId + ", diskOfferingId=" - + diskOfferingId + ", size=" + size + ", created=" + created + ", processed=" + processed + "]"; + + diskOfferingId + ", size=" + size + ", created=" + created + ", processed=" + processed + ", vmSnapshotId=" + vmSnapshotId + "]"; } } diff --git a/engine/schema/src/main/java/com/cloud/usage/dao/UsageVMSnapshotDaoImpl.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageVMSnapshotDaoImpl.java index 41c4a3a6bbe..337d05e58f5 100644 --- a/engine/schema/src/main/java/com/cloud/usage/dao/UsageVMSnapshotDaoImpl.java +++ b/engine/schema/src/main/java/com/cloud/usage/dao/UsageVMSnapshotDaoImpl.java @@ -25,6 +25,7 @@ import java.util.List; import java.util.TimeZone; +import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -36,12 +37,12 @@ import com.cloud.utils.db.TransactionLegacy; @Component public class UsageVMSnapshotDaoImpl extends GenericDaoBase implements UsageVMSnapshotDao { public static final Logger s_logger = Logger.getLogger(UsageVMSnapshotDaoImpl.class.getName()); - protected static final String GET_USAGE_RECORDS_BY_ACCOUNT = "SELECT id, zone_id, account_id, domain_id, vm_id, disk_offering_id, size, created, processed " + protected static final String GET_USAGE_RECORDS_BY_ACCOUNT = "SELECT id, zone_id, account_id, domain_id, vm_id, disk_offering_id, size, created, processed, vm_snapshot_id " + " FROM usage_vmsnapshot" + " WHERE account_id = ? " + " AND ( (created BETWEEN ? AND ?) OR " + " (created < ? AND processed is NULL) ) ORDER BY created asc"; protected static final String UPDATE_DELETED = "UPDATE usage_vmsnapshot SET processed = ? WHERE account_id = ? AND id = ? and vm_id = ? and created = ?"; - protected static final String PREVIOUS_QUERY = "SELECT id, zone_id, account_id, domain_id, vm_id, disk_offering_id,size, created, processed " + protected static final String PREVIOUS_QUERY = "SELECT id, zone_id, account_id, domain_id, vm_id, disk_offering_id,size, created, processed, vm_snapshot_id " + "FROM usage_vmsnapshot " + "WHERE account_id = ? AND id = ? AND vm_id = ? AND created < ? AND processed IS NULL " + "ORDER BY created desc limit 1"; @Override @@ -99,6 +100,8 @@ public class UsageVMSnapshotDaoImpl extends GenericDaoBase implements UsageVMSnapshotOnPrimaryDao { public static final Logger s_logger = Logger.getLogger(UsageVMSnapshotOnPrimaryDaoImpl.class.getName()); - protected static final String GET_USAGE_RECORDS_BY_ACCOUNT = "SELECT id, zone_id, account_id, domain_id, vm_id, name, type, physicalsize, virtualsize, created, deleted " + protected static final String GET_USAGE_RECORDS_BY_ACCOUNT = "SELECT id, zone_id, account_id, domain_id, vm_id, name, type, physicalsize, virtualsize, created, deleted, vm_snapshot_id " + " FROM usage_snapshot_on_primary" + " WHERE account_id = ? " + " AND ( (created < ? AND deleted is NULL)" + " OR ( deleted BETWEEN ? AND ?)) ORDER BY created asc"; protected static final String UPDATE_DELETED = "UPDATE usage_snapshot_on_primary SET deleted = ? WHERE account_id = ? AND id = ? and vm_id = ? and created = ?"; @@ -95,6 +96,8 @@ public class UsageVMSnapshotOnPrimaryDaoImpl extends GenericDaoBase details = new HashMap<>(); + if (vmSnapshot != null) { + details.put(UsageEventVO.DynamicParameters.vmSnapshotId.name(), String.valueOf(vmSnapshot.getId())); + } UsageEventUtils.publishUsageEvent(type, vmSnapshot.getAccountId(), userVm.getDataCenterId(), userVm.getId(), vmSnapshot.getName(), offeringId, volume.getId(), // save volume's id into templateId field - volumeTo.getSize(), VMSnapshot.class.getName(), vmSnapshot.getUuid()); + volumeTo.getSize(), VMSnapshot.class.getName(), vmSnapshot.getUuid(), details); } private void publishUsageEvent(String type, VMSnapshot vmSnapshot, UserVm userVm, Long vmSnapSize, Long virtualSize) { try { + Map details = new HashMap<>(); + if (vmSnapshot != null) { + details.put(UsageEventVO.DynamicParameters.vmSnapshotId.name(), String.valueOf(vmSnapshot.getId())); + } UsageEventUtils.publishUsageEvent(type, vmSnapshot.getAccountId(), userVm.getDataCenterId(), userVm.getId(), vmSnapshot.getName(), 0L, 0L, vmSnapSize, virtualSize, - VMSnapshot.class.getName(), vmSnapshot.getUuid()); + VMSnapshot.class.getName(), vmSnapshot.getUuid(), details); } catch (Exception e) { s_logger.error("Failed to publis usage event " + type, e); } diff --git a/server/src/main/java/com/cloud/api/ApiResponseHelper.java b/server/src/main/java/com/cloud/api/ApiResponseHelper.java index df1eedb90ab..8e6731dd20d 100644 --- a/server/src/main/java/com/cloud/api/ApiResponseHelper.java +++ b/server/src/main/java/com/cloud/api/ApiResponseHelper.java @@ -31,6 +31,8 @@ import java.util.stream.Collectors; import javax.inject.Inject; +import com.cloud.vm.snapshot.VMSnapshotVO; +import com.cloud.vm.snapshot.dao.VMSnapshotDao; import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.affinity.AffinityGroup; @@ -372,6 +374,8 @@ public class ApiResponseHelper implements ResponseGenerator { private IPAddressDao userIpAddressDao; @Inject NetworkDetailsDao networkDetailsDao; + @Inject + private VMSnapshotDao vmSnapshotDao; @Override public UserResponse createUserResponse(User user) { @@ -3643,24 +3647,35 @@ public class ApiResponseHelper implements ResponseGenerator { usageRecResponse.setDescription(builder.toString()); } } else if (usageRecord.getUsageType() == UsageTypes.VM_SNAPSHOT) { - resourceType = ResourceObjectType.UserVm; - if (vmInstance != null) { - resourceId = vmInstance.getId(); - usageRecResponse.setResourceName(vmInstance.getInstanceName()); - usageRecResponse.setUsageId(vmInstance.getUuid()); + resourceType = ResourceObjectType.VMSnapshot; + VMSnapshotVO vmSnapshotVO = null; + if (usageRecord.getUsageId() != null) { + vmSnapshotVO = vmSnapshotDao.findByIdIncludingRemoved(usageRecord.getUsageId()); + if (vmSnapshotVO != null) { + resourceId = vmSnapshotVO.getId(); + usageRecResponse.setResourceName(vmSnapshotVO.getDisplayName()); + usageRecResponse.setUsageId(vmSnapshotVO.getUuid()); + } } usageRecResponse.setSize(usageRecord.getSize()); if (usageRecord.getOfferingId() != null) { usageRecResponse.setOfferingId(usageRecord.getOfferingId().toString()); } if (!oldFormat) { - VolumeVO volume = _entityMgr.findByIdIncludingRemoved(VolumeVO.class, usageRecord.getUsageId().toString()); + VolumeVO volume = null; + if (vmSnapshotVO == null && usageRecord.getUsageId() != null) { + volume = _entityMgr.findByIdIncludingRemoved(VolumeVO.class, usageRecord.getUsageId().toString()); + } + DiskOfferingVO diskOff = null; if (usageRecord.getOfferingId() != null) { diskOff = _entityMgr.findByIdIncludingRemoved(DiskOfferingVO.class, usageRecord.getOfferingId()); } final StringBuilder builder = new StringBuilder(); builder.append("VMSnapshot usage"); + if (vmSnapshotVO != null) { + builder.append(" Id: ").append(vmSnapshotVO.getId()).append(" (").append(vmSnapshotVO.getUuid()).append(") "); + } if (vmInstance != null) { builder.append(" for VM ").append(vmInstance.getHostName()).append(" (").append(vmInstance.getUuid()).append(")"); } @@ -3684,10 +3699,23 @@ public class ApiResponseHelper implements ResponseGenerator { usageRecResponse.setDescription(builder.toString()); } } else if (usageRecord.getUsageType() == UsageTypes.VM_SNAPSHOT_ON_PRIMARY) { + resourceType = ResourceObjectType.VMSnapshot; + VMSnapshotVO vmSnapshotVO = null; + if (usageRecord.getUsageId() != null) { + vmSnapshotVO = vmSnapshotDao.findByIdIncludingRemoved(usageRecord.getUsageId()); + if (vmSnapshotVO != null) { + resourceId = vmSnapshotVO.getId(); + usageRecResponse.setResourceName(vmSnapshotVO.getDisplayName()); + usageRecResponse.setUsageId(vmSnapshotVO.getUuid()); + } + } usageRecResponse.setSize(usageRecord.getVirtualSize()); if (!oldFormat) { final StringBuilder builder = new StringBuilder(); builder.append("VMSnapshot on primary storage usage"); + if (vmSnapshotVO != null) { + builder.append(" Id: ").append(vmSnapshotVO.getId()).append(" (").append(vmSnapshotVO.getUuid()).append(") "); + } if (vmInstance != null) { builder.append(" for VM ").append(vmInstance.getHostName()).append(" (").append(vmInstance.getUuid()).append(") ") .append("with size ").append(usageRecord.getVirtualSize()); diff --git a/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java b/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java index d70910249b2..1abe5f75eb6 100644 --- a/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java +++ b/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java @@ -1827,7 +1827,15 @@ public class UsageManagerImpl extends ManagerBase implements UsageManager, Runna Date created = event.getCreateDate(); Account acct = _accountDao.findByIdIncludingRemoved(event.getAccountId()); Long domainId = acct.getDomainId(); + + UsageEventDetailsVO detailVO = _usageEventDetailsDao.findDetail(event.getId(), UsageEventVO.DynamicParameters.vmSnapshotId.name()); + Long vmSnapshotId = null; + if (detailVO != null) { + String snapId = detailVO.getValue(); + vmSnapshotId = Long.valueOf(snapId); + } UsageVMSnapshotVO vsVO = new UsageVMSnapshotVO(volumeId, zoneId, accountId, domainId, vmId, offeringId, size, created, null); + vsVO.setVmSnapshotId(vmSnapshotId); _usageVMSnapshotDao.persist(vsVO); } @@ -1842,7 +1850,15 @@ public class UsageManagerImpl extends ManagerBase implements UsageManager, Runna Date created = event.getCreateDate(); Account acct = _accountDao.findByIdIncludingRemoved(event.getAccountId()); Long domainId = acct.getDomainId(); + + UsageEventDetailsVO detailVO = _usageEventDetailsDao.findDetail(event.getId(), UsageEventVO.DynamicParameters.vmSnapshotId.name()); + Long vmSnapshotId = null; + if (detailVO != null) { + String snapId = detailVO.getValue(); + vmSnapshotId = Long.valueOf(snapId); + } UsageSnapshotOnPrimaryVO vsVO = new UsageSnapshotOnPrimaryVO(vmId, zoneId, accountId, domainId, vmId, name, 0, virtualsize, physicalsize, created, null); + vsVO.setVmSnapshotId(vmSnapshotId); if (s_logger.isDebugEnabled()) { s_logger.debug("createSnapshotOnPrimaryEvent UsageSnapshotOnPrimaryVO " + vsVO); } diff --git a/usage/src/main/java/com/cloud/usage/parser/VMSanpshotOnPrimaryParser.java b/usage/src/main/java/com/cloud/usage/parser/VMSanpshotOnPrimaryParser.java index 851929507af..d8daad11a34 100644 --- a/usage/src/main/java/com/cloud/usage/parser/VMSanpshotOnPrimaryParser.java +++ b/usage/src/main/java/com/cloud/usage/parser/VMSanpshotOnPrimaryParser.java @@ -94,14 +94,14 @@ public class VMSanpshotOnPrimaryParser { } long duration = (endDateEffective.getTime() - created.getTime()) + 1; createUsageRecord(UsageTypes.VM_SNAPSHOT_ON_PRIMARY, duration, created, endDateEffective, account, usageRec.getId(), usageRec.getName(), usageRec.getZoneId(), - usageRec.getVirtualSize(), usageRec.getPhysicalSize()); + usageRec.getVirtualSize(), usageRec.getPhysicalSize(), usageRec.getVmSnapshotId()); } return true; } private static void createUsageRecord(int usageType, long runningTime, Date startDate, Date endDate, AccountVO account, long vmId, String name, long zoneId, long virtualSize, - long physicalSize) { + long physicalSize, Long vmSnapshotId) { // Our smallest increment is hourly for now if (s_logger.isDebugEnabled()) { s_logger.debug("Total running time " + runningTime + "ms"); @@ -113,16 +113,16 @@ public class VMSanpshotOnPrimaryParser { String usageDisplay = dFormat.format(usage); if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating VMSnapshot On Primary usage record for vm: " + vmId + ", usage: " + usageDisplay + ", startDate: " + startDate + ", endDate: " + endDate + s_logger.debug("Creating VMSnapshot Id: " + vmSnapshotId + " On Primary usage record for vm: " + vmId + ", usage: " + usageDisplay + ", startDate: " + startDate + ", endDate: " + endDate + ", for account: " + account.getId()); } // Create the usage record - String usageDesc = "VMSnapshot On Primary Usage: " + "VM Id: " + vmId; + String usageDesc = "VMSnapshot Id: " + vmSnapshotId + " On Primary Usage: VM Id: " + vmId; usageDesc += " Size: " + virtualSize; UsageVO usageRecord = new UsageVO(zoneId, account.getId(), account.getDomainId(), usageDesc, usageDisplay + " Hrs", usageType, new Double(usage), vmId, name, null, null, - vmId, physicalSize, virtualSize, startDate, endDate); + vmSnapshotId, physicalSize, virtualSize, startDate, endDate); s_usageDao.persist(usageRecord); } diff --git a/usage/src/main/java/com/cloud/usage/parser/VMSnapshotUsageParser.java b/usage/src/main/java/com/cloud/usage/parser/VMSnapshotUsageParser.java index 9af81374437..4dbfd2ec317 100644 --- a/usage/src/main/java/com/cloud/usage/parser/VMSnapshotUsageParser.java +++ b/usage/src/main/java/com/cloud/usage/parser/VMSnapshotUsageParser.java @@ -94,7 +94,7 @@ public class VMSnapshotUsageParser { long duration = (createDate.getTime() - previousCreated.getTime()) + 1; createUsageRecord(UsageTypes.VM_SNAPSHOT, duration, previousCreated, createDate, account, volId, zoneId, previousEvent.getDiskOfferingId(), vmId, - previousEvent.getSize()); + previousEvent.getSize(), usageRec.getVmSnapshotId()); previousEvent.setProcessed(new Date()); s_usageVMSnapshotDao.update(previousEvent); @@ -113,14 +113,14 @@ public class VMSnapshotUsageParser { } long duration = (endDate.getTime() - created.getTime()) + 1; createUsageRecord(UsageTypes.VM_SNAPSHOT, duration, created, endDate, account, usageRec.getId(), usageRec.getZoneId(), usageRec.getDiskOfferingId(), - usageRec.getVmId(), usageRec.getSize()); + usageRec.getVmId(), usageRec.getSize(), usageRec.getVmSnapshotId()); } return true; } private static void createUsageRecord(int type, long runningTime, Date startDate, Date endDate, AccountVO account, long volId, long zoneId, Long doId, Long vmId, - long size) { + long size, Long vmSnapshotId) { // Our smallest increment is hourly for now if (s_logger.isDebugEnabled()) { s_logger.debug("Total running time " + runningTime + "ms"); @@ -132,12 +132,12 @@ public class VMSnapshotUsageParser { String usageDisplay = dFormat.format(usage); if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating VMSnapshot Volume usage record for vol: " + volId + ", usage: " + usageDisplay + ", startDate: " + startDate + ", endDate: " + + s_logger.debug("Creating VMSnapshot Id:" + vmSnapshotId + " Volume usage record for vol: " + volId + ", usage: " + usageDisplay + ", startDate: " + startDate + ", endDate: " + endDate + ", for account: " + account.getId()); } // Create the usage record - String usageDesc = "VMSnapshot Usage: " + "VM Id: " + vmId + " Volume Id: " + volId + " "; + String usageDesc = "VMSnapshot Id: " + vmSnapshotId + " Usage: " + "VM Id: " + vmId + " Volume Id: " + volId + " "; if (doId != null) { usageDesc += " DiskOffering: " + doId; @@ -146,7 +146,7 @@ public class VMSnapshotUsageParser { usageDesc += " Size: " + size; UsageVO usageRecord = - new UsageVO(zoneId, account.getId(), account.getDomainId(), usageDesc, usageDisplay + " Hrs", type, new Double(usage), vmId, null, doId, null, volId, size, + new UsageVO(zoneId, account.getId(), account.getDomainId(), usageDesc, usageDisplay + " Hrs", type, new Double(usage), vmId, null, doId, null, vmSnapshotId, size, startDate, endDate); s_usageDao.persist(usageRecord); }