You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ni...@apache.org on 2014/03/18 22:00:42 UTC

git commit: updated refs/heads/master to 7442b56

Repository: cloudstack
Updated Branches:
  refs/heads/master 0288a8704 -> 7442b56fa


CLOUDSTACK-6247: Usage Events - hide them when display flag is off in the context of "Ability to have better control over first class objects in CS" feature
And when the flag is updated on the resource accordingly generate usage events again.
Also when display flag is false in deployvm cmd it should be false for the volumes associated with the vm as well


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/7442b56f
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/7442b56f
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/7442b56f

Branch: refs/heads/master
Commit: 7442b56fa8c54fa4ffe920e139d41e1603355907
Parents: 0288a87
Author: Nitin Mehta <ni...@citrix.com>
Authored: Mon Mar 17 18:50:06 2014 -0700
Committer: Nitin Mehta <ni...@citrix.com>
Committed: Tue Mar 18 14:00:25 2014 -0700

----------------------------------------------------------------------
 api/src/com/cloud/storage/VolumeApiService.java |   2 +
 .../service/VolumeOrchestrationService.java     |   1 +
 .../src/com/cloud/event/UsageEventUtils.java    |  30 +++++-
 .../orchestration/VolumeOrchestrator.java       |  27 +++--
 .../com/cloud/storage/VolumeApiServiceImpl.java |  75 +++++++++++---
 server/src/com/cloud/vm/UserVmManager.java      |   2 +
 server/src/com/cloud/vm/UserVmManagerImpl.java  | 101 ++++++++++++++-----
 .../src/com/cloud/vm/UserVmStateListener.java   |  31 +++---
 8 files changed, 200 insertions(+), 69 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7442b56f/api/src/com/cloud/storage/VolumeApiService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/storage/VolumeApiService.java b/api/src/com/cloud/storage/VolumeApiService.java
