CLOUDSTACK-7792: Usage Events to be captured based on Volume State Machine

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

Branch: refs/heads/statscollector-graphite
Commit: 781648fb1003c8c32875e9ff7a6c4ef4694539f7
Parents: cd48720
Author: Damodar <damoder.re...@citrix.com>
Authored: Mon Nov 10 15:12:03 2014 +0530
Committer: Kishan Kavala <kis...@apache.org>
Committed: Mon Nov 10 15:19:02 2014 +0530

----------------------------------------------------------------------
 api/src/com/cloud/storage/Volume.java           | 72 +++++++++++---------
 api/src/com/cloud/vm/VirtualMachine.java        |  2 +-
 .../storage/ObjectInDataStoreStateMachine.java  |  3 +
 .../orchestration/VolumeOrchestrator.java       |  2 -
 .../schema/src/com/cloud/storage/VolumeVO.java  |  2 +-
 .../cloudstack/storage/volume/VolumeObject.java |  8 ++-
 .../storage/volume/VolumeServiceImpl.java       |  6 +-
 .../com/cloud/storage/StorageManagerImpl.java   |  2 +-
 .../com/cloud/storage/VolumeApiServiceImpl.java |  7 --
 .../storage/listener/VolumeStateListener.java   | 37 +++++++++-
 10 files changed, 90 insertions(+), 51 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/781648fb/api/src/com/cloud/storage/Volume.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/storage/Volume.java 
b/api/src/com/cloud/storage/Volume.java
index 91ad955..89d08f7 100755
--- a/api/src/com/cloud/storage/Volume.java
+++ b/api/src/com/cloud/storage/Volume.java
@@ -16,6 +16,7 @@
 // under the License.
 package com.cloud.storage;
 
+import java.util.Arrays;
 import java.util.Date;
 
 import org.apache.cloudstack.acl.ControlledEntity;
@@ -64,38 +65,42 @@ public interface Volume extends ControlledEntity, Identity, 
InternalIdentity, Ba
 
         private final static StateMachine2<State, Event, Volume> s_fsm = new 
