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
This commit is contained in:
Nicolas Vazquez 2019-08-20 10:20:23 -03:00 committed by Paul Angus
parent 7ac9f00eee
commit bfc08715cc
12 changed files with 152 additions and 28 deletions

View File

@ -25,6 +25,7 @@ import java.util.Map;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import javax.inject.Inject; import javax.inject.Inject;
import org.apache.commons.collections.MapUtils;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.NoSuchBeanDefinitionException;
@ -69,6 +70,12 @@ public class UsageEventUtils {
s_configDao = configDao; 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<String, String> 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, 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 size, String entityType, String entityUUID) {
saveUsageEvent(usageType, accountId, zoneId, resourceId, resourceName, offeringId, templateId, size); 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<String, String> 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, 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) { Long size, Long virtualSize, String entityType, String entityUUID) {
saveUsageEvent(usageType, accountId, zoneId, resourceId, resourceName, offeringId, templateId, size, virtualSize); 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)); 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<String, String> 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, public static void saveUsageEvent(String usageType, long accountId, long zoneId, long resourceId, String resourceName, Long offeringId, Long templateId, Long size,
Long virtualSize) { Long virtualSize) {
s_usageEventDao.persist(new UsageEventVO(usageType, accountId, zoneId, resourceId, resourceName, offeringId, templateId, size, 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<String, String> 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) { public static void saveUsageEvent(String usageType, long accountId, long zoneId, long resourceId, String resourceName) {
s_usageEventDao.persist(new UsageEventVO(usageType, accountId, zoneId, resourceId, resourceName)); s_usageEventDao.persist(new UsageEventVO(usageType, accountId, zoneId, resourceId, resourceName));
} }

View File

@ -31,7 +31,7 @@ import com.cloud.utils.db.GenericDao;
@Table(name = "usage_event") @Table(name = "usage_event")
public class UsageEventVO implements UsageEvent { public class UsageEventVO implements UsageEvent {
public enum DynamicParameters { public enum DynamicParameters {
cpuSpeed, cpuNumber, memory cpuSpeed, cpuNumber, memory, vmSnapshotId
}; };
@Id @Id

View File

@ -66,6 +66,9 @@ public class UsageSnapshotOnPrimaryVO implements InternalIdentity {
@Column(name = "virtualsize") @Column(name = "virtualsize")
private Long virtualSize; private Long virtualSize;
@Column(name = "vm_snapshot_id")
private Long vmSnapshotId;
protected UsageSnapshotOnPrimaryVO() { protected UsageSnapshotOnPrimaryVO() {
} }
@ -136,10 +139,18 @@ public class UsageSnapshotOnPrimaryVO implements InternalIdentity {
return this.id; return this.id;
} }
public Long getVmSnapshotId() {
return vmSnapshotId;
}
public void setVmSnapshotId(Long vmSnapshotId) {
this.vmSnapshotId = vmSnapshotId;
}
@Override @Override
public String toString() { public String toString() {
return "UsageSnapshotOnPrimaryVO [id=" + id + ", zoneId=" + zoneId + ", accountId=" + accountId + ", domainId=" + domainId + ", vmId=" + vmId + ", name=" + name 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 + "]";
} }
} }

View File

@ -60,6 +60,9 @@ public class UsageVMSnapshotVO implements InternalIdentity {
@Temporal(value = TemporalType.TIMESTAMP) @Temporal(value = TemporalType.TIMESTAMP)
private Date processed; private Date processed;
@Column(name = "vm_snapshot_id")
private Long vmSnapshotId;
protected UsageVMSnapshotVO() { protected UsageVMSnapshotVO() {
} }
@ -120,10 +123,18 @@ public class UsageVMSnapshotVO implements InternalIdentity {
return this.id; return this.id;
} }
public Long getVmSnapshotId() {
return vmSnapshotId;
}
public void setVmSnapshotId(Long vmSnapshotId) {
this.vmSnapshotId = vmSnapshotId;
}
@Override @Override
public String toString() { public String toString() {
return "UsageVMSnapshotVO [id=" + id + ", zoneId=" + zoneId + ", accountId=" + accountId + ", domainId=" + domainId + ", vmId=" + vmId + ", diskOfferingId=" 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 + "]";
} }
} }

View File