index beaa290..5487a4b 100644
--- a/api/src/com/cloud/storage/VolumeApiService.java
+++ b/api/src/com/cloud/storage/VolumeApiService.java
@@ -96,4 +96,6 @@ public interface VolumeApiService {
     String extractVolume(ExtractVolumeCmd cmd);
 
     boolean isDisplayResourceEnabled(Long id);
+
+    void updateDisplay(Volume volume, Boolean displayVolume);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7442b56f/engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java b/engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java
index 66b5ff5..095d954 100644
--- a/engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java
+++ b/engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java
@@ -118,4 +118,5 @@ public interface VolumeOrchestrationService {
     StoragePool findStoragePool(DiskProfile dskCh, DataCenter dc, Pod pod, Long clusterId, Long hostId, VirtualMachine vm, Set<StoragePool> avoid);
 
     void updateVolumeDiskChain(long volumeId, String path, String chainInfo);
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7442b56f/engine/components-api/src/com/cloud/event/UsageEventUtils.java
----------------------------------------------------------------------
diff --git a/engine/components-api/src/com/cloud/event/UsageEventUtils.java b/engine/components-api/src/com/cloud/event/UsageEventUtils.java
index 4f32cb3..f1707bd 100644
--- a/engine/components-api/src/com/cloud/event/UsageEventUtils.java
+++ b/engine/components-api/src/com/cloud/event/UsageEventUtils.java
@@ -71,6 +71,15 @@ public class UsageEventUtils {
     }
 
     public static void publishUsageEvent(String usageType, long accountId, long zoneId, long resourceId, String resourceName, Long offeringId, Long templateId,
+                                         Long size, String entityType, String entityUUID, boolean displayResource) {
+        if(displayResource){
+            saveUsageEvent(usageType, accountId, zoneId, resourceId, resourceName, offeringId, templateId, size);
+        }
+        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);
         publishUsageEvent(usageType, accountId, zoneId, entityType, entityUUID);
@@ -81,6 +90,13 @@ public class UsageEventUtils {
         publishUsageEvent(usageType, accountId, zoneId, entityType, entityUUID);
     }
 
+    public static void publishUsageEvent(String usageType, long accountId, long zoneId, long resourceId, String resourceName, String entityType, String entityUUID, boolean diplayResource) {
+        if (diplayResource){
+            saveUsageEvent(usageType, accountId, zoneId, resourceId, resourceName);
+            publishUsageEvent(usageType, accountId, zoneId, entityType, entityUUID);
+        }
+    }
+
     public static void publishUsageEvent(String usageType, long accountId, long zoneId, long ipAddressId, String ipAddress, boolean isSourceNat, String guestType,
         boolean isSystem, String entityType, String entityUUID) {
         saveUsageEvent(usageType, accountId, zoneId, ipAddressId, ipAddress, isSourceNat, guestType, isSystem);
@@ -88,9 +104,12 @@ public class UsageEventUtils {
     }
 
     public static void publishUsageEvent(String usageType, long accountId, long zoneId, long resourceId, String resourceName, Long offeringId, Long templateId,
-        String resourceType, String entityType, String entityUUID) {
-        saveUsageEvent(usageType, accountId, zoneId, resourceId, resourceName, offeringId, templateId, resourceType);
+        String resourceType, String entityType, String entityUUID, boolean displayResource) {
+        if(displayResource){
+            saveUsageEvent(usageType, accountId, zoneId, resourceId, resourceName, offeringId, templateId, resourceType);
+        }
         publishUsageEvent(usageType, accountId, zoneId, entityType, entityUUID);
+
     }
 
     public static void publishUsageEvent(String usageType, long accountId, long zoneId, long vmId, long securityGroupId, String entityType, String entityUUID) {
@@ -99,9 +118,12 @@ public class UsageEventUtils {
     }
 
     public static void publishUsageEvent(String usageType, long accountId, long zoneId, long resourceId, String resourceName, Long offeringId, Long templateId,
-        String resourceType, String entityType, String entityUUID, Map<String, String> details) {
-        saveUsageEvent(usageType, accountId, zoneId, resourceId, resourceName, offeringId, templateId, resourceType, details);
+        String resourceType, String entityType, String entityUUID, Map<String, String> details, boolean displayResource) {
+        if(displayResource){
+            saveUsageEvent(usageType, accountId, zoneId, resourceId, resourceName, offeringId, templateId, resourceType, details);
+        }
         publishUsageEvent(usageType, accountId, zoneId, entityType, entityUUID);
+
     }
 
     private static void saveUsageEvent(String usageType, long accountId, long zoneId, long resourceId, String resourceName, Long offeringId, Long templateId,

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7442b56f/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
----------------------------------------------------------------------
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
index 6471f76..a74d79c 100644
--- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
+++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
@@ -30,6 +30,8 @@ import java.util.concurrent.ExecutionException;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.dao.UserVmDao;
 import org.apache.log4j.Logger;
 
 import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
@@ -149,6 +151,8 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
     HostDao _hostDao;
     @Inject
     SnapshotService _snapshotSrv;
+    @Inject
+    protected UserVmDao _userVmDao;
 
     private final StateMachine2<Volume.State, Volume.Event, Volume> _volStateMachine;
     protected List<StoragePoolAllocator> _storagePoolAllocators;
@@ -592,6 +596,11 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
         if (template.getFormat() == ImageFormat.ISO) {
             vol.setIsoId(template.getId());
         }
+        // display flag matters only for the User vms
+        if (vm.getType() == VirtualMachine.Type.User) {
+            UserVmVO userVm = _userVmDao.findById(vm.getId());
+            vol.setDisplayVolume(userVm.isDisplayVm());
+        }
 
         vol.setFormat(getSupportedImageFormatForCluster(vm.getHypervisorType()));
         vol = _volsDao.persist(vol);
@@ -599,10 +608,10 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
         // Save usage event and update resource count for user vm volumes
         if (vm.getType() == VirtualMachine.Type.User) {
             UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), offering.getId(), null, size,
-                    Volume.class.getName(), vol.getUuid());
+                    Volume.class.getName(), vol.getUuid(), vol.isDisplayVolume());
 
-            _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume);
-            _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.primary_storage, new Long(vol.getSize()));
+            _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume, vol.isDisplayVolume());
+            _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.primary_storage, vol.isDisplayVolume(), new Long(vol.getSize()));
         }
         return toDiskProfile(vol, offering);
     }
