cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kis...@apache.org
Subject git commit: updated refs/heads/master to 50185b7
Date Mon, 13 Oct 2014 09:23:53 GMT
Repository: cloudstack
Updated Branches:
  refs/heads/master b6cacb3d6 -> 50185b7c3


CLOUDSTACK-7648: There are new VM State Machine changes introduced which were missed to capture the usage events


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

Branch: refs/heads/master
Commit: 50185b7c3a1fd26e9a8635c28cee70fda32d3fc5
Parents: b6cacb3
Author: Damodar <damoder.reddy@citrix.com>
Authored: Thu Oct 9 11:52:28 2014 +0530
Committer: Kishan Kavala <kishan@apache.org>
Committed: Mon Oct 13 14:42:00 2014 +0530

----------------------------------------------------------------------
 api/src/com/cloud/vm/VirtualMachine.java        | 109 +++++++-------
 .../com/cloud/network/NetworkStateListener.java |  12 +-
 .../baremetal/manager/BaremetalManagerImpl.java |  53 +++----
 .../cloud/network/ovs/OvsTunnelManagerImpl.java |  36 ++---
 .../com/cloud/capacity/CapacityManagerImpl.java | 124 ++++++++--------
 .../deploy/DeploymentPlanningManagerImpl.java   |  25 ++--
 .../VirtualNetworkApplianceManagerImpl.java     |  22 +--
 .../security/SecurityGroupManagerImpl.java      |  46 +++---
 .../storage/listener/SnapshotStateListener.java |   9 +-
 .../storage/listener/VolumeStateListener.java   |   9 +-
 .../src/com/cloud/vm/UserVmStateListener.java   |  57 ++++----
 .../affinity/AffinityGroupServiceImpl.java      |  26 ++--
 .../src/com/cloud/utils/fsm/StateListener.java  |  17 +--
 .../src/com/cloud/utils/fsm/StateMachine2.java  | 142 ++++++++++++++-----
 14 files changed, 398 insertions(+), 289 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/50185b7c/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 34387eb..99152d6 100755
--- a/api/src/com/cloud/vm/VirtualMachine.java
+++ b/api/src/com/cloud/vm/VirtualMachine.java
@@ -16,6 +16,7 @@
 // under the License.
 package com.cloud.vm;
 
+import java.util.Arrays;
 import java.util.Date;
 import java.util.Map;
 
@@ -26,6 +27,8 @@ import org.apache.cloudstack.api.InternalIdentity;
 
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
 import com.cloud.utils.fsm.StateMachine2;