@ -25,6 +25,7 @@ import java.util.List;
import java.util.TimeZone; import java.util.TimeZone;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -36,12 +37,12 @@ import com.cloud.utils.db.TransactionLegacy;
@Component @Component
public class UsageVMSnapshotDaoImpl extends GenericDaoBase<UsageVMSnapshotVO, Long> implements UsageVMSnapshotDao { public class UsageVMSnapshotDaoImpl extends GenericDaoBase<UsageVMSnapshotVO, Long> implements UsageVMSnapshotDao {
public static final Logger s_logger = Logger.getLogger(UsageVMSnapshotDaoImpl.class.getName()); 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 " + " FROM usage_vmsnapshot" + " WHERE account_id = ? " + " AND ( (created BETWEEN ? AND ?) OR "
+ " (created < ? AND processed is NULL) ) ORDER BY created asc"; + " (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 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"; + "FROM usage_vmsnapshot " + "WHERE account_id = ? AND id = ? AND vm_id = ? AND created < ? AND processed IS NULL " + "ORDER BY created desc limit 1";
@Override @Override
@ -99,6 +100,8 @@ public class UsageVMSnapshotDaoImpl extends GenericDaoBase<UsageVMSnapshotVO, Lo
Date processDate = null; Date processDate = null;
String createdTS = rs.getString(8); String createdTS = rs.getString(8);
String processed = rs.getString(9); String processed = rs.getString(9);
String snapId = rs.getString(10);
Long vmSnapshotId = StringUtils.isNotBlank(snapId) ? Long.valueOf(snapId) : null;
if (createdTS != null) { if (createdTS != null) {
createdDate = DateUtil.parseDateString(s_gmtTimeZone, createdTS); createdDate = DateUtil.parseDateString(s_gmtTimeZone, createdTS);
@ -106,7 +109,9 @@ public class UsageVMSnapshotDaoImpl extends GenericDaoBase<UsageVMSnapshotVO, Lo
if (processed != null) { if (processed != null) {
processDate = DateUtil.parseDateString(s_gmtTimeZone, processed); processDate = DateUtil.parseDateString(s_gmtTimeZone, processed);
} }
usageRecords.add(new UsageVMSnapshotVO(vId, zoneId, acctId, dId, vmId, doId, size, createdDate, processDate)); UsageVMSnapshotVO usageVMSnapshotVO = new UsageVMSnapshotVO(vId, zoneId, acctId, dId, vmId, doId, size, createdDate, processDate);
usageVMSnapshotVO.setVmSnapshotId(vmSnapshotId);
usageRecords.add(usageVMSnapshotVO);
} }
} catch (Exception e) { } catch (Exception e) {
txn.rollback(); txn.rollback();
@ -150,6 +155,8 @@ public class UsageVMSnapshotDaoImpl extends GenericDaoBase<UsageVMSnapshotVO, Lo
Date processDate = null; Date processDate = null;
String createdTS = rs.getString(8); String createdTS = rs.getString(8);
String processed = rs.getString(9); String processed = rs.getString(9);
String snapId = rs.getString(10);
Long vmSnapshotId = StringUtils.isNotBlank(snapId) ? Long.valueOf(snapId) : null;
if (createdTS != null) { if (createdTS != null) {
createdDate = DateUtil.parseDateString(s_gmtTimeZone, createdTS); createdDate = DateUtil.parseDateString(s_gmtTimeZone, createdTS);
@ -157,7 +164,9 @@ public class UsageVMSnapshotDaoImpl extends GenericDaoBase<UsageVMSnapshotVO, Lo
if (processed != null) { if (processed != null) {
processDate = DateUtil.parseDateString(s_gmtTimeZone, processed); processDate = DateUtil.parseDateString(s_gmtTimeZone, processed);
} }
usageRecords.add(new UsageVMSnapshotVO(vId, zoneId, acctId, dId, vmId, doId, size, createdDate, processDate)); UsageVMSnapshotVO usageVMSnapshotVO = new UsageVMSnapshotVO(vId, zoneId, acctId, dId, vmId, doId, size, createdDate, processDate);
usageVMSnapshotVO.setVmSnapshotId(vmSnapshotId);
usageRecords.add(usageVMSnapshotVO);
} }
} catch (Exception e) { } catch (Exception e) {
txn.rollback(); txn.rollback();

View File

@ -25,6 +25,7 @@ import java.util.List;
import java.util.TimeZone; import java.util.TimeZone;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -36,7 +37,7 @@ import com.cloud.utils.db.TransactionLegacy;
@Component @Component
public class UsageVMSnapshotOnPrimaryDaoImpl extends GenericDaoBase<UsageSnapshotOnPrimaryVO, Long> implements UsageVMSnapshotOnPrimaryDao { public class UsageVMSnapshotOnPrimaryDaoImpl extends GenericDaoBase<UsageSnapshotOnPrimaryVO, Long> implements UsageVMSnapshotOnPrimaryDao {
public static final Logger s_logger = Logger.getLogger(UsageVMSnapshotOnPrimaryDaoImpl.class.getName()); 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)" + " FROM usage_snapshot_on_primary" + " WHERE account_id = ? " + " AND ( (created < ? AND deleted is NULL)"
+ " OR ( deleted BETWEEN ? AND ?)) ORDER BY created asc"; + " 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 = ?"; 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<UsageSnapsho
Date deleteDate = null; Date deleteDate = null;
String createdTS = rs.getString(10); String createdTS = rs.getString(10);
String deleted = rs.getString(11); String deleted = rs.getString(11);
String snapId = rs.getString(12);
Long vmSnapshotId = StringUtils.isNotBlank(snapId) ? Long.valueOf(snapId) : null;
if (createdTS != null) { if (createdTS != null) {
createdDate = DateUtil.parseDateString(s_gmtTimeZone, createdTS); createdDate = DateUtil.parseDateString(s_gmtTimeZone, createdTS);
@ -102,7 +105,9 @@ public class UsageVMSnapshotOnPrimaryDaoImpl extends GenericDaoBase<UsageSnapsho
if (deleted != null) { if (deleted != null) {
deleteDate = DateUtil.parseDateString(s_gmtTimeZone, deleted); deleteDate = DateUtil.parseDateString(s_gmtTimeZone, deleted);
} }
usageRecords.add(new UsageSnapshotOnPrimaryVO(vId, zoneId, acctId, dId, vmId, name, type, virtaulSize, physicalSize, createdDate, deleteDate)); UsageSnapshotOnPrimaryVO usageSnapshotOnPrimaryVO = new UsageSnapshotOnPrimaryVO(vId, zoneId, acctId, dId, vmId, name, type, virtaulSize, physicalSize, createdDate, deleteDate);
usageSnapshotOnPrimaryVO.setVmSnapshotId(vmSnapshotId);
usageRecords.add(usageSnapshotOnPrimaryVO);
} }
} catch (Exception e) { } catch (Exception e) {
txn.rollback(); txn.rollback();

View File

@ -531,3 +531,7 @@ CREATE TABLE `cloud`.`template_ovf_properties` (
CONSTRAINT `fk_template_ovf_properties__template_id` FOREIGN KEY (`template_id`) REFERENCES `vm_template`(`id`) CONSTRAINT `fk_template_ovf_properties__template_id` FOREIGN KEY (`template_id`) REFERENCES `vm_template`(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8; ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- Add VM snapshot ID on usage helper tables
ALTER TABLE `cloud_usage`.`usage_vmsnapshot` ADD COLUMN `vm_snapshot_id` BIGINT(20) NULL DEFAULT NULL AFTER `processed`;
ALTER TABLE `cloud_usage`.`usage_snapshot_on_primary` ADD COLUMN `vm_snapshot_id` BIGINT(20) NULL DEFAULT NULL AFTER `deleted`;

View File

@ -18,12 +18,14 @@
*/ */
package org.apache.cloudstack.storage.vmsnapshot; package org.apache.cloudstack.storage.vmsnapshot;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.inject.Inject; import javax.inject.Inject;
import javax.naming.ConfigurationException; import javax.naming.ConfigurationException;
import com.cloud.event.UsageEventVO;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority; import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority;
@ -337,14 +339,22 @@ public class DefaultVMSnapshotStrategy extends ManagerBase implements VMSnapshot
offeringId = offering.getId(); offeringId = offering.getId();
} }
} }
Map<String, String> 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 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) { private void publishUsageEvent(String type, VMSnapshot vmSnapshot, UserVm userVm, Long vmSnapSize, Long virtualSize) {
try { try {
Map<String, String> 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, 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) { } catch (Exception e) {
s_logger.error("Failed to publis usage event " + type, e); s_logger.error("Failed to publis usage event " + type, e);
} }

View File

@ -31,6 +31,8 @@ import java.util.stream.Collectors;
import javax.inject.Inject; 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;
import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.affinity.AffinityGroup; import org.apache.cloudstack.affinity.AffinityGroup;
@ -372,6 +374,8 @@ public class ApiResponseHelper implements ResponseGenerator {
private IPAddressDao userIpAddressDao; private IPAddressDao userIpAddressDao;
@Inject @Inject
NetworkDetailsDao networkDetailsDao; NetworkDetailsDao networkDetailsDao;
@Inject
private VMSnapshotDao vmSnapshotDao;
@Override @Override
public UserResponse createUserResponse(User user) { public UserResponse createUserResponse(User user) {
@ -3643,24 +3647,35 @@ public class ApiResponseHelper implements ResponseGenerator {
usageRecResponse.setDescription(builder.toString()); usageRecResponse.setDescription(builder.toString());
} }
} else if (usageRecord.getUsageType() == UsageTypes.VM_SNAPSHOT) { } else if (usageRecord.getUsageType() == UsageTypes.VM_SNAPSHOT) {
resourceType = ResourceObjectType.UserVm; resourceType = ResourceObjectType.VMSnapshot;
if (vmInstance != null) { VMSnapshotVO vmSnapshotVO = null;
resourceId = vmInstance.getId(); if (usageRecord.getUsageId() != null) {
usageRecResponse.setResourceName(vmInstance.getInstanceName()); vmSnapshotVO = vmSnapshotDao.findByIdIncludingRemoved(usageRecord.getUsageId());
usageRecResponse.setUsageId(vmInstance.getUuid()); if (vmSnapshotVO != null) {
resourceId = vmSnapshotVO.getId();
usageRecResponse.setResourceName(vmSnapshotVO.getDisplayName());
usageRecResponse.setUsageId(vmSnapshotVO.getUuid());
}
} }
usageRecResponse.setSize(usageRecord.getSize()); usageRecResponse.setSize(usageRecord.getSize());
if (usageRecord.getOfferingId() != null) { if (usageRecord.getOfferingId() != null) {
usageRecResponse.setOfferingId(usageRecord.getOfferingId().toString()); usageRecResponse.setOfferingId(usageRecord.getOfferingId().toString());
} }
if (!oldFormat) { 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; DiskOfferingVO diskOff = null;
if (usageRecord.getOfferingId() != null) { if (usageRecord.getOfferingId() != null) {
diskOff = _entityMgr.findByIdIncludingRemoved(DiskOfferingVO.class, usageRecord.getOfferingId()); diskOff = _entityMgr.findByIdIncludingRemoved(DiskOfferingVO.class, usageRecord.getOfferingId());
} }
final StringBuilder builder = new StringBuilder(); final StringBuilder builder = new StringBuilder();
builder.append("VMSnapshot usage"); builder.append("VMSnapshot usage");
if (vmSnapshotVO != null) {
builder.append(" Id: ").append(vmSnapshotVO.getId()).append(" (").append(vmSnapshotVO.getUuid()).append(") ");
}
if (vmInstance != null) { if (vmInstance != null) {
builder.append(" for VM ").append(vmInstance.getHostName()).append(" (").append(vmInstance.getUuid()).append(")"); 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()); usageRecResponse.setDescription(builder.toString());
} }
} else if (usageRecord.getUsageType() == UsageTypes.VM_SNAPSHOT_ON_PRIMARY) { } 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()); usageRecResponse.setSize(usageRecord.getVirtualSize());
if (!oldFormat) { if (!oldFormat) {
final StringBuilder builder = new StringBuilder(); final StringBuilder builder = new StringBuilder();
builder.append("VMSnapshot on primary storage usage"); builder.append("VMSnapshot on primary storage usage");
if (vmSnapshotVO != null) {
builder.append(" Id: ").append(vmSnapshotVO.getId()).append(" (").append(vmSnapshotVO.getUuid()).append(") ");
}
if (vmInstance != null) { if (vmInstance != null) {
builder.append(" for VM ").append(vmInstance.getHostName()).append(" (").append(vmInstance.getUuid()).append(") ") builder.append(" for VM ").append(vmInstance.getHostName()).append(" (").append(vmInstance.getUuid()).append(") ")
.append("with size ").append(usageRecord.getVirtualSize()); .append("with size ").append(usageRecord.getVirtualSize());

View File

@ -1827,7 +1827,15 @@ public class UsageManagerImpl extends ManagerBase implements UsageManager, Runna
Date created = event.getCreateDate(); Date created = event.getCreateDate();
Account acct = _accountDao.findByIdIncludingRemoved(event.getAccountId()); Account acct = _accountDao.findByIdIncludingRemoved(event.getAccountId());
Long domainId = acct.getDomainId(); 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); UsageVMSnapshotVO vsVO = new UsageVMSnapshotVO(volumeId, zoneId, accountId, domainId, vmId, offeringId, size, created, null);
vsVO.setVmSnapshotId(vmSnapshotId);
_usageVMSnapshotDao.persist(vsVO); _usageVMSnapshotDao.persist(vsVO);
} }
@ -1842,7 +1850,15 @@ public class UsageManagerImpl extends ManagerBase implements UsageManager, Runna
Date created = event.getCreateDate(); Date created = event.getCreateDate();
Account acct = _accountDao.findByIdIncludingRemoved(event.getAccountId()); Account acct = _accountDao.findByIdIncludingRemoved(event.getAccountId());
Long domainId = acct.getDomainId(); 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); UsageSnapshotOnPrimaryVO vsVO = new UsageSnapshotOnPrimaryVO(vmId, zoneId, accountId, domainId, vmId, name, 0, virtualsize, physicalsize, created, null);
vsVO.setVmSnapshotId(vmSnapshotId);
if (s_logger.isDebugEnabled()) { if (s_logger.isDebugEnabled()) {
s_logger.debug("createSnapshotOnPrimaryEvent UsageSnapshotOnPrimaryVO " + vsVO); s_logger.debug("createSnapshotOnPrimaryEvent UsageSnapshotOnPrimaryVO " + vsVO);
} }

View File

@ -94,14 +94,14 @@ public class VMSanpshotOnPrimaryParser {
} }
long duration = (endDateEffective.getTime() - created.getTime()) + 1; long duration = (endDateEffective.getTime() - created.getTime()) + 1;
createUsageRecord(UsageTypes.VM_SNAPSHOT_ON_PRIMARY, duration, created, endDateEffective, account, usageRec.getId(), usageRec.getName(), usageRec.getZoneId(), 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; return true;
} }
private static void createUsageRecord(int usageType, long runningTime, Date startDate, Date endDate, AccountVO account, long vmId, String name, long zoneId, long virtualSize, 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 // Our smallest increment is hourly for now
if (s_logger.isDebugEnabled()) { if (s_logger.isDebugEnabled()) {
s_logger.debug("Total running time " + runningTime + "ms"); s_logger.debug("Total running time " + runningTime + "ms");
@ -113,16 +113,16 @@ public class VMSanpshotOnPrimaryParser {
String usageDisplay = dFormat.format(usage); String usageDisplay = dFormat.format(usage);
if (s_logger.isDebugEnabled()) { 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()); + ", for account: " + account.getId());
} }
// Create the usage record // 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; usageDesc += " Size: " + virtualSize;
UsageVO usageRecord = new UsageVO(zoneId, account.getId(), account.getDomainId(), usageDesc, usageDisplay + " Hrs", usageType, new Double(usage), vmId, name, null, null, 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); s_usageDao.persist(usageRecord);
} }

View File

@ -94,7 +94,7 @@ public class VMSnapshotUsageParser {
long duration = (createDate.getTime() - previousCreated.getTime()) + 1; long duration = (createDate.getTime() - previousCreated.getTime()) + 1;
createUsageRecord(UsageTypes.VM_SNAPSHOT, duration, previousCreated, createDate, account, volId, zoneId, previousEvent.getDiskOfferingId(), vmId, createUsageRecord(UsageTypes.VM_SNAPSHOT, duration, previousCreated, createDate, account, volId, zoneId, previousEvent.getDiskOfferingId(), vmId,
previousEvent.getSize()); previousEvent.getSize(), usageRec.getVmSnapshotId());
previousEvent.setProcessed(new Date()); previousEvent.setProcessed(new Date());
s_usageVMSnapshotDao.update(previousEvent); s_usageVMSnapshotDao.update(previousEvent);
@ -113,14 +113,14 @@ public class VMSnapshotUsageParser {
} }
long duration = (endDate.getTime() - created.getTime()) + 1; long duration = (endDate.getTime() - created.getTime()) + 1;
createUsageRecord(UsageTypes.VM_SNAPSHOT, duration, created, endDate, account, usageRec.getId(), usageRec.getZoneId(), usageRec.getDiskOfferingId(), 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; return true;
} }
private static void createUsageRecord(int type, long runningTime, Date startDate, Date endDate, AccountVO account, long volId, long zoneId, Long doId, Long vmId, 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 // Our smallest increment is hourly for now
if (s_logger.isDebugEnabled()) { if (s_logger.isDebugEnabled()) {
s_logger.debug("Total running time " + runningTime + "ms"); s_logger.debug("Total running time " + runningTime + "ms");
@ -132,12 +132,12 @@ public class VMSnapshotUsageParser {
String usageDisplay = dFormat.format(usage); String usageDisplay = dFormat.format(usage);
if (s_logger.isDebugEnabled()) { 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()); endDate + ", for account: " + account.getId());
} }
// Create the usage record // 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) { if (doId != null) {
usageDesc += " DiskOffering: " + doId; usageDesc += " DiskOffering: " + doId;
@ -146,7 +146,7 @@ public class VMSnapshotUsageParser {
usageDesc += " Size: " + size; usageDesc += " Size: " + size;
UsageVO usageRecord = 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); startDate, endDate);
s_usageDao.persist(usageRecord); s_usageDao.persist(usageRecord);
} }