@@ -642,6 +651,12 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
             vol.setDeviceId(1l);
         }
 
+        if (vm.getType() == VirtualMachine.Type.User) {
+           UserVmVO userVm = _userVmDao.findById(vm.getId());
+           vol.setDisplayVolume(userVm.isDisplayVm());
+        }
+
+
         vol = _volsDao.persist(vol);
 
         // Create event and update resource count for volumes if vm is a user vm
@@ -652,10 +667,10 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
             offeringId = offering.getId();
 
             UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), offeringId, null, size,
-                    Volume.class.getName(), vol.getUuid());
+                    Volume.class.getName(), vol.getUuid(), vol.isDisplayVolume());
 
-            _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume);
-            _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.primary_storage, new Long(vol.getSize()));
+            _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume, vol.isDisplayVolume());
+            _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.primary_storage, vol.isDisplayVolume(), new Long(vol.getSize()));
         }
         return toDiskProfile(vol, offering);
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7442b56f/server/src/com/cloud/storage/VolumeApiServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
index d820d02..5ffa99b 100644
--- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
@@ -591,10 +591,10 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
         }
 
         volume = _volsDao.persist(volume);
-        if (cmd.getSnapshotId() == null) {
+        if (cmd.getSnapshotId() == null && displayVolume) {
             // for volume created from snapshot, create usage event after volume creation
-                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
-                            diskOfferingId, null, size, Volume.class.getName(), volume.getUuid());
+            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
+                    diskOfferingId, null, size, Volume.class.getName(), volume.getUuid(), displayVolume);
         }
 
         CallContext.current().setEventDetails("Volume Id: " + volume.getId());
@@ -677,11 +677,11 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
         // sync old snapshots to region store if necessary
 
         createdVolume = _volumeMgr.createVolumeFromSnapshot(volume, snapshot, vm);
-
+        VolumeVO volumeVo = _volsDao.findById(createdVolume.getId());
         UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, createdVolume.getAccountId(), createdVolume.getDataCenterId(), createdVolume.getId(),
-                createdVolume.getName(), createdVolume.getDiskOfferingId(), null, createdVolume.getSize(), Volume.class.getName(), createdVolume.getUuid());
+                createdVolume.getName(), createdVolume.getDiskOfferingId(), null, createdVolume.getSize(), Volume.class.getName(), createdVolume.getUuid(), volumeVo.isDisplayVolume());
 
-        return _volsDao.findById(createdVolume.getId());
+        return volumeVo;
     }
 
     @Override
@@ -972,7 +972,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
 
                     // Log usage event for volumes belonging user VM's only
                     UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
-                            Volume.class.getName(), volume.getUuid());
+                            Volume.class.getName(), volume.getUuid(), volume.isDisplayVolume());
                 }
             }
             // Mark volume as removed if volume has not been created on primary or secondary
@@ -1225,14 +1225,13 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
 
         VolumeVO volume = _volumeDao.findById(volumeId);
 
+        if(volume == null)
+            throw new InvalidParameterValueException("The volume id doesn't exist");
+
         if (path != null) {
             volume.setPath(path);
         }
 
-        if (displayVolume != null) {
-            volume.setDisplayVolume(displayVolume);
-        }
-
         if(chainInfo != null){
             volume.setChainInfo(chainInfo);
         }
@@ -1258,17 +1257,61 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
             volume.setUuid(customId);
         }
 