StateMachine2<State, Event, Volume>();
         static {
-            s_fsm.addTransition(Allocated, Event.CreateRequested, Creating);
-            s_fsm.addTransition(Allocated, Event.DestroyRequested, Destroy);
-            s_fsm.addTransition(Creating, Event.OperationRetry, Creating);
-            s_fsm.addTransition(Creating, Event.OperationFailed, Allocated);
-            s_fsm.addTransition(Creating, Event.OperationSucceeded, Ready);
-            s_fsm.addTransition(Creating, Event.CreateRequested, Creating);
-            s_fsm.addTransition(Ready, Event.ResizeRequested, Resizing);
-            s_fsm.addTransition(Resizing, Event.OperationSucceeded, Ready);
-            s_fsm.addTransition(Resizing, Event.OperationFailed, Ready);
-            s_fsm.addTransition(Allocated, Event.UploadRequested, UploadOp);
-            s_fsm.addTransition(Uploaded, Event.CopyRequested, Copying);
-            s_fsm.addTransition(Copying, Event.OperationSucceeded, Ready);
-            s_fsm.addTransition(Copying, Event.OperationFailed, Uploaded);
-            s_fsm.addTransition(UploadOp, Event.DestroyRequested, Destroy);
-            s_fsm.addTransition(Ready, Event.DestroyRequested, Destroy);
-            s_fsm.addTransition(Destroy, Event.ExpungingRequested, Expunging);
-            s_fsm.addTransition(Expunging, Event.ExpungingRequested, 
Expunging);
-            s_fsm.addTransition(Expunging, Event.OperationSucceeded, Expunged);
-            s_fsm.addTransition(Expunging, Event.OperationFailed, Destroy);
-            s_fsm.addTransition(Ready, Event.SnapshotRequested, Snapshotting);
-            s_fsm.addTransition(Snapshotting, Event.OperationSucceeded, Ready);
-            s_fsm.addTransition(Snapshotting, Event.OperationFailed, Ready);
-            s_fsm.addTransition(Ready, Event.MigrationRequested, Migrating);
-            s_fsm.addTransition(Migrating, Event.OperationSucceeded, Ready);
-            s_fsm.addTransition(Migrating, Event.OperationFailed, Ready);
-            s_fsm.addTransition(Destroy, Event.OperationSucceeded, Destroy);
-            s_fsm.addTransition(UploadOp, Event.OperationSucceeded, Uploaded);
-            s_fsm.addTransition(UploadOp, Event.OperationFailed, Allocated);
-            s_fsm.addTransition(Uploaded, Event.DestroyRequested, Destroy);
-            s_fsm.addTransition(Expunged, Event.ExpungingRequested, Expunged);
-            s_fsm.addTransition(Expunged, Event.OperationSucceeded, Expunged);
-            s_fsm.addTransition(Expunged, Event.OperationFailed, Expunged);
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(Allocated, Event.CreateRequested, Creating, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(Allocated, Event.DestroyRequested, Destroy, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(Creating, Event.OperationRetry, Creating, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(Creating, Event.OperationFailed, Allocated, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(Creating, Event.OperationSucceeded, Ready, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(Creating, Event.DestroyRequested, Destroy, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(Creating, Event.CreateRequested, Creating, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(Ready, Event.ResizeRequested, Resizing, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(Resizing, Event.OperationSucceeded, Ready, Arrays.asList(new 
StateMachine2.Transition.Impact[]{StateMachine2.Transition.Impact.USAGE})));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(Resizing, Event.OperationFailed, Ready, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(Allocated, Event.UploadRequested, UploadOp, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(Uploaded, Event.CopyRequested, Copying, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(Copying, Event.OperationSucceeded, Ready, Arrays.asList(new 
StateMachine2.Transition.Impact[]{StateMachine2.Transition.Impact.USAGE})));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(Copying, Event.OperationFailed, Uploaded, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(UploadOp, Event.DestroyRequested, Destroy, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(Ready, Event.DestroyRequested, Destroy, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(Destroy, Event.ExpungingRequested, Expunging, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(Expunging, Event.ExpungingRequested, Expunging, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(Expunging, Event.OperationSucceeded, Expunged,null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(Expunging, Event.OperationFailed, Destroy, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(Ready, Event.SnapshotRequested, Snapshotting, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(Snapshotting, Event.OperationSucceeded, Ready, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(Snapshotting, Event.OperationFailed, Ready,null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(Allocated, Event.MigrationCopyRequested, Creating, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(Creating, Event.MigrationCopyFailed, Allocated, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(Creating, Event.MigrationCopySucceeded, Ready, Arrays.asList(new 
StateMachine2.Transition.Impact[]{StateMachine2.Transition.Impact.USAGE})));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(Ready, Event.MigrationRequested, Migrating, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(Migrating, Event.OperationSucceeded, Ready, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(Migrating, Event.OperationFailed, Ready, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(Destroy, Event.OperationSucceeded, Destroy, Arrays.asList(new 
StateMachine2.Transition.Impact[]{StateMachine2.Transition.Impact.USAGE})));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(UploadOp, Event.OperationSucceeded, Uploaded, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(UploadOp, Event.OperationFailed, Allocated, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(Uploaded, Event.DestroyRequested, Destroy, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(Expunged, Event.ExpungingRequested, Expunged, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(Expunged, Event.OperationSucceeded, Expunged, null));
+            s_fsm.addTransition(new StateMachine2.Transition<State, 
Event>(Expunged, Event.OperationFailed, Expunged,null));
         }
     }
 
@@ -109,6 +114,9 @@ public interface Volume extends ControlledEntity, Identity, 
InternalIdentity, Ba
         OperationRetry,
         UploadRequested,
         MigrationRequested,
+        MigrationCopyRequested,
+        MigrationCopySucceeded,
+        MigrationCopyFailed,
         SnapshotRequested,
         DestroyRequested,
         ExpungingRequested,

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/781648fb/api/src/com/cloud/vm/VirtualMachine.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/vm/VirtualMachine.java 
b/api/src/com/cloud/vm/VirtualMachine.java
index 99152d6..2a6039f 100755
--- a/api/src/com/cloud/vm/VirtualMachine.java
+++ b/api/src/com/cloud/vm/VirtualMachine.java
@@ -98,7 +98,7 @@ public interface VirtualMachine extends RunningOn, 
ControlledEntity, Identity, I
             s_fsm.addTransition(new Transition<State, Event>(State.Starting, 
VirtualMachine.Event.AgentReportRunning, State.Running, Arrays.asList(new 
Impact[]{Impact.USAGE})));
             s_fsm.addTransition(new Transition<State, Event>(State.Starting, 
VirtualMachine.Event.AgentReportStopped, State.Stopped, null));
             s_fsm.addTransition(new Transition<State, Event>(State.Starting, 
VirtualMachine.Event.AgentReportShutdowned, State.Stopped, null));
-            s_fsm.addTransition(new Transition<State, Event>(State.Destroyed, 
VirtualMachine.Event.RecoveryRequested, State.Stopped, null));
+            s_fsm.addTransition(new Transition<State, Event>(State.Destroyed, 
VirtualMachine.Event.RecoveryRequested, State.Stopped, Arrays.asList(new 
Impact[]{Impact.USAGE})));
             s_fsm.addTransition(new Transition<State, Event>(State.Destroyed, 
VirtualMachine.Event.ExpungeOperation, State.Expunging, null));
             s_fsm.addTransition(new Transition<State, Event>(State.Running, 
VirtualMachine.Event.MigrationRequested, State.Migrating, null));
             s_fsm.addTransition(new Transition<State, Event>(State.Running, 
VirtualMachine.Event.AgentReportRunning, State.Running, null));

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/781648fb/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ObjectInDataStoreStateMachine.java
----------------------------------------------------------------------
diff --git 
a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ObjectInDataStoreStateMachine.java
 
b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ObjectInDataStoreStateMachine.java
index b21616a..204cab0 100644
--- 
a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ObjectInDataStoreStateMachine.java
+++ 
b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ObjectInDataStoreStateMachine.java
@@ -51,6 +51,9 @@ public interface ObjectInDataStoreStateMachine extends 
StateObject<ObjectInDataS
         OperationFailed,
         CopyingRequested,
         MigrationRequested,
+        MigrationCopyRequested,
+        MigrationCopySucceeded,
+        MigrationCopyFailed,
         ResizeRequested,
         ExpungeRequested
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/781648fb/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 826e2ee..f474fe3 100644
--- 
a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
+++ 
b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
@@ -1382,8 +1382,6 @@ public class VolumeOrchestrator extends ManagerBase 
implements VolumeOrchestrati
             }
             // FIXME - All this is boiler plate code and should be done as 
part of state transition. This shouldn't be part of orchestrator.
             // publish usage event for the volume
-            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, 
volume.getAccountId(), volume.getDataCenterId(), volume.getId(), 
volume.getName(),
-                    Volume.class.getName(), volume.getUuid(), 
volume.isDisplayVolume());
             _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), 
ResourceType.volume, volume.isDisplay());
             //FIXME - why recalculate and not decrement
             _resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), 
volume.getDomainId(), ResourceType.primary_storage.getOrdinal());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/781648fb/engine/schema/src/com/cloud/storage/VolumeVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/storage/VolumeVO.java 
b/engine/schema/src/com/cloud/storage/VolumeVO.java
index e328253..e2f717d 100755
--- a/engine/schema/src/com/cloud/storage/VolumeVO.java
+++ b/engine/schema/src/com/cloud/storage/VolumeVO.java
@@ -247,7 +247,7 @@ public class VolumeVO implements Volume {
             that.get_iScsiName(),
             that.getVolumeType());
         recreatable = that.isRecreatable();
-        state = that.getState();
+        state = State.Allocated; //This should be in Allocated state before 
going into Ready state
         size = that.getSize();
         minIops = that.getMinIops();
         maxIops = that.getMaxIops();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/781648fb/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
----------------------------------------------------------------------
diff --git 
a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
 
b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
index f2b4c95..6a42435 100644
--- 
a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
+++ 
b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
@@ -178,7 +178,7 @@ public class VolumeObject implements VolumeInfo {
     }
 
     @Override
-    public boolean stateTransit(Volume.Event event) {
+    public boolean  stateTransit(Volume.Event event) {
         boolean result = false;
         try {
             volumeVO = volumeDao.findById(volumeVO.getId());
@@ -308,6 +308,8 @@ public class VolumeObject implements VolumeInfo {
                     volEvent = Volume.Event.CopyRequested;
                 } else if (event == 
ObjectInDataStoreStateMachine.Event.MigrationRequested) {
                     volEvent = Volume.Event.MigrationRequested;
+                } else if (event == 
ObjectInDataStoreStateMachine.Event.MigrationCopyRequested) {
+                    volEvent = Event.MigrationCopyRequested;
                 }
             }
 
@@ -317,8 +319,12 @@ public class VolumeObject implements VolumeInfo {
                 volEvent = Volume.Event.ExpungingRequested;
             } else if (event == 
ObjectInDataStoreStateMachine.Event.OperationSuccessed) {
                 volEvent = Volume.Event.OperationSucceeded;
+            } else if (event == 
ObjectInDataStoreStateMachine.Event.MigrationCopySucceeded) {
+              volEvent = Event.MigrationCopySucceeded;
             } else if (event == 
ObjectInDataStoreStateMachine.Event.OperationFailed) {
                 volEvent = Volume.Event.OperationFailed;
+            } else if (event == 
ObjectInDataStoreStateMachine.Event.MigrationCopyFailed) {
+              volEvent = Event.MigrationCopyFailed;
             } else if (event == 
ObjectInDataStoreStateMachine.Event.ResizeRequested) {
                 volEvent = Volume.Event.ResizeRequested;
             }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/781648fb/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
 
b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
index 9c45cb8..174874a 100644
--- 
a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
+++ 
b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
@@ -984,7 +984,7 @@ public class VolumeServiceImpl implements VolumeService {
 
             VolumeVO destVol = duplicateVolumeOnAnotherStorage(srcVolume, 
(StoragePool)destStore);
             VolumeInfo destVolume = volFactory.getVolume(destVol.getId(), 
destStore);
-            destVolume.processEvent(Event.MigrationRequested);
+            destVolume.processEvent(Event.MigrationCopyRequested);
             srcVolume.processEvent(Event.MigrationRequested);
 
             CopyVolumeContext<VolumeApiResult> context = new 
CopyVolumeContext<VolumeApiResult>(null, future, srcVolume, destVolume, 
destStore);
@@ -1008,7 +1008,7 @@ public class VolumeServiceImpl implements VolumeService {
         try {
             if (result.isFailed()) {
                 res.setResult(result.getResult());
-                destVolume.processEvent(Event.OperationFailed);
+                destVolume.processEvent(Event.MigrationCopyFailed);
                 srcVolume.processEvent(Event.OperationFailed);
                 destroyVolume(destVolume.getId());
                 destVolume = volFactory.getVolume(destVolume.getId());
@@ -1018,7 +1018,7 @@ public class VolumeServiceImpl implements VolumeService {
                 return null;
             }
             srcVolume.processEvent(Event.OperationSuccessed);
-            destVolume.processEvent(Event.OperationSuccessed, 
result.getAnswer());
+            destVolume.processEvent(Event.MigrationCopySucceeded, 
result.getAnswer());
             _volumeDao.updateUuid(srcVolume.getId(), destVolume.getId());
             try {
                 destroyVolume(srcVolume.getId());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/781648fb/server/src/com/cloud/storage/StorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java 
b/server/src/com/cloud/storage/StorageManagerImpl.java
index 153c25a..297f1ce 100755
--- a/server/src/com/cloud/storage/StorageManagerImpl.java
+++ b/server/src/com/cloud/storage/StorageManagerImpl.java
@@ -499,7 +499,7 @@ public class StorageManagerImpl extends ManagerBase 
implements StorageManager, C
         LocalStorageSearch.and("type", 
LocalStorageSearch.entity().getPoolType(), SearchCriteria.Op.IN);
         LocalStorageSearch.done();
 
-        Volume.State.getStateMachine().registerListener(new 
VolumeStateListener(_configDao));
+        Volume.State.getStateMachine().registerListener(new 
VolumeStateListener(_configDao, _vmInstanceDao));
 
         return true;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/781648fb/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 088f054..17902c2 100644
--- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
@@ -1043,9 +1043,6 @@ public class VolumeApiServiceImpl extends ManagerBase 
implements VolumeApiServic
             }
 
             _volsDao.update(volume.getId(), volume);
-            // Log usage event for volumes belonging user VM's only
-            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_RESIZE, 
volume.getAccountId(), volume.getDataCenterId(), volume.getId(), 
volume.getName(),
-                    volume.getDiskOfferingId(), volume.getTemplateId(), 
volume.getSize(), Volume.class.getName(), volume.getUuid());
 
             /* Update resource count for the account on primary storage 
resource */
             if (!shrinkOk) {
@@ -1111,10 +1108,6 @@ public class VolumeApiServiceImpl extends ManagerBase 
implements VolumeApiServic
                     } else {
                         
_resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), 
volume.getDomainId(), ResourceType.secondary_storage.getOrdinal());
                     }
-
-                    // 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.isDisplayVolume());
                 }
             }
             // Mark volume as removed if volume has not been created on 
primary or secondary

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/781648fb/server/src/com/cloud/storage/listener/VolumeStateListener.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/listener/VolumeStateListener.java 
b/server/src/com/cloud/storage/listener/VolumeStateListener.java
index 0ba2969..9fd1423 100644
--- a/server/src/com/cloud/storage/listener/VolumeStateListener.java
+++ b/server/src/com/cloud/storage/listener/VolumeStateListener.java
@@ -22,7 +22,12 @@ import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
 
+import com.cloud.event.EventTypes;
+import com.cloud.event.UsageEventUtils;
 import com.cloud.utils.fsm.StateMachine2;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.dao.VMInstanceDao;
 import org.apache.log4j.Logger;
 import org.springframework.beans.factory.NoSuchBeanDefinitionException;
 
@@ -43,11 +48,13 @@ public class VolumeStateListener implements 
StateListener<State, Event, Volume>
 
     protected static EventBus s_eventBus = null;
     protected ConfigurationDao _configDao;
+    protected VMInstanceDao _vmInstanceDao;
 
     private static final Logger s_logger = 
Logger.getLogger(VolumeStateListener.class);
 
-    public VolumeStateListener(ConfigurationDao configDao) {
+    public VolumeStateListener(ConfigurationDao configDao, VMInstanceDao 
vmInstanceDao) {
         this._configDao = configDao;
+        this._vmInstanceDao = vmInstanceDao;
     }
 
     @Override
@@ -57,8 +64,32 @@ public class VolumeStateListener implements 
StateListener<State, Event, Volume>
     }
 
     @Override
-    public boolean postStateTransitionEvent(StateMachine2.Transition<State, 
Event> transition, Volume vo, boolean status, Object opaque) {
-      pubishOnEventBus(transition.getEvent().name(), 
"postStateTransitionEvent", vo, transition.getCurrentState(), 
transition.getToState());
+    public boolean postStateTransitionEvent(StateMachine2.Transition<State, 
Event> transition, Volume vol, boolean status, Object opaque) {
+      pubishOnEventBus(transition.getEvent().name(), 
"postStateTransitionEvent", vol, transition.getCurrentState(), 
transition.getToState());
+      if(transition.isImpacted(StateMachine2.Transition.Impact.USAGE)) {
+        Long instanceId = vol.getInstanceId();
+        VMInstanceVO vmInstanceVO = null;
+        if(instanceId != null) {
+          vmInstanceVO = _vmInstanceDao.findById(instanceId);
+        }
+        if(instanceId == null || vmInstanceVO.getType() == 
VirtualMachine.Type.User) {
+          if (transition.getToState() == State.Ready) {
+            if (transition.getCurrentState() == State.Resizing) {
+              // Log usage event for volumes belonging user VM's only
+              
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_RESIZE, 
vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(),
+                      vol.getDiskOfferingId(), vol.getTemplateId(), 
vol.getSize(), Volume.class.getName(), vol.getUuid());
+            } else {
+              
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, 
vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), 
vol.getDiskOfferingId(), null, vol.getSize(),
+                      Volume.class.getName(), vol.getUuid(), 
vol.isDisplayVolume());
+            }
+          } else if (transition.getToState() == State.Destroy) {
+            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, 
vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(),
+                    Volume.class.getName(), vol.getUuid(), 
vol.isDisplayVolume());
+          } else if (transition.getToState() == State.Uploaded) {
+            //Currently we are not capturing Usage for Secondary Storage so 
Usage for this operation will be captured when it is moved to primary storage
+          }
+        }
+      }
       return true;
     }
 

Reply via email to