This is an automated email from the ASF dual-hosted git repository.

rohit pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/master by this push:
     new 391952d  CLOUDSTACK-9867: VM snapshot on primary storage usage metrics 
(#2035)
391952d is described below

commit 391952da5bd522e44e0a17723c6ec77254a76353
Author: Abhinandan Prateek <[email protected]>
AuthorDate: Thu Dec 28 14:57:10 2017 +0530

    CLOUDSTACK-9867: VM snapshot on primary storage usage metrics (#2035)
    
    VM snapshot on primary storage usage metrics.
---
 api/src/com/cloud/event/EventTypes.java            |   6 +
 .../org/apache/cloudstack/usage/UsageTypes.java    |   2 +
 .../resources/META-INF/db/schema-41000to41100.sql  |  17 +++
 ...apshotVO.java => UsageSnapshotOnPrimaryVO.java} |  66 +++++++----
 .../src/com/cloud/usage/UsageVMSnapshotVO.java     |   6 +
 .../usage/dao/UsageVMSnapshotOnPrimaryDao.java     |  31 +++++
 .../usage/dao/UsageVMSnapshotOnPrimaryDaoImpl.java | 117 +++++++++++++++++++
 .../storage/snapshot/SnapshotServiceImpl.java      |   4 +
 .../snapshot/StorageSystemSnapshotStrategy.java    |   6 +
 .../snapshot/XenserverSnapshotStrategy.java        |   6 +-
 .../vmsnapshot/DefaultVMSnapshotStrategy.java      |  26 ++++-
 .../storage/endpoint/DefaultEndPointSelector.java  |   1 +
 .../cloudstack/quota/constant/QuotaTypes.java      |   1 +
 usage/src/com/cloud/usage/UsageManagerImpl.java    |  62 ++++++++++
 .../usage/parser/VMSanpshotOnPrimaryParser.java    | 129 +++++++++++++++++++++
 15 files changed, 454 insertions(+), 26 deletions(-)

diff --git a/api/src/com/cloud/event/EventTypes.java 
b/api/src/com/cloud/event/EventTypes.java
index ce410a6..26b6922 100644
--- a/api/src/com/cloud/event/EventTypes.java
+++ b/api/src/com/cloud/event/EventTypes.java
@@ -241,6 +241,8 @@ public class EventTypes {
 
     // Snapshots
     public static final String EVENT_SNAPSHOT_CREATE = "SNAPSHOT.CREATE";
+    public static final String EVENT_SNAPSHOT_ON_PRIMARY = 
"SNAPSHOT.ON_PRIMARY";
+    public static final String EVENT_SNAPSHOT_OFF_PRIMARY = 
"SNAPSHOT.OFF_PRIMARY";
     public static final String EVENT_SNAPSHOT_DELETE = "SNAPSHOT.DELETE";
     public static final String EVENT_SNAPSHOT_REVERT = "SNAPSHOT.REVERT";
     public static final String EVENT_SNAPSHOT_POLICY_CREATE = 
"SNAPSHOTPOLICY.CREATE";
@@ -462,6 +464,8 @@ public class EventTypes {
     // vm snapshot events
     public static final String EVENT_VM_SNAPSHOT_CREATE = "VMSNAPSHOT.CREATE";
     public static final String EVENT_VM_SNAPSHOT_DELETE = "VMSNAPSHOT.DELETE";
+    public static final String EVENT_VM_SNAPSHOT_ON_PRIMARY = 
"VMSNAPSHOT.ON_PRIMARY";
+    public static final String EVENT_VM_SNAPSHOT_OFF_PRIMARY = 
"VMSNAPSHOT.OFF_PRIMARY";
     public static final String EVENT_VM_SNAPSHOT_REVERT = 
"VMSNAPSHOT.REVERTTO";
 
     // external network device events
@@ -711,6 +715,8 @@ public class EventTypes {
         // Snapshots
         entityEventDetails.put(EVENT_SNAPSHOT_CREATE, Snapshot.class);
         entityEventDetails.put(EVENT_SNAPSHOT_DELETE, Snapshot.class);
+        entityEventDetails.put(EVENT_SNAPSHOT_ON_PRIMARY, Snapshot.class);
+        entityEventDetails.put(EVENT_SNAPSHOT_OFF_PRIMARY, Snapshot.class);
         entityEventDetails.put(EVENT_SNAPSHOT_POLICY_CREATE, 
SnapshotPolicy.class);
         entityEventDetails.put(EVENT_SNAPSHOT_POLICY_UPDATE, 
SnapshotPolicy.class);
         entityEventDetails.put(EVENT_SNAPSHOT_POLICY_DELETE, 
SnapshotPolicy.class);
diff --git a/api/src/org/apache/cloudstack/usage/UsageTypes.java 
b/api/src/org/apache/cloudstack/usage/UsageTypes.java
index 08cd7dd..f03d9a9 100644
--- a/api/src/org/apache/cloudstack/usage/UsageTypes.java
+++ b/api/src/org/apache/cloudstack/usage/UsageTypes.java
@@ -43,6 +43,7 @@ public class UsageTypes {
     public static final int VM_DISK_BYTES_WRITE = 24;
     public static final int VM_SNAPSHOT = 25;
     public static final int VOLUME_SECONDARY = 26;
+    public static final int VM_SNAPSHOT_ON_PRIMARY = 27;
 
     public static List<UsageTypeResponse> listUsageTypes() {
         List<UsageTypeResponse> responseList = new 
ArrayList<UsageTypeResponse>();
@@ -65,6 +66,7 @@ public class UsageTypes {
         responseList.add(new UsageTypeResponse(VM_DISK_BYTES_READ, "VM Disk 
usage(Bytes Read)"));
         responseList.add(new UsageTypeResponse(VM_DISK_BYTES_WRITE, "VM Disk 
usage(Bytes Write)"));
         responseList.add(new UsageTypeResponse(VM_SNAPSHOT, "VM Snapshot 
storage usage"));
+        responseList.add(new UsageTypeResponse(VM_SNAPSHOT_ON_PRIMARY, "VM 
Snapshot on primary storage usage"));
         return responseList;
     }
 }
diff --git a/engine/schema/resources/META-INF/db/schema-41000to41100.sql 
b/engine/schema/resources/META-INF/db/schema-41000to41100.sql
index 19c9039..5d51b47 100644
--- a/engine/schema/resources/META-INF/db/schema-41000to41100.sql
+++ b/engine/schema/resources/META-INF/db/schema-41000to41100.sql
@@ -490,6 +490,23 @@ INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid, 
hypervisor_type, hypervi
 
 INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, 
hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) 
SELECT UUID(),'Xenserver', '7.2.0', guest_os_name, guest_os_id, 
utc_timestamp(), 0  FROM `cloud`.`guest_os_hypervisor` WHERE 
hypervisor_type='Xenserver' AND hypervisor_version='7.1.0' AND guest_os_id not 
in 
(1,2,3,4,56,101,56,58,93,94,50,51,87,88,89,90,91,92,26,27,28,29,40,41,42,43,44,45,96,97,107,108,109,110,151,152,153);
 
+-- Add table to track primary storage in use for snapshots
+DROP TABLE IF EXISTS `cloud_usage`.`usage_snapshot_on_primary`;
+CREATE TABLE `cloud_usage`.`usage_snapshot_on_primary` (
+  `id` bigint(20) unsigned NOT NULL,
+  `zone_id` bigint(20) unsigned NOT NULL,
+  `account_id` bigint(20) unsigned NOT NULL,
+  `domain_id` bigint(20) unsigned NOT NULL,
+  `vm_id` bigint(20) unsigned NOT NULL,
+  `name` varchar(128),
+  `type` int(1) unsigned NOT NULL,
+  `physicalsize` bigint(20),
+  `virtualsize` bigint(20),
+  `created` datetime NOT NULL,
+  `deleted` datetime,
+  INDEX `i_usage_snapshot_on_primary` (`account_id`,`id`,`vm_id`,`created`)
+) ENGINE=InnoDB CHARSET=utf8;
+
 -- Change monitor patch for apache2 in systemvm
 UPDATE `cloud`.`monitoring_services` SET 
pidfile="/var/run/apache2/apache2.pid" WHERE process_name="apache2" AND 
service_name="apache2";
 
diff --git a/engine/schema/src/com/cloud/usage/UsageVMSnapshotVO.java 
b/engine/schema/src/com/cloud/usage/UsageSnapshotOnPrimaryVO.java
similarity index 58%
copy from engine/schema/src/com/cloud/usage/UsageVMSnapshotVO.java
copy to engine/schema/src/com/cloud/usage/UsageSnapshotOnPrimaryVO.java
index 1266d63..74f944b 100644
--- a/engine/schema/src/com/cloud/usage/UsageVMSnapshotVO.java
+++ b/engine/schema/src/com/cloud/usage/UsageSnapshotOnPrimaryVO.java
@@ -27,8 +27,8 @@ import javax.persistence.TemporalType;
 import org.apache.cloudstack.api.InternalIdentity;
 
 @Entity
-@Table(name = "usage_vmsnapshot")
-public class UsageVMSnapshotVO implements InternalIdentity {
+@Table(name = "usage_snapshot_on_primary")
+public class UsageSnapshotOnPrimaryVO implements InternalIdentity {
 
     @Column(name = "id")
     // volumeId
@@ -46,33 +46,41 @@ public class UsageVMSnapshotVO implements InternalIdentity {
     @Column(name = "vm_id")
     private long vmId;
 
-    @Column(name = "disk_offering_id")
-    private Long diskOfferingId;
+    @Column(name = "name")
+    private String name;
 
-    @Column(name = "size")
-    private long size;
+    @Column(name = "type")
+    private int snapshotType;
+
+    @Column(name = "physicalsize")
+    private long physicalSize;
 
     @Column(name = "created")
     @Temporal(value = TemporalType.TIMESTAMP)
     private Date created = null;
 
-    @Column(name = "processed")
+    @Column(name = "deleted")
     @Temporal(value = TemporalType.TIMESTAMP)
-    private Date processed;
+    private Date deleted;
+
+    @Column(name = "virtualsize")
+    private Long virtualSize;
 
-    protected UsageVMSnapshotVO() {
+    protected UsageSnapshotOnPrimaryVO() {
     }
 
-    public UsageVMSnapshotVO(long id, long zoneId, long accountId, long 
domainId, long vmId, Long diskOfferingId, long size, Date created, Date 
processed) {
+    public UsageSnapshotOnPrimaryVO(long id, long zoneId, long accountId, long 
domainId, long vmId, String name, int type, long virtualSize, long 
physicalSize, Date created, Date deleted) {
+        this.id = id;
         this.zoneId = zoneId;
         this.accountId = accountId;
         this.domainId = domainId;
-        this.diskOfferingId = diskOfferingId;
-        this.id = id;
-        this.size = size;
+        this.snapshotType = type;
+        this.physicalSize = physicalSize;
+        this.virtualSize = virtualSize;
         this.created = created;
         this.vmId = vmId;
-        this.processed = processed;
+        this.name = name;
+        this.deleted = deleted;
     }
 
     public long getZoneId() {
@@ -87,20 +95,24 @@ public class UsageVMSnapshotVO implements InternalIdentity {
         return domainId;
     }
 
-    public Long getDiskOfferingId() {
-        return diskOfferingId;
+    public int getSnapshotType() {
+        return snapshotType;
+    }
+
+    public long getPhysicalSize() {
+        return physicalSize;
     }
 
-    public long getSize() {
-        return size;
+    public Long getVirtualSize() {
+        return virtualSize;
     }
 
-    public Date getProcessed() {
-        return processed;
+    public Date getDeleted() {
+        return deleted;
     }
 
-    public void setProcessed(Date processed) {
-        this.processed = processed;
+    public void setDeleted(Date deleted) {
+        this.deleted = deleted;
     }
 
     public Date getCreated() {
@@ -115,9 +127,19 @@ public class UsageVMSnapshotVO implements InternalIdentity 
{
         return vmId;
     }
 
+    public String getName() {
+        return name;
+    }
+
     @Override
     public long getId() {
         return this.id;
     }
 
+    @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 + "]";
+    }
+
 }
diff --git a/engine/schema/src/com/cloud/usage/UsageVMSnapshotVO.java 
b/engine/schema/src/com/cloud/usage/UsageVMSnapshotVO.java
index 1266d63..05a1b29 100644
--- a/engine/schema/src/com/cloud/usage/UsageVMSnapshotVO.java
+++ b/engine/schema/src/com/cloud/usage/UsageVMSnapshotVO.java
@@ -120,4 +120,10 @@ public class UsageVMSnapshotVO implements InternalIdentity 
{
         return this.id;
     }
 
+    @Override
+    public String toString() {
+        return "UsageVMSnapshotVO [id=" + id + ", zoneId=" + zoneId + ", 
accountId=" + accountId + ", domainId=" + domainId + ", vmId=" + vmId + ", 
diskOfferingId="
+                + diskOfferingId + ", size=" + size + ", created=" + created + 
", processed=" + processed + "]";
+    }
+
 }
diff --git 
a/engine/schema/src/com/cloud/usage/dao/UsageVMSnapshotOnPrimaryDao.java 
b/engine/schema/src/com/cloud/usage/dao/UsageVMSnapshotOnPrimaryDao.java
new file mode 100644
index 0000000..09d6e00
--- /dev/null
+++ b/engine/schema/src/com/cloud/usage/dao/UsageVMSnapshotOnPrimaryDao.java
@@ -0,0 +1,31 @@
+// 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.usage.dao;
+
+import java.util.Date;
+import java.util.List;
+
+import com.cloud.usage.UsageSnapshotOnPrimaryVO;
+import com.cloud.utils.db.GenericDao;
+
+public interface UsageVMSnapshotOnPrimaryDao extends 
GenericDao<UsageSnapshotOnPrimaryVO, Long> {
+
+    public void updateDeleted(UsageSnapshotOnPrimaryVO usage);
+
+    public List<UsageSnapshotOnPrimaryVO> getUsageRecords(Long accountId, Long 
domainId, Date startDate, Date endDate);
+
+}
diff --git 
a/engine/schema/src/com/cloud/usage/dao/UsageVMSnapshotOnPrimaryDaoImpl.java 
b/engine/schema/src/com/cloud/usage/dao/UsageVMSnapshotOnPrimaryDaoImpl.java
new file mode 100644
index 0000000..5926938
--- /dev/null
+++ b/engine/schema/src/com/cloud/usage/dao/UsageVMSnapshotOnPrimaryDaoImpl.java
@@ -0,0 +1,117 @@
+// 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.usage.dao;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.TimeZone;
+
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.usage.UsageSnapshotOnPrimaryVO;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.TransactionLegacy;
+
+@Component
+public class UsageVMSnapshotOnPrimaryDaoImpl extends 
GenericDaoBase<UsageSnapshotOnPrimaryVO, Long> 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 "
+        + " 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 = ?";
+
+    @Override
+    public void updateDeleted(UsageSnapshotOnPrimaryVO usage) {
+        TransactionLegacy txn = 
TransactionLegacy.open(TransactionLegacy.USAGE_DB);
+        PreparedStatement pstmt = null;
+        try {
+            txn.start();
+            pstmt = txn.prepareAutoCloseStatement(UPDATE_DELETED);
+            pstmt.setString(1, 
DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), usage.getDeleted()));
+            pstmt.setLong(2, usage.getAccountId());
+            pstmt.setLong(3, usage.getId());
+            pstmt.setLong(4, usage.getVmId());
+            pstmt.setString(5, 
DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), usage.getCreated()));
+            pstmt.executeUpdate();
+            txn.commit();
+        } catch (Exception e) {
+            txn.rollback();
+            s_logger.warn("Error updating UsageSnapshotOnPrimaryVO", e);
+        } finally {
+            txn.close();
+        }
+    }
+
+    @Override
+    public List<UsageSnapshotOnPrimaryVO> getUsageRecords(Long accountId, Long 
domainId, Date startDate, Date endDate) {
+        List<UsageSnapshotOnPrimaryVO> usageRecords = new 
ArrayList<UsageSnapshotOnPrimaryVO>();
+
+        String sql = GET_USAGE_RECORDS_BY_ACCOUNT;
+        TransactionLegacy txn = 
TransactionLegacy.open(TransactionLegacy.USAGE_DB);
+        PreparedStatement pstmt = null;
+
+        try {
+            int i = 1;
+            pstmt = txn.prepareAutoCloseStatement(sql);
+            pstmt.setLong(i++, accountId);
+            pstmt.setString(i++, 
DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), endDate));
+            pstmt.setString(i++, 
DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), startDate));
+            pstmt.setString(i++, 
DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), endDate));
+            s_logger.debug("GET_USAGE_RECORDS_BY_ACCOUNT " + pstmt);
+            ResultSet rs = pstmt.executeQuery();
+            while (rs.next()) {
+                //id, zone_id, account_id, domain_iVMSnapshotVOd, vm_id, 
disk_offering_id, size, created, deleted
+                Long vId = Long.valueOf(rs.getLong(1));
+                Long zoneId = Long.valueOf(rs.getLong(2));
+                Long acctId = Long.valueOf(rs.getLong(3));
+                Long dId = Long.valueOf(rs.getLong(4));
+                Long vmId = Long.valueOf(rs.getLong(5));
+                String name = String.valueOf(rs.getString(6));
+                Integer type = Integer.valueOf(rs.getInt(7));
+                Long physicalSize = Long.valueOf(rs.getLong(8));
+                Long virtaulSize = Long.valueOf(rs.getLong(9));
+                Date createdDate = null;
+                Date deleteDate = null;
+                String createdTS = rs.getString(10);
+                String deleted = rs.getString(11);
+
+                if (createdTS != null) {
+                    createdDate = DateUtil.parseDateString(s_gmtTimeZone, 
createdTS);
+                }
+                if (deleted != null) {
+                    deleteDate = DateUtil.parseDateString(s_gmtTimeZone, 
deleted);
+                }
+                usageRecords.add(new UsageSnapshotOnPrimaryVO(vId, zoneId, 
acctId, dId, vmId, name, type, virtaulSize, physicalSize, createdDate, 
deleteDate));
+            }
+        } catch (Exception e) {
+            txn.rollback();
+            s_logger.warn("Error getting usage records", e);
+        } finally {
+            txn.close();
+        }
+
+        return usageRecords;
+    }
+
+}
diff --git 
a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java
 
b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java
index b7bc447..601959b 100644
--- 
a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java
+++ 
b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java
@@ -49,6 +49,8 @@ import 
org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
 import org.apache.log4j.Logger;
 
 import com.cloud.storage.CreateSnapshotPayload;
+import com.cloud.event.EventTypes;
+import com.cloud.event.UsageEventUtils;
 import com.cloud.storage.DataStoreRole;
 import com.cloud.storage.Snapshot;
 import com.cloud.storage.SnapshotVO;
@@ -216,6 +218,8 @@ public class SnapshotServiceImpl implements SnapshotService 
{
 
         try {
             result = future.get();
+            
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_ON_PRIMARY, 
snap.getAccountId(), snap.getDataCenterId(), snap.getId(),
+                    snap.getName(), null, null, snapshotOnPrimary.getSize(), 
snapshotOnPrimary.getSize(), snap.getClass().getName(), snap.getUuid());
             return result;
         } catch (InterruptedException e) {
             s_logger.debug("Failed to create snapshot", e);
diff --git 
a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/StorageSystemSnapshotStrategy.java
 
b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/StorageSystemSnapshotStrategy.java
index 185cf56..7aa5388 100644
--- 
a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/StorageSystemSnapshotStrategy.java
+++ 
b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/StorageSystemSnapshotStrategy.java
@@ -19,6 +19,9 @@ package org.apache.cloudstack.storage.snapshot;
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.api.to.DiskTO;
 import com.cloud.dc.dao.ClusterDao;
+import com.cloud.event.ActionEvent;
+import com.cloud.event.EventTypes;
+import com.cloud.event.UsageEventUtils;
 import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.host.HostVO;
 import com.cloud.host.dao.HostDao;
@@ -147,6 +150,7 @@ public class StorageSystemSnapshotStrategy extends 
SnapshotStrategyBase {
      * @return true if snapshot is removed, false otherwise
      */
 
+    @ActionEvent(eventType = EventTypes.EVENT_SNAPSHOT_OFF_PRIMARY, 
eventDescription = "deleting snapshot", async = true)
     private boolean cleanupSnapshotOnPrimaryStore(long snapshotId) {
 
         SnapshotObject snapshotObj = 
(SnapshotObject)snapshotDataFactory.getSnapshot(snapshotId, 
DataStoreRole.Primary);
@@ -176,6 +180,8 @@ public class StorageSystemSnapshotStrategy extends 
SnapshotStrategyBase {
             snapshotSvr.deleteSnapshot(snapshotObj);
 
             snapshotObj.processEvent(Snapshot.Event.OperationSucceeded);
+            
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_OFF_PRIMARY, 
snapshotObj.getAccountId(), snapshotObj.getDataCenterId(), snapshotId,
+                    snapshotObj.getName(), null, null, 0L, 
snapshotObj.getClass().getName(), snapshotObj.getUuid());
         }
         catch (Exception e) {
             s_logger.debug("Failed to delete snapshot: ", e);
diff --git 
a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java
 
b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java
index a673a462..837b201 100644
--- 
a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java
+++ 
b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java
@@ -42,6 +42,8 @@ import 
org.apache.cloudstack.storage.datastore.PrimaryDataStoreImpl;
 import org.apache.cloudstack.storage.to.SnapshotObjectTO;
 import org.apache.cloudstack.utils.identity.ManagementServerNode;
 
+import com.cloud.event.EventTypes;
+import com.cloud.event.UsageEventUtils;
 import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.hypervisor.Hypervisor;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
@@ -97,7 +99,6 @@ public class XenserverSnapshotStrategy extends 
SnapshotStrategyBase {
         SnapshotInfo parentSnapshot = snapshot.getParent();
 
         if (parentSnapshot != null && 
snapshot.getPath().equalsIgnoreCase(parentSnapshot.getPath())) {
-            s_logger.debug("backup an empty snapshot");
             // don't need to backup this snapshot
             SnapshotDataStoreVO parentSnapshotOnBackupStore = 
snapshotStoreDao.findBySnapshot(parentSnapshot.getId(), DataStoreRole.Image);
             if (parentSnapshotOnBackupStore != null && 
parentSnapshotOnBackupStore.getState() == State.Ready) {
@@ -254,7 +255,6 @@ public class XenserverSnapshotStrategy extends 
SnapshotStrategyBase {
         }
 
         if (snapshotVO.getState() == Snapshot.State.CreatedOnPrimary) {
-            s_logger.debug("delete snapshot on primary storage:");
             snapshotVO.setState(Snapshot.State.Destroyed);
             snapshotDao.update(snapshotId, snapshotVO);
             return true;
@@ -428,6 +428,8 @@ public class XenserverSnapshotStrategy extends 
SnapshotStrategyBase {
                                 SnapshotDataStoreVO snapshotDataStoreVO = 
snapshotStoreDao.findByStoreSnapshot(primaryStore.getRole(), 
primaryStore.getId(), parentSnapshotId);
                                 if (snapshotDataStoreVO != null) {
                                     parentSnapshotId = 
snapshotDataStoreVO.getParentSnapshotId();
+                                    
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_OFF_PRIMARY, 
parent.getAccountId(), parent.getDataCenterId(), parent.getId(),
+                                            parent.getName(), null, null, 0L, 
0L, parent.getClass().getName(), parent.getUuid());
                                     
snapshotStoreDao.remove(snapshotDataStoreVO.getId());
                                 } else {
                                     parentSnapshotId = null;
diff --git 
a/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java
 
b/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java
index 71a5e10..ebe8b27 100644
--- 
a/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java
+++ 
b/engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java
@@ -119,6 +119,14 @@ public class DefaultVMSnapshotStrategy extends ManagerBase 
implements VMSnapshot
 
             List<VolumeObjectTO> volumeTOs = 
vmSnapshotHelper.getVolumeTOList(userVm.getId());
 
+            long prev_chain_size = 0;
+            long virtual_size=0;
+            for (VolumeObjectTO volume : volumeTOs) {
+                virtual_size += volume.getSize();
+                VolumeVO volumeVO = volumeDao.findById(volume.getId());
+                prev_chain_size += volumeVO.getVmSnapshotChainSize() == null ? 
0 : volumeVO.getVmSnapshotChainSize();
+            }
+
             VMSnapshotTO current = null;
             VMSnapshotVO currentSnapshot = 
vmSnapshotDao.findCurrentSnapshotByVmId(userVm.getId());
             if (currentSnapshot != null)
@@ -150,10 +158,12 @@ public class DefaultVMSnapshotStrategy extends 
ManagerBase implements VMSnapshot
                 processAnswer(vmSnapshotVO, userVm, answer, hostId);
                 s_logger.debug("Create vm snapshot " + vmSnapshot.getName() + 
" succeeded for vm: " + userVm.getInstanceName());
                 result = true;
-
+                long new_chain_size=0;
                 for (VolumeObjectTO volumeTo : answer.getVolumeTOs()) {
                     publishUsageEvent(EventTypes.EVENT_VM_SNAPSHOT_CREATE, 
vmSnapshot, userVm, volumeTo);
+                    new_chain_size += volumeTo.getSize();
                 }
+                publishUsageEvent(EventTypes.EVENT_VM_SNAPSHOT_ON_PRIMARY, 
vmSnapshot, userVm, new_chain_size - prev_chain_size, virtual_size);
                 return vmSnapshot;
             } else {
                 String errMsg = "Creating VM snapshot: " + 
vmSnapshot.getName() + " failed";
@@ -208,9 +218,12 @@ public class DefaultVMSnapshotStrategy extends ManagerBase 
implements VMSnapshot
             if (answer != null && answer.getResult()) {
                 DeleteVMSnapshotAnswer deleteVMSnapshotAnswer = 
(DeleteVMSnapshotAnswer)answer;
                 processAnswer(vmSnapshotVO, userVm, answer, hostId);
+                long full_chain_size=0;
                 for (VolumeObjectTO volumeTo : 
deleteVMSnapshotAnswer.getVolumeTOs()) {
                     publishUsageEvent(EventTypes.EVENT_VM_SNAPSHOT_DELETE, 
vmSnapshot, userVm, volumeTo);
+                    full_chain_size += volumeTo.getSize();
                 }
+                publishUsageEvent(EventTypes.EVENT_VM_SNAPSHOT_OFF_PRIMARY, 
vmSnapshot, userVm, full_chain_size, 0L);
                 return true;
             } else {
                 String errMsg = (answer == null) ? null : answer.getDetails();
@@ -325,7 +338,16 @@ public class DefaultVMSnapshotStrategy extends ManagerBase 
implements VMSnapshot
             }
         }
         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());
+    }
+
+    private void publishUsageEvent(String type, VMSnapshot vmSnapshot, UserVm 
userVm, Long vmSnapSize, Long virtualSize) {
+        try {
+            UsageEventUtils.publishUsageEvent(type, vmSnapshot.getAccountId(), 
userVm.getDataCenterId(), userVm.getId(), vmSnapshot.getName(), 0L, 0L, 
vmSnapSize, virtualSize,
+                    VMSnapshot.class.getName(), vmSnapshot.getUuid());
+        } catch (Exception e) {
+            s_logger.error("Failed to publis usage event " + type, e);
+        }
     }
 
     @Override
diff --git 
a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java
 
b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java
index c25c1ad..158ee18 100644
--- 
a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java
+++ 
b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java
@@ -209,6 +209,7 @@ public class DefaultEndPointSelector implements 
EndPointSelector {
 
     @Override
     public EndPoint select(DataObject srcData, DataObject destData, 
StorageAction action) {
+        s_logger.error("IR24 select BACKUPSNAPSHOT from primary to secondary " 
+ srcData.getId() + " dest=" + destData.getId());
         if (action == StorageAction.BACKUPSNAPSHOT && 
srcData.getDataStore().getRole() == DataStoreRole.Primary) {
             SnapshotInfo srcSnapshot = (SnapshotInfo)srcData;
             VolumeInfo volumeInfo = srcSnapshot.getBaseVolume();
diff --git 
a/framework/quota/src/org/apache/cloudstack/quota/constant/QuotaTypes.java 
b/framework/quota/src/org/apache/cloudstack/quota/constant/QuotaTypes.java
index 6e1432d..97e22da 100644
--- a/framework/quota/src/org/apache/cloudstack/quota/constant/QuotaTypes.java
+++ b/framework/quota/src/org/apache/cloudstack/quota/constant/QuotaTypes.java
@@ -55,6 +55,7 @@ public class QuotaTypes extends UsageTypes {
         quotaTypeList.put(VM_DISK_BYTES_READ, new 
QuotaTypes(VM_DISK_BYTES_READ, "VM_DISK_BYTES_READ", "GB", "VM Disk usage(Bytes 
Read)"));
         quotaTypeList.put(VM_DISK_BYTES_WRITE, new 
QuotaTypes(VM_DISK_BYTES_WRITE, "VPN_USERS", "GB", "VM Disk usage(Bytes 
Write)"));
         quotaTypeList.put(VM_SNAPSHOT, new QuotaTypes(VM_SNAPSHOT, 
"VM_SNAPSHOT", "GB-Month", "VM Snapshot storage usage"));
+        quotaTypeList.put(VM_SNAPSHOT_ON_PRIMARY, new 
QuotaTypes(VM_SNAPSHOT_ON_PRIMARY, "VM_SNAPSHOT_ON_PRIMARY", "GB-Month", "VM 
Snapshot primary storage usage"));
         quotaTypeList.put(CPU_CLOCK_RATE, new QuotaTypes(CPU_CLOCK_RATE, 
"CPU_CLOCK_RATE", "Compute-Month", "Quota tariff for using 1 CPU of clock rate 
100MHz"));
         quotaTypeList.put(CPU_NUMBER, new QuotaTypes(CPU_NUMBER, "CPU_NUMBER", 
"Compute-Month", "Quota tariff for running VM that has 1vCPU"));
         quotaTypeList.put(MEMORY, new QuotaTypes(MEMORY, "MEMORY", 
"Compute-Month", "Quota tariff for using 1MB of RAM"));
diff --git a/usage/src/com/cloud/usage/UsageManagerImpl.java 
b/usage/src/com/cloud/usage/UsageManagerImpl.java
index 4a60b24..d709102 100644
--- a/usage/src/com/cloud/usage/UsageManagerImpl.java
+++ b/usage/src/com/cloud/usage/UsageManagerImpl.java
@@ -57,6 +57,7 @@ import com.cloud.usage.dao.UsageNetworkDao;
 import com.cloud.usage.dao.UsageNetworkOfferingDao;
 import com.cloud.usage.dao.UsagePortForwardingRuleDao;
 import com.cloud.usage.dao.UsageSecurityGroupDao;
+import com.cloud.usage.dao.UsageVMSnapshotOnPrimaryDao;
 import com.cloud.usage.dao.UsageStorageDao;
 import com.cloud.usage.dao.UsageVMInstanceDao;
 import com.cloud.usage.dao.UsageVMSnapshotDao;
@@ -75,6 +76,7 @@ import com.cloud.usage.parser.VMSnapshotUsageParser;
 import com.cloud.usage.parser.VPNUserUsageParser;
 import com.cloud.usage.parser.VmDiskUsageParser;
 import com.cloud.usage.parser.VolumeUsageParser;
+import com.cloud.usage.parser.VMSanpshotOnPrimaryParser;
 import com.cloud.user.Account;
 import com.cloud.user.AccountVO;
 import com.cloud.user.UserStatisticsVO;
@@ -87,6 +89,7 @@ import com.cloud.utils.concurrency.NamedThreadFactory;
 import com.cloud.utils.db.DB;
 import com.cloud.utils.db.Filter;
 import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.db.QueryBuilder;
 import com.cloud.utils.db.SearchCriteria;
 import com.cloud.utils.db.TransactionLegacy;
 
@@ -145,6 +148,8 @@ public class UsageManagerImpl extends ManagerBase 
implements UsageManager, Runna
     @Inject
     private UsageVMSnapshotDao _usageVMSnapshotDao;
     @Inject
+    private UsageVMSnapshotOnPrimaryDao _usageSnapshotOnPrimaryDao;
+    @Inject
     private QuotaManager _quotaManager;
     @Inject
     private QuotaAlertManager _alertManager;
@@ -939,6 +944,18 @@ public class UsageManagerImpl extends ManagerBase 
implements UsageManager, Runna
                 s_logger.debug("VM Snapshot usage successfully parsed? " + 
parsed + " (for account: " + account.getAccountName() + ", id: " + 
account.getId() + ")");
             }
         }
+        parsed = VMSnapshotUsageParser.parse(account, currentStartDate, 
currentEndDate);
+        if (s_logger.isDebugEnabled()) {
+            if (!parsed) {
+                s_logger.debug("VM Snapshot usage successfully parsed? " + 
parsed + " (for account: " + account.getAccountName() + ", id: " + 
account.getId() + ")");
+            }
+        }
+        parsed = VMSanpshotOnPrimaryParser.parse(account, currentStartDate, 
currentEndDate);
+        if (s_logger.isDebugEnabled()) {
+            if (!parsed) {
+                s_logger.debug("VM Snapshot on primary usage successfully 
parsed? " + parsed + " (for account: " + account.getAccountName() + ", id: " + 
account.getId() + ")");
+            }
+        }
         return parsed;
     }
 
@@ -968,6 +985,8 @@ public class UsageManagerImpl extends ManagerBase 
implements UsageManager, Runna
             createSecurityGroupEvent(event);
         } else if (isVmSnapshotEvent(eventType)) {
             createVMSnapshotEvent(event);
+        } else if (isVmSnapshotOnPrimaryEvent(eventType)) {
+            createVmSnapshotOnPrimaryEvent(event);
         }
     }
 
@@ -1043,6 +1062,12 @@ public class UsageManagerImpl extends ManagerBase 
implements UsageManager, Runna
         return (eventType.equals(EventTypes.EVENT_VM_SNAPSHOT_CREATE) || 
eventType.equals(EventTypes.EVENT_VM_SNAPSHOT_DELETE));
     }
 
+    private boolean isVmSnapshotOnPrimaryEvent(String eventType) {
+        if (eventType == null)
+            return false;
+        return (eventType.equals(EventTypes.EVENT_VM_SNAPSHOT_ON_PRIMARY) || 
eventType.equals(EventTypes.EVENT_VM_SNAPSHOT_OFF_PRIMARY));
+    }
+
     private void createVMHelperEvent(UsageEventVO event) {
 
         // One record for handling VM.START and VM.STOP
@@ -1806,6 +1831,43 @@ public class UsageManagerImpl extends ManagerBase 
implements UsageManager, Runna
         _usageVMSnapshotDao.persist(vsVO);
     }
 
+    private void createVmSnapshotOnPrimaryEvent(UsageEventVO event) {
+        Long vmId = event.getResourceId();
+        String name = event.getResourceName();
+        if (EventTypes.EVENT_VM_SNAPSHOT_ON_PRIMARY.equals(event.getType())) {
+            Long zoneId = event.getZoneId();
+            Long accountId = event.getAccountId();
+            long physicalsize = (event.getSize() == null) ? 0 : 
event.getSize();
+            long virtualsize = (event.getVirtualSize() == null) ? 0 : 
event.getVirtualSize();
+            Date created = event.getCreateDate();
+            Account acct = 
_accountDao.findByIdIncludingRemoved(event.getAccountId());
+            Long domainId = acct.getDomainId();
+            UsageSnapshotOnPrimaryVO vsVO = new UsageSnapshotOnPrimaryVO(vmId, 
zoneId, accountId, domainId, vmId, name, 0, virtualsize, physicalsize, created, 
null);
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("createSnapshotOnPrimaryEvent 
UsageSnapshotOnPrimaryVO " + vsVO);
+            }
+            _usageSnapshotOnPrimaryDao.persist(vsVO);
+        } else if 
(EventTypes.EVENT_VM_SNAPSHOT_OFF_PRIMARY.equals(event.getType())) {
+            QueryBuilder<UsageSnapshotOnPrimaryVO> sc = 
QueryBuilder.create(UsageSnapshotOnPrimaryVO.class);
+            sc.and(sc.entity().getAccountId(), SearchCriteria.Op.EQ, 
event.getAccountId());
+            sc.and(sc.entity().getId(), SearchCriteria.Op.EQ, vmId);
+            sc.and(sc.entity().getName(), SearchCriteria.Op.EQ, name);
+            sc.and(sc.entity().getDeleted(), SearchCriteria.Op.NULL);
+            List<UsageSnapshotOnPrimaryVO> vmsnaps = sc.list();
+            if (vmsnaps.size() > 1) {
+                s_logger.warn("More that one usage entry for vm snapshot: " + 
name + " for vm id:" + vmId + " assigned to account: " + event.getAccountId()
+                        + "; marking them all as deleted...");
+            }
+            for (UsageSnapshotOnPrimaryVO vmsnap : vmsnaps) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("deleting vm snapshot name: " + 
vmsnap.getName() + " from account: " + vmsnap.getAccountId());
+                }
+                vmsnap.setDeleted(event.getCreateDate()); // there really 
shouldn't be more than one
+                _usageSnapshotOnPrimaryDao.updateDeleted(vmsnap);
+            }
+        }
+    }
+
     private class Heartbeat extends ManagedContextRunnable {
         @Override
         protected void runInContext() {
diff --git a/usage/src/com/cloud/usage/parser/VMSanpshotOnPrimaryParser.java 
b/usage/src/com/cloud/usage/parser/VMSanpshotOnPrimaryParser.java
new file mode 100644
index 0000000..8519295
--- /dev/null
+++ b/usage/src/com/cloud/usage/parser/VMSanpshotOnPrimaryParser.java
@@ -0,0 +1,129 @@
+// 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
+// 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.usage.parser;
+
+import java.text.DecimalFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import org.apache.cloudstack.usage.UsageTypes;
+
+import com.cloud.usage.UsageSnapshotOnPrimaryVO;
+import com.cloud.usage.UsageVO;
+import com.cloud.usage.dao.UsageDao;
+import com.cloud.usage.dao.UsageVMSnapshotOnPrimaryDao;
+import com.cloud.user.AccountVO;
+
+@Component
+public class VMSanpshotOnPrimaryParser {
+    public static final Logger s_logger = 
Logger.getLogger(VMSanpshotOnPrimaryParser.class.getName());
+
+    private static UsageDao s_usageDao;
+    private static UsageVMSnapshotOnPrimaryDao s_usageSnapshotOnPrimaryDao;
+
+    @Inject
+    private UsageDao _usageDao;
+    @Inject
+    private UsageVMSnapshotOnPrimaryDao _usageSnapshotOnPrimaryDao;
+
+    @PostConstruct
+    void init() {
+        s_usageDao = _usageDao;
+        s_usageSnapshotOnPrimaryDao = _usageSnapshotOnPrimaryDao;
+    }
+
+    public static boolean parse(AccountVO account, Date startDate, Date 
endDate) {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Parsing all VmSnapshot on primary usage events for 
account: " + account.getId());
+        }
+        if ((endDate == null) || endDate.after(new Date())) {
+            endDate = new Date();
+        }
+
+        List<UsageSnapshotOnPrimaryVO> usageUsageVMSnapshots = 
s_usageSnapshotOnPrimaryDao.getUsageRecords(account.getId(), 
account.getDomainId(), startDate, endDate);
+
+        if (usageUsageVMSnapshots.isEmpty()) {
+            s_logger.debug("No VM snapshot on primary usage events for this 
period");
+            return true;
+        }
+
+        Map<String, UsageSnapshotOnPrimaryVO> unprocessedUsage = new 
HashMap<String, UsageSnapshotOnPrimaryVO>();
+        for (UsageSnapshotOnPrimaryVO usageRec : usageUsageVMSnapshots) {
+            s_logger.debug("usageRec for VMsnap on primary " + 
usageRec.toString());
+            String key = usageRec.getName();
+            if (usageRec.getPhysicalSize() == 0) {
+                usageRec.setDeleted(new Date());
+                s_usageSnapshotOnPrimaryDao.updateDeleted(usageRec);
+            } else {
+                unprocessedUsage.put(key, usageRec);
+            }
+        }
+
+        for (String key : unprocessedUsage.keySet()) {
+            UsageSnapshotOnPrimaryVO usageRec = unprocessedUsage.get(key);
+            Date created = usageRec.getCreated();
+            if (created.before(startDate)) {
+                created = startDate;
+            }
+            Date endDateEffective = endDate;
+            if (usageRec.getDeleted() != null && 
usageRec.getDeleted().before(endDate)){
+                endDateEffective = usageRec.getDeleted();
+                s_logger.debug("Remoevd vm snapshot found endDateEffective " + 
endDateEffective + " period end data " + endDate);
+            }
+            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());
+        }
+
+        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) {
+        // Our smallest increment is hourly for now
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Total running time " + runningTime + "ms");
+        }
+
+        float usage = runningTime / 1000f / 60f / 60f;
+
+        DecimalFormat dFormat = new DecimalFormat("#.######");
+        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
+                    + ", for account: " + account.getId());
+        }
+
+        // Create the usage record
+        String usageDesc = "VMSnapshot 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);
+        s_usageDao.persist(usageRecord);
+    }
+
+}

-- 
To stop receiving notification emails like this one, please contact
['"[email protected]" <[email protected]>'].

Reply via email to