-        if (displayVolume != null && displayVolume != volume.isDisplayVolume()) { // No need to check permissions since only Admin allowed to call this API.
-            volume.setDisplayVolume(displayVolume);
-            _resourceLimitMgr.changeResourceCount(entityOwnerId, ResourceType.volume, displayVolume);
-            _resourceLimitMgr.changeResourceCount(entityOwnerId, ResourceType.primary_storage, displayVolume, new Long(volume.getSize()));
-        }
+        updateDisplay(volume, displayVolume);
 
         _volumeDao.update(volumeId, volume);
 
         return volume;
     }
 
+
+    @Override
+    public void updateDisplay(Volume volume, Boolean displayVolume){
+        // 1. Resource limit changes
+        updateResourceCount(volume, displayVolume);
+
+        // 2. generate usage event if not in destroyed state
+        saveUsageEvent(volume, displayVolume);
+
+        // 3. Set the flag
+        if (displayVolume != null && displayVolume != volume.isDisplayVolume()){
+            // FIXME - Confused - typecast for now.
+            ((VolumeVO)volume).setDisplayVolume(displayVolume);
+            _volumeDao.update(volume.getId(), (VolumeVO)volume);
+        }
+
+    }
+
+    private void updateResourceCount(Volume volume, Boolean displayVolume){
+        // Update only when the flag has changed.
+        if (displayVolume != null && displayVolume != volume.isDisplayVolume()){
+            _resourceLimitMgr.changeResourceCount(volume.getAccountId(), ResourceType.volume, displayVolume);
+            _resourceLimitMgr.changeResourceCount(volume.getAccountId(), ResourceType.primary_storage, displayVolume, new Long(volume.getSize()));
+        }
+    }
+
+    private void saveUsageEvent(Volume volume, Boolean displayVolume){
+
+        // Update only when the flag has changed  &&  only when volume in a non-destroyed state.
+        if ((displayVolume != null && displayVolume != volume.isDisplayVolume()) && !isVolumeDestroyed(volume)){
+            if (displayVolume){
+                // flag turned 1 equivalent to freshly created volume
+                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
+                        volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(), volume.getUuid());
+            }else {
+                // flag turned 0 equivalent to deleting a volume
+                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
+                        Volume.class.getName(), volume.getUuid());
+            }
+        }
+    }
+
+    private boolean isVolumeDestroyed(Volume volume){
+        if(volume.getState() == Volume.State.Destroy || volume.getState() == Volume.State.Expunging && volume.getState() == Volume.State.Expunged)
+            return true;
+        return false;
+    }
+
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_VOLUME_DETACH, eventDescription = "detaching volume", async = true)
     public Volume detachVolumeFromVM(DetachVolumeCmd cmmd) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7442b56f/server/src/com/cloud/vm/UserVmManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/UserVmManager.java b/server/src/com/cloud/vm/UserVmManager.java
index afe1002..61e28d8 100755
--- a/server/src/com/cloud/vm/UserVmManager.java
+++ b/server/src/com/cloud/vm/UserVmManager.java
@@ -109,4 +109,6 @@ public interface UserVmManager extends UserVmService {
     public void saveCustomOfferingDetails(long vmId, ServiceOffering serviceOffering);
 
     public void removeCustomOfferingDetails(long vmId);
+
+    void generateUsageEvent(VirtualMachine vm, boolean isDisplay, String eventType);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7442b56f/server/src/com/cloud/vm/UserVmManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java
index f9063cf..3550185 100755
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -38,6 +38,7 @@ import javax.naming.ConfigurationException;
 import org.apache.commons.codec.binary.Base64;
 import org.apache.log4j.Logger;
 
+import com.cloud.storage.VolumeApiService;
 import org.apache.cloudstack.acl.ControlledEntity.ACLType;
 import org.apache.cloudstack.acl.SecurityChecker.AccessType;
 import org.apache.cloudstack.affinity.AffinityGroupService;
@@ -445,6 +446,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
     UUIDManager _uuidMgr;
     @Inject
     DeploymentPlanningManager _planningMgr;
+    @Inject
+    VolumeApiService _volumeService;
 
     protected ScheduledExecutorService _executor = null;
     protected int _expungeInterval;
@@ -828,9 +831,10 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
         }
 
         // Generate usage event for VM upgrade