+import com.cloud.utils.fsm.StateMachine2.Transition;
+import com.cloud.utils.fsm.StateMachine2.Transition.Impact;
 import com.cloud.utils.fsm.StateObject;
 
 /**
@@ -75,63 +78,63 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, Identity, I
 
         protected static final StateMachine2<State, VirtualMachine.Event, VirtualMachine> s_fsm = new StateMachine2<State, VirtualMachine.Event, VirtualMachine>();
         static {
-            s_fsm.addTransition(State.Stopped, VirtualMachine.Event.StartRequested, State.Starting);
-            s_fsm.addTransition(State.Stopped, VirtualMachine.Event.DestroyRequested, State.Destroyed);
-            s_fsm.addTransition(State.Stopped, VirtualMachine.Event.StopRequested, State.Stopped);
-            s_fsm.addTransition(State.Stopped, VirtualMachine.Event.AgentReportStopped, State.Stopped);
+            s_fsm.addTransition(new Transition<State, Event>(State.Stopped, VirtualMachine.Event.StartRequested, State.Starting, null));
+            s_fsm.addTransition(new Transition<State, Event>(State.Stopped, VirtualMachine.Event.DestroyRequested, State.Destroyed, Arrays.asList(new Impact[]{Impact.USAGE})));
+            s_fsm.addTransition(new Transition<State, Event>(State.Stopped, VirtualMachine.Event.StopRequested, State.Stopped, null));
+            s_fsm.addTransition(new Transition<State, Event>(State.Stopped, VirtualMachine.Event.AgentReportStopped, State.Stopped, null));
 
             // please pay attention about state transition to Error state, there should be only one case (failed in VM
             // creation process)
             // that can have such transition
-            s_fsm.addTransition(State.Stopped, VirtualMachine.Event.OperationFailedToError, State.Error);
-
-            s_fsm.addTransition(State.Stopped, VirtualMachine.Event.OperationFailed, State.Stopped);
-            s_fsm.addTransition(State.Stopped, VirtualMachine.Event.ExpungeOperation, State.Expunging);
-            s_fsm.addTransition(State.Stopped, VirtualMachine.Event.AgentReportShutdowned, State.Stopped);
-            s_fsm.addTransition(State.Stopped, VirtualMachine.Event.StorageMigrationRequested, State.Migrating);
-            s_fsm.addTransition(State.Starting, VirtualMachine.Event.OperationRetry, State.Starting);
-            s_fsm.addTransition(State.Starting, VirtualMachine.Event.OperationSucceeded, State.Running);
-            s_fsm.addTransition(State.Starting, VirtualMachine.Event.OperationFailed, State.Stopped);
-            s_fsm.addTransition(State.Starting, VirtualMachine.Event.AgentReportRunning, State.Running);
-            s_fsm.addTransition(State.Starting, VirtualMachine.Event.AgentReportStopped, State.Stopped);
-            s_fsm.addTransition(State.Starting, VirtualMachine.Event.AgentReportShutdowned, State.Stopped);
-            s_fsm.addTransition(State.Destroyed, VirtualMachine.Event.RecoveryRequested, State.Stopped);
-            s_fsm.addTransition(State.Destroyed, VirtualMachine.Event.ExpungeOperation, State.Expunging);
-            s_fsm.addTransition(State.Running, VirtualMachine.Event.MigrationRequested, State.Migrating);
-            s_fsm.addTransition(State.Running, VirtualMachine.Event.AgentReportRunning, State.Running);
-            s_fsm.addTransition(State.Running, VirtualMachine.Event.AgentReportStopped, State.Stopped);
-            s_fsm.addTransition(State.Running, VirtualMachine.Event.StopRequested, State.Stopping);
-            s_fsm.addTransition(State.Running, VirtualMachine.Event.AgentReportShutdowned, State.Stopped);
-            s_fsm.addTransition(State.Running, VirtualMachine.Event.AgentReportMigrated, State.Running);
-            s_fsm.addTransition(State.Running, VirtualMachine.Event.OperationSucceeded, State.Running);
-            s_fsm.addTransition(State.Migrating, VirtualMachine.Event.MigrationRequested, State.Migrating);
-            s_fsm.addTransition(State.Migrating, VirtualMachine.Event.OperationSucceeded, State.Running);
-            s_fsm.addTransition(State.Migrating, VirtualMachine.Event.OperationFailed, State.Running);
-            s_fsm.addTransition(State.Migrating, VirtualMachine.Event.AgentReportRunning, State.Running);
-            s_fsm.addTransition(State.Migrating, VirtualMachine.Event.AgentReportStopped, State.Stopped);
-            s_fsm.addTransition(State.Migrating, VirtualMachine.Event.AgentReportShutdowned, State.Stopped);
-            s_fsm.addTransition(State.Stopping, VirtualMachine.Event.OperationSucceeded, State.Stopped);
-            s_fsm.addTransition(State.Stopping, VirtualMachine.Event.OperationFailed, State.Running);
-            s_fsm.addTransition(State.Stopping, VirtualMachine.Event.AgentReportRunning, State.Running);
-            s_fsm.addTransition(State.Stopping, VirtualMachine.Event.AgentReportStopped, State.Stopped);
-            s_fsm.addTransition(State.Stopping, VirtualMachine.Event.StopRequested, State.Stopping);
-            s_fsm.addTransition(State.Stopping, VirtualMachine.Event.AgentReportShutdowned, State.Stopped);
-            s_fsm.addTransition(State.Expunging, VirtualMachine.Event.OperationFailed, State.Expunging);
-            s_fsm.addTransition(State.Expunging, VirtualMachine.Event.ExpungeOperation, State.Expunging);
-            s_fsm.addTransition(State.Error, VirtualMachine.Event.DestroyRequested, State.Expunging);
-            s_fsm.addTransition(State.Error, VirtualMachine.Event.ExpungeOperation, State.Expunging);
-
-            s_fsm.addTransition(State.Starting, VirtualMachine.Event.FollowAgentPowerOnReport, State.Running);
-            s_fsm.addTransition(State.Stopping, VirtualMachine.Event.FollowAgentPowerOnReport, State.Running);
-            s_fsm.addTransition(State.Stopped, VirtualMachine.Event.FollowAgentPowerOnReport, State.Running);
-            s_fsm.addTransition(State.Running, VirtualMachine.Event.FollowAgentPowerOnReport, State.Running);
-            s_fsm.addTransition(State.Migrating, VirtualMachine.Event.FollowAgentPowerOnReport, State.Running);
-
-            s_fsm.addTransition(State.Starting, VirtualMachine.Event.FollowAgentPowerOffReport, State.Stopped);
-            s_fsm.addTransition(State.Stopping, VirtualMachine.Event.FollowAgentPowerOffReport, State.Stopped);
-            s_fsm.addTransition(State.Running, VirtualMachine.Event.FollowAgentPowerOffReport, State.Stopped);
-            s_fsm.addTransition(State.Migrating, VirtualMachine.Event.FollowAgentPowerOffReport, State.Stopped);
-            s_fsm.addTransition(State.Stopped, VirtualMachine.Event.FollowAgentPowerOffReport, State.Stopped);
+            s_fsm.addTransition(new Transition<State, Event>(State.Stopped, VirtualMachine.Event.OperationFailedToError, State.Error, Arrays.asList(new Impact[]{Impact.USAGE})));
+
+            s_fsm.addTransition(new Transition<State, Event>(State.Stopped, VirtualMachine.Event.OperationFailed, State.Stopped, null));
+            s_fsm.addTransition(new Transition<State, Event>(State.Stopped, VirtualMachine.Event.ExpungeOperation, State.Expunging, Arrays.asList(new Impact[]{Impact.USAGE})));
+            s_fsm.addTransition(new Transition<State, Event>(State.Stopped, VirtualMachine.Event.AgentReportShutdowned, State.Stopped, null));
+            s_fsm.addTransition(new Transition<State, Event>(State.Stopped, VirtualMachine.Event.StorageMigrationRequested, State.Migrating, null));
+            s_fsm.addTransition(new Transition<State, Event>(State.Starting, VirtualMachine.Event.OperationRetry, State.Starting, null));
+            s_fsm.addTransition(new Transition<State, Event>(State.Starting, VirtualMachine.Event.OperationSucceeded, State.Running, Arrays.asList(new Impact[]{Impact.USAGE})));
+            s_fsm.addTransition(new Transition<State, Event>(State.Starting, VirtualMachine.Event.OperationFailed, State.Stopped, null));
+            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.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));
+            s_fsm.addTransition(new Transition<State, Event>(State.Running, VirtualMachine.Event.AgentReportStopped, State.Stopped, Arrays.asList(new Impact[]{Impact.USAGE})));
+            s_fsm.addTransition(new Transition<State, Event>(State.Running, VirtualMachine.Event.StopRequested, State.Stopping, null));
+            s_fsm.addTransition(new Transition<State, Event>(State.Running, VirtualMachine.Event.AgentReportShutdowned, State.Stopped, Arrays.asList(new Impact[]{Impact.USAGE})));
+            s_fsm.addTransition(new Transition<State, Event>(State.Running, VirtualMachine.Event.AgentReportMigrated, State.Running, null));
+            s_fsm.addTransition(new Transition<State, Event>(State.Running, VirtualMachine.Event.OperationSucceeded, State.Running, null));
+            s_fsm.addTransition(new Transition<State, Event>(State.Migrating, VirtualMachine.Event.MigrationRequested, State.Migrating, null));
+            s_fsm.addTransition(new Transition<State, Event>(State.Migrating, VirtualMachine.Event.OperationSucceeded, State.Running, null));
+            s_fsm.addTransition(new Transition<State, Event>(State.Migrating, VirtualMachine.Event.OperationFailed, State.Running, null));
+            s_fsm.addTransition(new Transition<State, Event>(State.Migrating, VirtualMachine.Event.AgentReportRunning, State.Running, null));
+            s_fsm.addTransition(new Transition<State, Event>(State.Migrating, VirtualMachine.Event.AgentReportStopped, State.Stopped, null));
+            s_fsm.addTransition(new Transition<State, Event>(State.Migrating, VirtualMachine.Event.AgentReportShutdowned, State.Stopped, null));
+            s_fsm.addTransition(new Transition<State, Event>(State.Stopping, VirtualMachine.Event.OperationSucceeded, State.Stopped, Arrays.asList(new Impact[]{Impact.USAGE})));
+            s_fsm.addTransition(new Transition<State, Event>(State.Stopping, VirtualMachine.Event.OperationFailed, State.Running, null));
+            s_fsm.addTransition(new Transition<State, Event>(State.Stopping, VirtualMachine.Event.AgentReportRunning, State.Running, null));
+            s_fsm.addTransition(new Transition<State, Event>(State.Stopping, VirtualMachine.Event.AgentReportStopped, State.Stopped, Arrays.asList(new Impact[]{Impact.USAGE})));
+            s_fsm.addTransition(new Transition<State, Event>(State.Stopping, VirtualMachine.Event.StopRequested, State.Stopping, null));
+            s_fsm.addTransition(new Transition<State, Event>(State.Stopping, VirtualMachine.Event.AgentReportShutdowned, State.Stopped, Arrays.asList(new Impact[]{Impact.USAGE})));
+            s_fsm.addTransition(new Transition<State, Event>(State.Expunging, VirtualMachine.Event.OperationFailed, State.Expunging,null));
+            s_fsm.addTransition(new Transition<State, Event>(State.Expunging, VirtualMachine.Event.ExpungeOperation, State.Expunging,null));
+            s_fsm.addTransition(new Transition<State, Event>(State.Error, VirtualMachine.Event.DestroyRequested, State.Expunging, null));
+            s_fsm.addTransition(new Transition<State, Event>(State.Error, VirtualMachine.Event.ExpungeOperation, State.Expunging, null));
+
+            s_fsm.addTransition(new Transition<State, Event>(State.Starting, VirtualMachine.Event.FollowAgentPowerOnReport, State.Running, Arrays.asList(new Impact[]{Impact.USAGE})));
+            s_fsm.addTransition(new Transition<State, Event>(State.Stopping, VirtualMachine.Event.FollowAgentPowerOnReport, State.Running, null));
+            s_fsm.addTransition(new Transition<State, Event>(State.Stopped, VirtualMachine.Event.FollowAgentPowerOnReport, State.Running, Arrays.asList(new Impact[]{Impact.USAGE})));
+            s_fsm.addTransition(new Transition<State, Event>(State.Running, VirtualMachine.Event.FollowAgentPowerOnReport, State.Running, null));
+            s_fsm.addTransition(new Transition<State, Event>(State.Migrating, VirtualMachine.Event.FollowAgentPowerOnReport, State.Running, null));
+
+            s_fsm.addTransition(new Transition<State, Event>(State.Starting, VirtualMachine.Event.FollowAgentPowerOffReport, State.Stopped, null));
+            s_fsm.addTransition(new Transition<State, Event>(State.Stopping, VirtualMachine.Event.FollowAgentPowerOffReport, State.Stopped, Arrays.asList(new Impact[]{Impact.USAGE})));
+            s_fsm.addTransition(new Transition<State, Event>(State.Running, VirtualMachine.Event.FollowAgentPowerOffReport, State.Stopped, Arrays.asList(new Impact[]{Impact.USAGE})));
+            s_fsm.addTransition(new Transition<State, Event>(State.Migrating, VirtualMachine.Event.FollowAgentPowerOffReport, State.Stopped, null));
+            s_fsm.addTransition(new Transition<State, Event>(State.Stopped, VirtualMachine.Event.FollowAgentPowerOffReport, State.Stopped, null));
         }
 
         public static boolean isVmStarted(State oldState, Event e, State newState) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/50185b7c/engine/components-api/src/com/cloud/network/NetworkStateListener.java
----------------------------------------------------------------------
diff --git a/engine/components-api/src/com/cloud/network/NetworkStateListener.java b/engine/components-api/src/com/cloud/network/NetworkStateListener.java
index c86f782..0ed1d9e 100644
--- a/engine/components-api/src/com/cloud/network/NetworkStateListener.java
+++ b/engine/components-api/src/com/cloud/network/NetworkStateListener.java
@@ -24,6 +24,7 @@ import java.util.Map;
 
 import javax.inject.Inject;
 
+import com.cloud.utils.fsm.StateMachine2;
 import org.apache.log4j.Logger;
 import org.springframework.beans.factory.NoSuchBeanDefinitionException;
 
@@ -65,12 +66,15 @@ public class NetworkStateListener implements StateListener<State, Event, Network
     }
 
     @Override
-    public boolean postStateTransitionEvent(State oldState, Event event, State newState, Network vo, boolean status, Object opaque) {
-        pubishOnEventBus(event.name(), "postStateTransitionEvent", vo, oldState, newState);
-        return true;
+    public boolean postStateTransitionEvent(StateMachine2.Transition<State, Event> transition, Network vo, boolean status, Object opaque) {
+      State oldState = transition.getCurrentState();
+      State newState = transition.getToState();
+      Event event = transition.getEvent();
+      pubishOnEventBus(event.name(), "postStateTransitionEvent", vo, oldState, newState);
+      return true;
     }
 
-    private void pubishOnEventBus(String event, String status, Network vo, State oldState, State newState) {
+  private void pubishOnEventBus(String event, String status, Network vo, State oldState, State newState) {
 
         String configKey = "publish.resource.state.events";
         String value = _configDao.getValue(configKey);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/50185b7c/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalManagerImpl.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalManagerImpl.java
index 92163ea..f826ae9 100755
--- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalManagerImpl.java
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalManagerImpl.java
@@ -29,6 +29,7 @@ import javax.naming.ConfigurationException;
 import com.cloud.utils.db.QueryBuilder;
 import com.cloud.utils.db.SearchCriteria;
 import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.fsm.StateMachine2;
 import com.cloud.vm.VMInstanceVO;
 import com.cloud.vm.dao.VMInstanceDao;
 import org.apache.cloudstack.api.BaremetalProvisionDoneNotificationCmd;
@@ -81,37 +82,39 @@ public class BaremetalManagerImpl extends ManagerBase implements BaremetalManage
     }
 
     @Override
-    public boolean postStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vo, boolean status, Object opaque) {
-        if (newState != State.Starting && newState != State.Error && newState != State.Expunging) {
-            return true;
-        }
-
-        if (vo.getHypervisorType() != HypervisorType.BareMetal) {
-            return true;
-        }
+    public boolean postStateTransitionEvent(StateMachine2.Transition<State, Event> transition, VirtualMachine vo, boolean status, Object opaque) {
+      State newState = transition.getToState();
+      State oldState = transition.getCurrentState();
+      if (newState != State.Starting && newState != State.Error && newState != State.Expunging) {
+        return true;
+      }
 
-        HostVO host = _hostDao.findById(vo.getHostId());
-        if (host == null) {
-            s_logger.debug("Skip oldState " + oldState + " to " + "newState " + newState + " transimtion");
-            return true;
-        }
-        _hostDao.loadDetails(host);
+      if (vo.getHypervisorType() != HypervisorType.BareMetal) {
+        return true;
+      }
 
-        if (newState == State.Starting) {
-            host.setDetail("vmName", vo.getInstanceName());
-            s_logger.debug("Add vmName " + host.getDetail("vmName") + " to host " + host.getId() + " details");
-        } else {
-            if (host.getDetail("vmName") != null && host.getDetail("vmName").equalsIgnoreCase(vo.getInstanceName())) {
-                s_logger.debug("Remove vmName " + host.getDetail("vmName") + " from host " + host.getId() + " details");
-                host.getDetails().remove("vmName");
-            }
+      HostVO host = _hostDao.findById(vo.getHostId());
+      if (host == null) {
+        s_logger.debug("Skip oldState " + oldState + " to " + "newState " + newState + " transimtion");
+        return true;
+      }
+      _hostDao.loadDetails(host);
+
+      if (newState == State.Starting) {
+        host.setDetail("vmName", vo.getInstanceName());
+        s_logger.debug("Add vmName " + host.getDetail("vmName") + " to host " + host.getId() + " details");
+      } else {
+        if (host.getDetail("vmName") != null && host.getDetail("vmName").equalsIgnoreCase(vo.getInstanceName())) {
+          s_logger.debug("Remove vmName " + host.getDetail("vmName") + " from host " + host.getId() + " details");
+          host.getDetails().remove("vmName");
         }
-        _hostDao.saveDetails(host);
+      }
+      _hostDao.saveDetails(host);
 
-        return true;
+      return true;
     }
 
-    @Override
+  @Override
     public List<Class<?>> getCommands() {
         List<Class<?>> cmds = new ArrayList<Class<?>>();
         cmds.add(AddBaremetalHostCmd.class);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/50185b7c/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
index c998e3b..04d21fd 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
@@ -36,6 +36,7 @@ import com.cloud.network.vpc.dao.VpcDao;
 import com.cloud.network.vpc.VpcManager;
 import com.cloud.network.vpc.VpcVO;
 import com.cloud.network.vpc.dao.NetworkACLDao;
+import com.cloud.utils.fsm.StateMachine2;
 import com.cloud.vm.VMInstanceVO;
 import com.cloud.vm.dao.VMInstanceDao;
 import com.cloud.vm.Nic;
@@ -680,25 +681,26 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
     }
 
     @Override
-    public boolean postStateTransitionEvent(VirtualMachine.State oldState, VirtualMachine.Event event,
-                                            VirtualMachine.State newState, VirtualMachine vm,
-                                            boolean status, Object opaque) {
-        if (!status) {
-            return false;
-        }
-
-        if (VirtualMachine.State.isVmStarted(oldState, event, newState)) {
-            handleVmStateChange((VMInstanceVO)vm);
-        } else if (VirtualMachine.State.isVmStopped(oldState, event, newState)) {
-            handleVmStateChange((VMInstanceVO)vm);
-        } else if (VirtualMachine.State.isVmMigrated(oldState, event, newState)) {
-            handleVmStateChange((VMInstanceVO)vm);
-        }
-
-        return true;
+    public boolean postStateTransitionEvent(StateMachine2.Transition<VirtualMachine.State, VirtualMachine.Event> transition, VirtualMachine vm, boolean status, Object opaque) {
+      if (!status) {
+        return false;
+      }
+
+      VirtualMachine.State oldState = transition.getCurrentState();
+      VirtualMachine.State newState = transition.getToState();
+      VirtualMachine.Event event = transition.getEvent();
+      if (VirtualMachine.State.isVmStarted(oldState, event, newState)) {
+        handleVmStateChange((VMInstanceVO)vm);
+      } else if (VirtualMachine.State.isVmStopped(oldState, event, newState)) {
+        handleVmStateChange((VMInstanceVO)vm);
+      } else if (VirtualMachine.State.isVmMigrated(oldState, event, newState)) {
+        handleVmStateChange((VMInstanceVO)vm);
+      }
+
+      return true;
     }
 
-    private void handleVmStateChange(VMInstanceVO vm) {
+  private void handleVmStateChange(VMInstanceVO vm) {
 
         // get the VPC's impacted with the VM start
         List<Long> vpcIds = _ovsNetworkToplogyGuru.getVpcIdsVmIsPartOf(vm.getId());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/50185b7c/server/src/com/cloud/capacity/CapacityManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/capacity/CapacityManagerImpl.java b/server/src/com/cloud/capacity/CapacityManagerImpl.java
index e5b7d19..6866444 100755
--- a/server/src/com/cloud/capacity/CapacityManagerImpl.java
+++ b/server/src/com/cloud/capacity/CapacityManagerImpl.java
@@ -27,6 +27,7 @@ import javax.ejb.Local;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
+import com.cloud.utils.fsm.StateMachine2;
 import org.apache.log4j.Logger;
 
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
@@ -770,79 +771,82 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager,
     }
 
     @Override
-    public boolean postStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vm, boolean status, Object opaque) {
-        if (!status) {
-            return false;
+    public boolean postStateTransitionEvent(StateMachine2.Transition<State, Event> transition, VirtualMachine vm, boolean status, Object opaque) {
+      if (!status) {
+        return false;
+      }
+      @SuppressWarnings("unchecked")
+      Pair<Long, Long> hosts = (Pair<Long, Long>)opaque;
+      Long oldHostId = hosts.first();
+
+      State oldState = transition.getCurrentState();
+      State newState = transition.getToState();
+      Event event = transition.getEvent();
+      s_logger.debug("VM state transitted from :" + oldState + " to " + newState + " with event: " + event + "vm's original host id: " + vm.getLastHostId() +
+              " new host id: " + vm.getHostId() + " host id before state transition: " + oldHostId);
+
+      if (oldState == State.Starting) {
+        if (newState != State.Running) {
+          releaseVmCapacity(vm, false, false, oldHostId);
         }
-        @SuppressWarnings("unchecked")
-        Pair<Long, Long> hosts = (Pair<Long, Long>)opaque;
-        Long oldHostId = hosts.first();
-
-        s_logger.debug("VM state transitted from :" + oldState + " to " + newState + " with event: " + event + "vm's original host id: " + vm.getLastHostId() +
-            " new host id: " + vm.getHostId() + " host id before state transition: " + oldHostId);
-
-        if (oldState == State.Starting) {
-            if (newState != State.Running) {
-                releaseVmCapacity(vm, false, false, oldHostId);
-            }
-        } else if (oldState == State.Running) {
-            if (event == Event.AgentReportStopped) {
-                releaseVmCapacity(vm, false, true, oldHostId);
-            } else if (event == Event.AgentReportMigrated) {
-                releaseVmCapacity(vm, false, false, oldHostId);
-            }
-        } else if (oldState == State.Migrating) {
-            if (event == Event.AgentReportStopped) {
+      } else if (oldState == State.Running) {
+        if (event == Event.AgentReportStopped) {
+          releaseVmCapacity(vm, false, true, oldHostId);
+        } else if (event == Event.AgentReportMigrated) {
+          releaseVmCapacity(vm, false, false, oldHostId);
+        }
+      } else if (oldState == State.Migrating) {
+        if (event == Event.AgentReportStopped) {
                 /* Release capacity from original host */