-        generateUsageEvent(newServiceOffering, cmd.getDetails(), _vmDao.findById(vmId), EventTypes.EVENT_VM_UPGRADE);
+        UserVmVO userVm = _vmDao.findById(vmId);
+        generateUsageEvent( userVm, userVm.isDisplayVm(), EventTypes.EVENT_VM_UPGRADE);
 
-        return _vmDao.findById(vmInstance.getId());
+        return userVm;
     }
 
     @Override
@@ -1212,11 +1216,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
             UserVmVO vmInstance = _vmDao.findById(vmId);
             if (vmInstance.getState().equals(State.Stopped)) {
                 // Generate usage event for VM upgrade
-                generateUsageEvent(_offeringDao.findById(newServiceOfferingId), cmd.getDetails(), _vmDao.findById(vmId), EventTypes.EVENT_VM_UPGRADE);
+                generateUsageEvent(vmInstance, vmInstance.isDisplayVm(), EventTypes.EVENT_VM_UPGRADE);
             }
             if (vmInstance.getState().equals(State.Running)) {
                 // Generate usage event for Dynamic scaling of VM
-                generateUsageEvent(_offeringDao.findById(newServiceOfferingId), cmd.getDetails(), _vmDao.findById(vmId), EventTypes.EVENT_VM_UPGRADE);
+                generateUsageEvent( vmInstance, vmInstance.isDisplayVm(), EventTypes.EVENT_VM_DYNAMIC_SCALE);
             }
             return vmInstance;
         } else {
@@ -1557,8 +1561,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
                         offeringId = offering.getId();
                     }
                 }
-                        UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
-                                offeringId, templateId, volume.getSize(), Volume.class.getName(), volume.getUuid());
+                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
+                        offeringId, templateId, volume.getSize(), Volume.class.getName(), volume.getUuid(), volume.isDisplayVolume());
             }
         }
 
@@ -1610,7 +1614,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
 
         _itMgr.registerGuru(VirtualMachine.Type.User, this);
 
-        VirtualMachine.State.getStateMachine().registerListener(new UserVmStateListener(_usageEventDao, _networkDao, _nicDao, _offeringDao));
+        VirtualMachine.State.getStateMachine().registerListener(new UserVmStateListener(_usageEventDao, _networkDao, _nicDao, _offeringDao, _vmDao, this));
 
         String value = _configDao.getValue(Config.SetVmInternalNameUsingDisplayName.key());
         _instanceNameFlag = (value == null) ? false : Boolean.parseBoolean(value);
@@ -1829,6 +1833,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
         String userData = cmd.getUserData();
         Boolean isDynamicallyScalable = cmd.isDynamicallyScalable();
         String hostName = cmd.getHostName();
+        Account caller = CallContext.current().getCallingAccount();
 
         // Input validation and permission checks
         UserVmVO vmInstance = _vmDao.findById(id.longValue());
@@ -1840,15 +1845,52 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
 
         //If the flag is specified and is changed
         if (isDisplayVm != null && isDisplayVm != vmInstance.isDisplayVm()) {
+
+            //update vm
+            vmInstance.setDisplayVm(isDisplayVm);
+
+            // Resource limit changes
             ServiceOffering offering = _serviceOfferingDao.findByIdIncludingRemoved(vmInstance.getServiceOfferingId());
             _resourceLimitMgr.changeResourceCount(vmInstance.getAccountId(), ResourceType.user_vm, isDisplayVm);
             _resourceLimitMgr.changeResourceCount(vmInstance.getAccountId(), ResourceType.cpu, isDisplayVm, new Long(offering.getCpu()));
             _resourceLimitMgr.changeResourceCount(vmInstance.getAccountId(), ResourceType.memory, isDisplayVm, new Long(offering.getRamSize()));
+
+            // Usage
+            saveUsageEvent(vmInstance);
+
+            // take care of the root volume as well.
+            _volumeService.updateDisplay(_volsDao.findByInstanceAndType(id, Volume.Type.ROOT).get(0), isDisplayVm);
+
         }
 
         return updateVirtualMachine(id, displayName, group, ha, isDisplayVm, osTypeId, userData, isDynamicallyScalable, cmd.getHttpMethod(), cmd.getCustomId(), hostName);
     }
 