-                releaseVmCapacity(vm, false, false, vm.getLastHostId());
-                releaseVmCapacity(vm, false, false, oldHostId);
-            } else if (event == Event.OperationFailed) {
+          releaseVmCapacity(vm, false, false, vm.getLastHostId());
+          releaseVmCapacity(vm, false, false, oldHostId);
+        } else if (event == Event.OperationFailed) {
                 /* Release from dest host */
-                releaseVmCapacity(vm, false, false, oldHostId);
-            } else if (event == Event.OperationSucceeded) {
-                releaseVmCapacity(vm, false, false, vm.getLastHostId());
-            }
-        } else if (oldState == State.Stopping) {
-            if (event == Event.OperationSucceeded) {
-                releaseVmCapacity(vm, false, true, oldHostId);
-            } else if (event == Event.AgentReportStopped) {
-                releaseVmCapacity(vm, false, false, oldHostId);
-            } else if (event == Event.AgentReportMigrated) {
-                releaseVmCapacity(vm, false, false, oldHostId);
-            }
-        } else if (oldState == State.Stopped) {
-            if (event == Event.DestroyRequested || event == Event.ExpungeOperation) {
-                releaseVmCapacity(vm, true, false, vm.getLastHostId());
-            } else if (event == Event.AgentReportMigrated) {
-                releaseVmCapacity(vm, false, false, oldHostId);
-            }
+          releaseVmCapacity(vm, false, false, oldHostId);
+        } else if (event == Event.OperationSucceeded) {
+          releaseVmCapacity(vm, false, false, vm.getLastHostId());
+        }
+      } else if (oldState == State.Stopping) {
+        if (event == Event.OperationSucceeded) {
+          releaseVmCapacity(vm, false, true, oldHostId);
+        } else if (event == Event.AgentReportStopped) {
+          releaseVmCapacity(vm, false, false, oldHostId);
+        } else if (event == Event.AgentReportMigrated) {
+          releaseVmCapacity(vm, false, false, oldHostId);
+        }
+      } else if (oldState == State.Stopped) {
+        if (event == Event.DestroyRequested || event == Event.ExpungeOperation) {
+          releaseVmCapacity(vm, true, false, vm.getLastHostId());
+        } else if (event == Event.AgentReportMigrated) {
+          releaseVmCapacity(vm, false, false, oldHostId);
         }
+      }
 