+    private void saveUsageEvent(UserVmVO vm) {
+
+        // If vm not destroyed
+        if( vm.getState() != State.Destroyed && vm.getState() != State.Expunging && vm.getState() != State.Error){
+
+            if(vm.isDisplayVm()){
+                //1. Allocated VM Usage Event
+                generateUsageEvent(vm, true, EventTypes.EVENT_VM_CREATE);
+                //2. Running VM Usage Event
+                if(vm.getState() == State.Running || vm.getState() == State.Stopping){
+                    generateUsageEvent(vm, true, EventTypes.EVENT_VM_START);
+                }
+
+            }else {
+                //1. Allocated VM Usage Event
+                generateUsageEvent(vm, true, EventTypes.EVENT_VM_DESTROY);
+                //2. Running VM Usage Event
+                if(vm.getState() == State.Running || vm.getState() == State.Stopping){
+                    generateUsageEvent(vm, true, EventTypes.EVENT_VM_STOP);
+                }
+            }
+        }
+
+    }
+
     @Override
     public UserVm updateVirtualMachine(long id, String displayName, String group, Boolean ha, Boolean isDisplayVmEnabled, Long osTypeId, String userData,
             Boolean isDynamicallyScalable, HTTPMethod httpMethod, String customId, String hostName) throws ResourceUnavailableException, InsufficientCapacityException {
@@ -2935,10 +2977,10 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
 
                 if (!offering.isDynamic()) {
                     UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, accountId, zone.getId(), vm.getId(), vm.getHostName(), offering.getId(), template.getId(),
-                            hypervisorType.toString(), VirtualMachine.class.getName(), vm.getUuid());
+                            hypervisorType.toString(), VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplayVm());
                 } else {
                     UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, accountId, zone.getId(), vm.getId(), vm.getHostName(), offering.getId(), template.getId(),
-                            hypervisorType.toString(), VirtualMachine.class.getName(), vm.getUuid(), customParameters);
+                            hypervisorType.toString(), VirtualMachine.class.getName(), vm.getUuid(), customParameters, vm.isDisplayVm());
                 }
 
                 //Update Resource Count for the given account
@@ -2948,13 +2990,22 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
         });
     }
 
-    private void generateUsageEvent(ServiceOfferingVO serviceOffering, Map<String, String> customParameters, UserVmVO vm, String eventType) {
+    @Override
+    public void generateUsageEvent(VirtualMachine vm, boolean isDisplay, String eventType){
+        ServiceOfferingVO serviceOffering = _offeringDao.findById(vm.getId(), vm.getServiceOfferingId());
         if (!serviceOffering.isDynamic()) {
-            UsageEventUtils.publishUsageEvent(eventType, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), vm.getHostName(), serviceOffering.getId(), vm.getTemplateId(), vm
-                    .getHypervisorType().toString(), VirtualMachine.class.getName(), vm.getUuid());
-        } else {
-            UsageEventUtils.publishUsageEvent(eventType, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), vm.getHostName(), serviceOffering.getId(), vm.getTemplateId(), vm
-                    .getHypervisorType().toString(), VirtualMachine.class.getName(), vm.getUuid(), customParameters);
+            UsageEventUtils.publishUsageEvent(eventType, vm.getAccountId(), vm.getDataCenterId(), vm.getId(),
+                    vm.getHostName(), serviceOffering.getId(), vm.getTemplateId(), vm.getHypervisorType().toString(),
+                    VirtualMachine.class.getName(), vm.getUuid(), isDisplay);
+        }
+        else {
+            Map<String, String> customParameters = new HashMap<String, String>();
+            customParameters.put(UsageEventVO.DynamicParameters.cpuNumber.name(), serviceOffering.getCpu().toString());
+            customParameters.put(UsageEventVO.DynamicParameters.cpuSpeed.name(), serviceOffering.getSpeed().toString());
+            customParameters.put(UsageEventVO.DynamicParameters.memory.name(), serviceOffering.getRamSize().toString());
+            UsageEventUtils.publishUsageEvent(eventType, vm.getAccountId(), vm.getDataCenterId(), vm.getId(),
+                    vm.getHostName(), serviceOffering.getId(), vm.getTemplateId(), vm.getHypervisorType().toString(),
+                    VirtualMachine.class.getName(), vm.getUuid(), customParameters, isDisplay);
         }
     }
 