-        if ((newState == State.Starting || newState == State.Migrating || event == Event.AgentReportMigrated) && vm.getHostId() != null) {
-            boolean fromLastHost = false;
-            if (vm.getHostId().equals(vm.getLastHostId())) {
-                s_logger.debug("VM starting again on the last host it was stopped on");
-                fromLastHost = true;
-            }
-            allocateVmCapacity(vm, fromLastHost);
+      if ((newState == State.Starting || newState == State.Migrating || event == Event.AgentReportMigrated) && vm.getHostId() != null) {
+        boolean fromLastHost = false;
+        if (vm.getHostId().equals(vm.getLastHostId())) {
+          s_logger.debug("VM starting again on the last host it was stopped on");
+          fromLastHost = true;
         }
+        allocateVmCapacity(vm, fromLastHost);
+      }
 
-        if (newState == State.Stopped) {
-            if (vm.getType() == VirtualMachine.Type.User) {
+      if (newState == State.Stopped) {
+        if (vm.getType() == VirtualMachine.Type.User) {
 
-                UserVmVO userVM = _userVMDao.findById(vm.getId());
-                _userVMDao.loadDetails(userVM);
-                // free the message sent flag if it exists
-                userVM.setDetail(MESSAGE_RESERVED_CAPACITY_FREED_FLAG, "false");
-                _userVMDao.saveDetails(userVM);
+          UserVmVO userVM = _userVMDao.findById(vm.getId());
+          _userVMDao.loadDetails(userVM);
+          // free the message sent flag if it exists
+          userVM.setDetail(MESSAGE_RESERVED_CAPACITY_FREED_FLAG, "false");
+          _userVMDao.saveDetails(userVM);
 
-            }
         }
+      }
 
-        return true;
+      return true;
     }
 
-    // TODO: Get rid of this case once we've determined that the capacity listeners above have all the changes
+  // TODO: Get rid of this case once we've determined that the capacity listeners above have all the changes
     // create capacity entries if none exist for this server
     private void createCapacityEntry(StartupCommand startup, HostVO server) {
         SearchCriteria<CapacityVO> capacitySC = _capacityDao.createSearchCriteria();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/50185b7c/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java
index a40a7d7..bfb33b0 100755
--- a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java
+++ b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java
@@ -31,6 +31,7 @@ import javax.ejb.Local;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
+import com.cloud.utils.fsm.StateMachine2;
 import org.apache.log4j.Logger;
 
 import org.apache.cloudstack.affinity.AffinityGroupProcessor;
@@ -1443,16 +1444,18 @@ StateListener<State, VirtualMachine.Event, VirtualMachine> {
     }
 
     @Override
-    public boolean postStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vo, boolean status, Object opaque) {
-        if (!status) {
-            return false;
-        }
-        if ((oldState == State.Starting) && (newState != State.Starting)) {
-            // cleanup all VM reservation entries
-            SearchCriteria<VMReservationVO> sc = _reservationDao.createSearchCriteria();
-            sc.addAnd("vmId", SearchCriteria.Op.EQ, vo.getId());
-            _reservationDao.expunge(sc);
-        }
-        return true;
+    public boolean postStateTransitionEvent(StateMachine2.Transition<State, Event> transition, VirtualMachine vo, boolean status, Object opaque) {
+      if (!status) {
+        return false;
+      }
+      State oldState = transition.getCurrentState();
+      State newState = transition.getToState();
+      if ((oldState == State.Starting) && (newState != State.Starting)) {
+        // cleanup all VM reservation entries
+        SearchCriteria<VMReservationVO> sc = _reservationDao.createSearchCriteria();
+        sc.addAnd("vmId", SearchCriteria.Op.EQ, vo.getId());
+        _reservationDao.expunge(sc);
+      }
+      return true;
     }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/50185b7c/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
index 968c538..7d1dfa4 100755
--- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
+++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
@@ -218,6 +218,7 @@ import com.cloud.utils.db.TransactionCallbackNoReturn;
 import com.cloud.utils.db.TransactionStatus;
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.utils.fsm.StateListener;
+import com.cloud.utils.fsm.StateMachine2;
 import com.cloud.utils.net.Ip;
 import com.cloud.utils.net.MacAddress;
 import com.cloud.utils.net.NetUtils;
@@ -4432,17 +4433,20 @@ VirtualMachineGuru, Listener, Configurable, StateListener<State, VirtualMachine.
     }
 
     @Override
-    public boolean postStateTransitionEvent(State oldState, VirtualMachine.Event event, State newState, VirtualMachine vo, boolean status, Object opaque) {
-        if (oldState == State.Stopped && event == VirtualMachine.Event.FollowAgentPowerOnReport && newState == State.Running) {
-            if (vo.getType() == VirtualMachine.Type.DomainRouter) {
-                s_logger.info("Schedule a router reboot task as router " + vo.getId() + " is powered-on out-of-band. we need to reboot to refresh network rules");
-                _executor.schedule(new RebootTask(vo.getId()), 1000, TimeUnit.MICROSECONDS);
-            }
-        }
-        return true;
+    public boolean postStateTransitionEvent(StateMachine2.Transition<State, VirtualMachine.Event> transition, VirtualMachine vo, boolean status, Object opaque) {
+      State oldState = transition.getCurrentState();
+      State newState = transition.getToState();
+      VirtualMachine.Event event = transition.getEvent();
+      if (oldState == State.Stopped && event == VirtualMachine.Event.FollowAgentPowerOnReport && newState == State.Running) {
+        if (vo.getType() == VirtualMachine.Type.DomainRouter) {
+          s_logger.info("Schedule a router reboot task as router " + vo.getId() + " is powered-on out-of-band. we need to reboot to refresh network rules");
+          _executor.schedule(new RebootTask(vo.getId()), 1000, TimeUnit.MICROSECONDS);
+        }
+      }
+      return true;
     }
 
-    protected class RebootTask extends ManagedContextRunnable {
+  protected class RebootTask extends ManagedContextRunnable {
 
         long _routerId;
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/50185b7c/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java b/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java
index f60a746..cffdf8f 100755
--- a/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java
+++ b/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java
@@ -40,6 +40,7 @@ import javax.ejb.Local;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
+import com.cloud.utils.fsm.StateMachine2;
 import org.apache.commons.codec.digest.DigestUtils;
 import org.apache.log4j.Logger;
 
@@ -1279,32 +1280,35 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro
     }
 
     @Override
-    public boolean postStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vm, boolean status, Object opaque) {
-        if (!status) {
-            return false;
-        }
+    public boolean postStateTransitionEvent(StateMachine2.Transition<State, Event> transition, VirtualMachine vm, boolean status, Object opaque) {
+      if (!status) {
+        return false;
+      }
 
-        if (VirtualMachine.State.isVmStarted(oldState, event, newState)) {
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("Security Group Mgr: handling start of vm id" + vm.getId());
-            }
-            handleVmStarted((VMInstanceVO)vm);
-        } else if (VirtualMachine.State.isVmStopped(oldState, event, newState)) {
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("Security Group Mgr: handling stop of vm id" + vm.getId());
-            }
-            handleVmStopped((VMInstanceVO)vm);
-        } else if (VirtualMachine.State.isVmMigrated(oldState, event, newState)) {
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("Security Group Mgr: handling migration of vm id" + vm.getId());
-            }
-            handleVmMigrated((VMInstanceVO)vm);
+      State oldState = transition.getCurrentState();
+      State newState = transition.getToState();
+      Event event = transition.getEvent();
+      if (VirtualMachine.State.isVmStarted(oldState, event, newState)) {
+        if (s_logger.isTraceEnabled()) {
+          s_logger.trace("Security Group Mgr: handling start of vm id" + vm.getId());
+        }
+        handleVmStarted((VMInstanceVO)vm);
+      } else if (VirtualMachine.State.isVmStopped(oldState, event, newState)) {
+        if (s_logger.isTraceEnabled()) {
+          s_logger.trace("Security Group Mgr: handling stop of vm id" + vm.getId());
         }
+        handleVmStopped((VMInstanceVO)vm);
+      } else if (VirtualMachine.State.isVmMigrated(oldState, event, newState)) {
+        if (s_logger.isTraceEnabled()) {
+          s_logger.trace("Security Group Mgr: handling migration of vm id" + vm.getId());
+        }
+        handleVmMigrated((VMInstanceVO)vm);
+      }
 
-        return true;
+      return true;
     }
 
-    @Override
+  @Override
     public boolean isVmSecurityGroupEnabled(Long vmId) {
         VirtualMachine vm = _vmDao.findByIdIncludingRemoved(vmId);
         List<NicProfile> nics = _networkMgr.getNicProfiles(vm);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/50185b7c/server/src/com/cloud/storage/listener/SnapshotStateListener.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/listener/SnapshotStateListener.java b/server/src/com/cloud/storage/listener/SnapshotStateListener.java
index 8da71a6..f4decf6 100644
--- a/server/src/com/cloud/storage/listener/SnapshotStateListener.java
+++ b/server/src/com/cloud/storage/listener/SnapshotStateListener.java
@@ -26,6 +26,7 @@ import javax.annotation.PostConstruct;
 import javax.ejb.Local;
 import javax.inject.Inject;
 
+import com.cloud.utils.fsm.StateMachine2;
 import org.apache.log4j.Logger;
 import org.springframework.beans.factory.NoSuchBeanDefinitionException;
 import org.springframework.stereotype.Component;
@@ -72,12 +73,12 @@ public class SnapshotStateListener implements StateListener<State, Event, Snapsh
     }
 
     @Override
-    public boolean postStateTransitionEvent(State oldState, Event event, State newState, SnapshotVO vo, boolean status, Object opaque) {
-        pubishOnEventBus(event.name(), "postStateTransitionEvent", vo, oldState, newState);
-        return true;
+    public boolean postStateTransitionEvent(StateMachine2.Transition<State, Event> transition, SnapshotVO vo, boolean status, Object opaque) {
+      pubishOnEventBus(transition.getEvent().name(), "postStateTransitionEvent", vo, transition.getCurrentState(), transition.getToState());
+      return true;
     }
 
-    private void pubishOnEventBus(String event, String status, Snapshot vo, State oldState, State newState) {
+  private void pubishOnEventBus(String event, String status, Snapshot vo, State oldState, State newState) {
 
         String configKey = Config.PublishResourceStateEvent.key();
         String value = s_configDao.getValue(configKey);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/50185b7c/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 1911a48..0ba2969 100644
--- a/server/src/com/cloud/storage/listener/VolumeStateListener.java
+++ b/server/src/com/cloud/storage/listener/VolumeStateListener.java
@@ -22,6 +22,7 @@ import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
 
+import com.cloud.utils.fsm.StateMachine2;
 import org.apache.log4j.Logger;
 import org.springframework.beans.factory.NoSuchBeanDefinitionException;
 
@@ -56,12 +57,12 @@ public class VolumeStateListener implements StateListener<State, Event, Volume>
     }
 
     @Override
-    public boolean postStateTransitionEvent(State oldState, Event event, State newState, Volume vo, boolean status, Object opaque) {
-        pubishOnEventBus(event.name(), "postStateTransitionEvent", vo, oldState, newState);
-        return true;
+    public boolean postStateTransitionEvent(StateMachine2.Transition<State, Event> transition, Volume vo, boolean status, Object opaque) {
+      pubishOnEventBus(transition.getEvent().name(), "postStateTransitionEvent", vo, transition.getCurrentState(), transition.getToState());
+      return true;
     }
 
-    private void pubishOnEventBus(String event, String status, Volume vo, State oldState, State newState) {
+  private void pubishOnEventBus(String event, String status, Volume vo, State oldState, State newState) {
 
         String configKey = Config.PublishResourceStateEvent.key();
         String value = _configDao.getValue(configKey);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/50185b7c/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 a0088b8..e4df6bb 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.utils.fsm.StateMachine2;
 import com.cloud.vm.dao.UserVmDao;
 import org.apache.log4j.Logger;
 import org.springframework.beans.factory.NoSuchBeanDefinitionException;
@@ -77,36 +78,40 @@ public class UserVmStateListener implements StateListener<State, VirtualMachine.
     }
 
     @Override
-    public boolean postStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vo, boolean status, Object opaque) {
-        if (!status) {
-            return false;
-        }
-
-        pubishOnEventBus(event.name(), "postStateTransitionEvent", vo, oldState, newState);
-
-        if (vo.getType() != VirtualMachine.Type.User) {
-            return true;
-        }
-
-        if (VirtualMachine.State.isVmCreated(oldState, event, newState)) {
-            generateUsageEvent(vo.getServiceOfferingId(), vo, EventTypes.EVENT_VM_CREATE);
-        } else if (VirtualMachine.State.isVmStarted(oldState, event, newState)) {
-            generateUsageEvent(vo.getServiceOfferingId(), vo, EventTypes.EVENT_VM_START);
-        } else if (VirtualMachine.State.isVmStopped(oldState, event, newState)) {
-            generateUsageEvent(vo.getServiceOfferingId(), vo, EventTypes.EVENT_VM_STOP);
-            List<NicVO> nics = _nicDao.listByVmId(vo.getId());
-            for (NicVO nic : nics) {
-                NetworkVO network = _networkDao.findById(nic.getNetworkId());
-                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_REMOVE, vo.getAccountId(), vo.getDataCenterId(), vo.getId(),
+    public boolean postStateTransitionEvent(StateMachine2.Transition<State, Event> transition, VirtualMachine vo, boolean status, Object opaque) {
+      if (!status) {
+        return false;
+      }
+      Event event = transition.getEvent();
+      State oldState = transition.getCurrentState();
+      State newState = transition.getToState();
+      pubishOnEventBus(event.name(), "postStateTransitionEvent", vo, oldState, newState);
+
+      if (vo.getType() != VirtualMachine.Type.User) {
+        return true;
+      }
+
+      if(transition.isImpacted(StateMachine2.Transition.Impact.USAGE)) {
+        if (oldState == State.Destroyed && newState == State.Stopped) {
+          generateUsageEvent(vo.getServiceOfferingId(), vo, EventTypes.EVENT_VM_CREATE);
+        } else if (newState == State.Running) {
+          generateUsageEvent(vo.getServiceOfferingId(), vo, EventTypes.EVENT_VM_START);
+        } else if (newState == State.Stopped) {
+          generateUsageEvent(vo.getServiceOfferingId(), vo, EventTypes.EVENT_VM_STOP);
+          List<NicVO> nics = _nicDao.listByVmId(vo.getId());
+          for (NicVO nic : nics) {
+            NetworkVO network = _networkDao.findById(nic.getNetworkId());
+            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_REMOVE, vo.getAccountId(), vo.getDataCenterId(), vo.getId(),
                     Long.toString(nic.getId()), network.getNetworkOfferingId(), null, 0L, vo.getClass().getName(), vo.getUuid(), vo.isDisplay());
-            }
-        } else if (VirtualMachine.State.isVmDestroyed(oldState, event, newState)) {
-            generateUsageEvent(vo.getServiceOfferingId(), vo, EventTypes.EVENT_VM_DESTROY);
+          }
+        } else if (newState == State.Destroyed || newState == State.Error || newState == State.Expunging) {
+          generateUsageEvent(vo.getServiceOfferingId(), vo, EventTypes.EVENT_VM_DESTROY);
         }
-        return true;
+      }
+      return true;
     }
 
-    private void generateUsageEvent(Long serviceOfferingId, VirtualMachine vm,  String eventType){
+  private void generateUsageEvent(Long serviceOfferingId, VirtualMachine vm,  String eventType){
         boolean displayVm = true;
         if(vm.getType() == VirtualMachine.Type.User){
             UserVmVO uservm = _userVmDao.findById(vm.getId());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/50185b7c/server/src/org/apache/cloudstack/affinity/AffinityGroupServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/org/apache/cloudstack/affinity/AffinityGroupServiceImpl.java b/server/src/org/apache/cloudstack/affinity/AffinityGroupServiceImpl.java
index 592ebd6..b984b97 100644
--- a/server/src/org/apache/cloudstack/affinity/AffinityGroupServiceImpl.java
+++ b/server/src/org/apache/cloudstack/affinity/AffinityGroupServiceImpl.java
@@ -26,6 +26,7 @@ import javax.ejb.Local;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
+import com.cloud.utils.fsm.StateMachine2;
 import org.apache.log4j.Logger;
 
 import org.apache.cloudstack.acl.ControlledEntity;
@@ -439,20 +440,21 @@ public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGro
     }
 
     @Override
-    public boolean postStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vo, boolean status, Object opaque) {
-        if (!status) {
-            return false;
-        }
-        if ((newState == State.Expunging) || (newState == State.Error)) {
-            // cleanup all affinity groups associations of the Expunged VM
-            SearchCriteria<AffinityGroupVMMapVO> sc = _affinityGroupVMMapDao.createSearchCriteria();
-            sc.addAnd("instanceId", SearchCriteria.Op.EQ, vo.getId());
-            _affinityGroupVMMapDao.expunge(sc);
-        }
-        return true;
+    public boolean postStateTransitionEvent(StateMachine2.Transition<State, Event> transition, VirtualMachine vo, boolean status, Object opaque) {
+      if (!status) {
+        return false;
+      }
+      State newState = transition.getToState();
+      if ((newState == State.Expunging) || (newState == State.Error)) {
+        // cleanup all affinity groups associations of the Expunged VM
+        SearchCriteria<AffinityGroupVMMapVO> sc = _affinityGroupVMMapDao.createSearchCriteria();
+        sc.addAnd("instanceId", SearchCriteria.Op.EQ, vo.getId());
+        _affinityGroupVMMapDao.expunge(sc);
+      }
+      return true;
     }
 
-    @Override
+  @Override
     public UserVm updateVMAffinityGroups(Long vmId, List<Long> affinityGroupIds) {
         // Verify input parameters
         UserVmVO vmInstance = _userVmDao.findById(vmId);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/50185b7c/utils/src/com/cloud/utils/fsm/StateListener.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/fsm/StateListener.java b/utils/src/com/cloud/utils/fsm/StateListener.java
index 3d0a645..96e8be9 100644
--- a/utils/src/com/cloud/utils/fsm/StateListener.java
+++ b/utils/src/com/cloud/utils/fsm/StateListener.java
@@ -28,19 +28,16 @@ public interface StateListener<S, E, V> {
      * @param newState VM's new state
      * @param vo the VM instance
      * @param opaque host id
-     * @param vmDao VM dao
      * @return
      */
     public boolean preStateTransitionEvent(S oldState, E event, S newState, V vo, boolean status, Object opaque);
 
     /**
-     * Event is triggered after state machine transition finished
-     * @param oldState VM's old state
-     * @param event that triggered this VM state change
-     * @param newState VM's new state
-     * @param vo the VM instance
-     * @param status the state transition is allowed or not
-     * @return
-     */
-    public boolean postStateTransitionEvent(S oldState, E event, S newState, V vo, boolean status, Object opaque);
+    * Event is triggered after state machine transition finished
+    * @param transition The Transition fo the Event
+    * @param vo the VM instance
+    * @param status the state transition is allowed or not
+    * @return
+    */
+    public boolean postStateTransitionEvent(StateMachine2.Transition<S, E> transition, V vo, boolean status, Object opaque);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/50185b7c/utils/src/com/cloud/utils/fsm/StateMachine2.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/fsm/StateMachine2.java b/utils/src/com/cloud/utils/fsm/StateMachine2.java
index 4950a25cb..431d961 100644
--- a/utils/src/com/cloud/utils/fsm/StateMachine2.java
+++ b/utils/src/com/cloud/utils/fsm/StateMachine2.java
@@ -46,25 +46,33 @@ public class StateMachine2<S, E, V extends StateObject<S>> {
     }
 
     public void addTransition(S currentState, E event, S toState) {
-        StateEntry entry = null;
-        if (currentState == null) {
-            entry = _initialStateEntry;
-        } else {
-            entry = _states.get(currentState);
-            if (entry == null) {
-                entry = new StateEntry(currentState);
-                _states.put(currentState, entry);
-            }
-        }
+      addTransition(new Transition<S, E>(currentState, event, toState, null));
+    }
 
-        entry.addTransition(event, toState);
 
-        entry = _states.get(toState);
+    public void addTransition(Transition<S, E> transition) {
+      S currentState = transition.getCurrentState();
+      E event = transition.getEvent();
+      S toState = transition.getToState();
+      StateEntry entry = null;
+      if (currentState == null) {
+        entry = _initialStateEntry;
+      } else {
+        entry = _states.get(currentState);
         if (entry == null) {
-            entry = new StateEntry(toState);
-            _states.put(toState, entry);
+          entry = new StateEntry(currentState);
+          _states.put(currentState, entry);
         }
-        entry.addFromTransition(event, currentState);
+      }
+
+      entry.addTransition(event, toState, transition);
+
+      entry = _states.get(toState);
+      if (entry == null) {
+        entry = new StateEntry(toState);
+        _states.put(toState, entry);
+      }
+      entry.addFromTransition(event, currentState);
     }
 
     public Set<E> getPossibleEvents(S s) {
@@ -73,19 +81,23 @@ public class StateMachine2<S, E, V extends StateObject<S>> {
     }
 
     public S getNextState(S s, E e) throws NoTransitionException {
-        StateEntry entry = null;
-        if (s == null) {
-            entry = _initialStateEntry;
-        } else {
-            entry = _states.get(s);
-            assert entry != null : "Cannot retrieve transitions for state " + s;
-        }
+        return getTransition(s, e).getToState();
+    }
 
-        S ns = entry.nextStates.get(e);
-        if (ns == null) {
-            throw new NoTransitionException("Unable to transition to a new state from " + s + " via " + e);
-        }
-        return ns;
+    public Transition<S, E> getTransition(S s, E e) throws NoTransitionException {
+      StateEntry entry = null;
+      if (s == null) {
+        entry = _initialStateEntry;
+      } else {
+        entry = _states.get(s);
+        assert entry != null : "Cannot retrieve transitions for state " + s;
+      }
+
+      Transition<S, E> transition = entry.nextStates.get(e);
+      if (transition == null) {
+        throw new NoTransitionException("Unable to transition to a new state from " + s + " via " + e);
+      }
+      return transition;
     }
 
     public List<S> getFromStates(S s, E e) {
@@ -100,6 +112,7 @@ public class StateMachine2<S, E, V extends StateObject<S>> {
     public boolean transitTo(V vo, E e, Object opaque, StateDao<S, E, V> dao) throws NoTransitionException {
         S currentState = vo.getState();
         S nextState = getNextState(currentState, e);
+        Transition<S, E> transition = getTransition(currentState, e);
 
         boolean transitionStatus = true;
         if (nextState == null) {
@@ -116,7 +129,7 @@ public class StateMachine2<S, E, V extends StateObject<S>> {
         }
 
         for (StateListener<S, E, V> listener : _listeners) {
-            listener.postStateTransitionEvent(currentState, e, nextState, vo, transitionStatus, opaque);
+            listener.postStateTransitionEvent(transition, vo, transitionStatus, opaque);
         }
 
         return true;
@@ -138,21 +151,84 @@ public class StateMachine2<S, E, V extends StateObject<S>> {
         return str.toString();
     }
 
+    public static class Transition<S, E> {
+
+      private S currentState;
+
+      private E event;
+
+      private S toState;
+
+      private List<Impact> impacts;
+
+      public static enum Impact {
+        USAGE
+      }
+
+      public Transition(S currentState, E event, S toState, List<Impact> impacts) {
+        this.currentState = currentState;
+        this.event = event;
+        this.toState = toState;
+        this.impacts = impacts;
+      }
+
+      public S getCurrentState() {
+        return currentState;
+      }
+
+      public E getEvent() {
+        return event;
+      }
+
+      public S getToState() {
+        return toState;
+      }
+
+      public boolean isImpacted(Impact impact) {
+        if (impacts == null || impacts.isEmpty()) {
+          return false;
+        }
+        return impacts.contains(impact);
+      }
+
+      @Override
+      public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        Transition that = (Transition) o;
+
+        if (currentState != null ? !currentState.equals(that.currentState) : that.currentState != null) return false;
+        if (event != null ? !event.equals(that.event) : that.event != null) return false;
+        if (toState != null ? !toState.equals(that.toState) : that.toState != null) return false;
+
+        return true;
+      }
+
+      @Override
+      public int hashCode() {
+        int result = currentState != null ? currentState.hashCode() : 0;
+        result = 31 * result + (event != null ? event.hashCode() : 0);
+        result = 31 * result + (toState != null ? toState.hashCode() : 0);
+        return result;
+      }
+    }
+
     private class StateEntry {
         public S state;
-        public HashMap<E, S> nextStates;
+        public HashMap<E, Transition<S, E>> nextStates;
         public HashMap<E, List<S>> prevStates;
 
         public StateEntry(S state) {
             this.state = state;
-            nextStates = new HashMap<E, S>();
             prevStates = new HashMap<E, List<S>>();
+            nextStates = new HashMap<E, Transition<S, E>>();
         }
 
-        public void addTransition(E e, S s) {
+        public void addTransition(E e, S s, Transition<S, E> transition) {
             assert !nextStates.containsKey(e) : "State " + getStateStr() + " already contains a transition to state " + nextStates.get(e).toString() + " via event " +
                 e.toString() + ".  Please revisit the rule you're adding to state " + s.toString();
-            nextStates.put(e, s);
+            nextStates.put(e, transition);
         }
 
         public void addFromTransition(E e, S s) {
@@ -172,7 +248,7 @@ public class StateMachine2<S, E, V extends StateObject<S>> {
 
         public void buildString(StringBuilder str) {
             str.append("State: ").append(getStateStr()).append("\n");
-            for (Map.Entry<E, S> nextState : nextStates.entrySet()) {
+            for (Map.Entry<E, Transition<S, E>> nextState : nextStates.entrySet()) {
                 str.append("  --> Event: ");
                 Formatter format = new Formatter();
                 str.append(format.format("%-30s", nextState.getKey().toString()));


Mime
View raw message