@@ -3409,7 +3460,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
             for (VolumeVO volume : volumes) {
                 if (volume.getVolumeType().equals(Volume.Type.ROOT)) {
                     UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
-                            Volume.class.getName(), volume.getUuid());
+                            Volume.class.getName(), volume.getUuid(), volume.isDisplayVolume());
                 }
             }
 
@@ -4214,7 +4265,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
             public void doInTransactionWithoutResult(TransactionStatus status) {
         //generate destroy vm event for usage
                 UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_DESTROY, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), vm.getHostName(), vm.getServiceOfferingId(),
-                        vm.getTemplateId(), vm.getHypervisorType().toString(), VirtualMachine.class.getName(), vm.getUuid());
+                        vm.getTemplateId(), vm.getHypervisorType().toString(), VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplayVm());
 
         // update resource counts for old account
                 resourceCountDecrement(oldAccount.getAccountId(), vm.isDisplayVm(), new Long(offering.getCpu()), new Long(offering.getRamSize()));
@@ -4226,20 +4277,20 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
 
         // OS 2: update volume
         for (VolumeVO volume : volumes) {
-                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
-                            Volume.class.getName(), volume.getUuid());
+            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
+                    Volume.class.getName(), volume.getUuid(), volume.isDisplayVolume());
             _resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.volume);
-                    _resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.primary_storage, new Long(volume.getSize()));
+            _resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.primary_storage, new Long(volume.getSize()));
             volume.setAccountId(newAccount.getAccountId());
             volume.setDomainId(newAccount.getDomainId());
             _volsDao.persist(volume);
             _resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.volume);
-                    _resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.primary_storage, new Long(volume.getSize()));
-                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
-                            volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(), volume.getUuid());
+            _resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.primary_storage, new Long(volume.getSize()));
+            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
+                    volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(), volume.getUuid(), volume.isDisplayVolume());
             //snapshots: mark these removed in db
             List<SnapshotVO> snapshots = _snapshotDao.listByVolumeIdIncludingRemoved(volume.getId());
-                    for (SnapshotVO snapshot : snapshots) {
+            for (SnapshotVO snapshot : snapshots) {
                 _snapshotDao.remove(snapshot.getId());
             }
         }
@@ -4249,7 +4300,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
 
         //generate usage events to account for this change
                 UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), vm.getHostName(), vm.getServiceOfferingId(),
-                        vm.getTemplateId(), vm.getHypervisorType().toString(), VirtualMachine.class.getName(), vm.getUuid());
+                        vm.getTemplateId(), vm.getHypervisorType().toString(), VirtualMachine.class.getName(), vm.getUuid(), vm.isDisplayVm());
             }
         });
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7442b56f/server/src/com/cloud/vm/UserVmStateListener.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/UserVmStateListener.java b/server/src/com/cloud/vm/UserVmStateListener.java
index 2f6be6c..af5f882 100644
--- a/server/src/com/cloud/vm/UserVmStateListener.java
+++ b/server/src/com/cloud/vm/UserVmStateListener.java
@@ -25,6 +25,7 @@ import java.util.Map;
 import javax.inject.Inject;
 
 import com.cloud.server.ManagementService;
+import com.cloud.vm.dao.UserVmDao;
 import org.apache.log4j.Logger;
 import org.springframework.beans.factory.NoSuchBeanDefinitionException;
 
@@ -33,11 +34,9 @@ import org.apache.cloudstack.framework.events.EventBus;
 import com.cloud.event.EventCategory;
 import com.cloud.event.EventTypes;
 import com.cloud.event.UsageEventUtils;
-import com.cloud.event.UsageEventVO;
 import com.cloud.event.dao.UsageEventDao;
 import com.cloud.network.dao.NetworkDao;
 import com.cloud.network.dao.NetworkVO;
-import com.cloud.service.ServiceOfferingVO;
 import com.cloud.service.dao.ServiceOfferingDao;
 import com.cloud.utils.component.ComponentContext;
 import com.cloud.utils.fsm.StateListener;
@@ -51,15 +50,19 @@ public class UserVmStateListener implements StateListener<State, VirtualMachine.
     @Inject protected NetworkDao _networkDao;
     @Inject protected NicDao _nicDao;
     @Inject protected ServiceOfferingDao _offeringDao;
+    @Inject protected UserVmDao _userVmDao;
+    @Inject protected UserVmManager _userVmMgr;
     private static final Logger s_logger = Logger.getLogger(UserVmStateListener.class);
 
     protected static EventBus s_eventBus = null;
 
-    public UserVmStateListener(UsageEventDao usageEventDao, NetworkDao networkDao, NicDao nicDao, ServiceOfferingDao offeringDao) {
+    public UserVmStateListener(UsageEventDao usageEventDao, NetworkDao networkDao, NicDao nicDao, ServiceOfferingDao offeringDao, UserVmDao userVmDao, UserVmManager userVmMgr) {
         this._usageEventDao = usageEventDao;
         this._networkDao = networkDao;
         this._nicDao = nicDao;
         this._offeringDao = offeringDao;
+        this._userVmDao = userVmDao;
+        this._userVmMgr = userVmMgr;
     }
 
     @Override
@@ -98,22 +101,14 @@ public class UserVmStateListener implements StateListener<State, VirtualMachine.
         return true;
     }
 
-    private void generateUsageEvent(Long serviceOfferingId,VirtualMachine vm,  String eventType){
-        ServiceOfferingVO serviceOffering = _offeringDao.findById(vm.getId(), serviceOfferingId);
-        if (!serviceOffering.isDynamic()) {
-            UsageEventUtils.publishUsageEvent(eventType, vm.getAccountId(), vm.getDataCenterId(), vm.getId(),
-                    vm.getHostName(), serviceOffering.getId(), vm.getTemplateId(), vm.getHypervisorType().toString(),
-                    VirtualMachine.class.getName(), vm.getUuid());
-        }
-        else {
-            Map<String, String> customParameters = new HashMap<String, String>();
-            customParameters.put(UsageEventVO.DynamicParameters.cpuNumber.name(), serviceOffering.getCpu().toString());
-            customParameters.put(UsageEventVO.DynamicParameters.cpuSpeed.name(), serviceOffering.getSpeed().toString());
-            customParameters.put(UsageEventVO.DynamicParameters.memory.name(), serviceOffering.getRamSize().toString());
-            UsageEventUtils.publishUsageEvent(eventType, vm.getAccountId(), vm.getDataCenterId(), vm.getId(),
-                    vm.getHostName(), serviceOffering.getId(), vm.getTemplateId(), vm.getHypervisorType().toString(),
-                    VirtualMachine.class.getName(), vm.getUuid(), customParameters);
+    private void generateUsageEvent(Long serviceOfferingId, VirtualMachine vm,  String eventType){
+        boolean displayVm = true;
+        if(vm.getType() == VirtualMachine.Type.User){
+            UserVmVO uservm = _userVmDao.findById(vm.getId());
+            displayVm = uservm.isDisplayVm();
         }
+
+        _userVmMgr.generateUsageEvent(vm, displayVm, eventType);
     }
 
     private void pubishOnEventBus(String event, String status, VirtualMachine vo, VirtualMachine.State oldState, VirtualMachine.State newState) {