You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ki...@apache.org on 2013/02/01 07:11:33 UTC

[38/48] Merging events framework branch into master. This commit will bring following changes

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/e7a554fc/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java b/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java
index 65e2f5f..3fe1aba 100644
--- a/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java
+++ b/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java
@@ -16,33 +16,27 @@
 // under the License.
 package com.cloud.storage.dao;
 
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.util.List;
-
-import javax.ejb.Local;
-
-import org.apache.log4j.Logger;
-
 import com.cloud.server.ResourceTag.TaggedResourceType;
 import com.cloud.storage.Snapshot;
+import com.cloud.storage.Snapshot.Event;
+import com.cloud.storage.Snapshot.State;
 import com.cloud.storage.Snapshot.Type;
 import com.cloud.storage.SnapshotVO;
 import com.cloud.storage.Volume;
 import com.cloud.storage.VolumeVO;
 import com.cloud.tags.dao.ResourceTagsDaoImpl;
 import com.cloud.utils.component.ComponentLocator;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.GenericSearchBuilder;
+import com.cloud.utils.db.*;
 import com.cloud.utils.db.JoinBuilder.JoinType;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
 import com.cloud.utils.db.SearchCriteria.Func;
-import com.cloud.utils.db.Transaction;
 import com.cloud.vm.VMInstanceVO;
 import com.cloud.vm.dao.VMInstanceDaoImpl;
+import org.apache.log4j.Logger;
+
+import javax.ejb.Local;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.List;
 
 @Local (value={SnapshotDao.class})
 public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements SnapshotDao {
@@ -113,7 +107,7 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements
     public List<SnapshotVO> listByHostId(Filter filter, long hostId ) {
         SearchCriteria<SnapshotVO> sc = HostIdSearch.create();
         sc.setParameters("hostId", hostId);
-        sc.setParameters("status", Snapshot.Status.BackedUp);
+        sc.setParameters("status", Snapshot.State.BackedUp);
         return listBy(sc, filter);
     }
         
@@ -145,7 +139,7 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements
         
         HostIdSearch = createSearchBuilder();
         HostIdSearch.and("hostId", HostIdSearch.entity().getSecHostId(), SearchCriteria.Op.EQ);
-        HostIdSearch.and("status", HostIdSearch.entity().getStatus(), SearchCriteria.Op.EQ);
+        HostIdSearch.and("status", HostIdSearch.entity().getState(), SearchCriteria.Op.EQ);
         HostIdSearch.done();
         
         VolumeIdTypeSearch = createSearchBuilder();
@@ -172,7 +166,7 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements
         
         StatusSearch = createSearchBuilder();
         StatusSearch.and("volumeId", StatusSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
-        StatusSearch.and("status", StatusSearch.entity().getStatus(), SearchCriteria.Op.IN);
+        StatusSearch.and("status", StatusSearch.entity().getState(), SearchCriteria.Op.IN);
         StatusSearch.done();
         
         CountSnapshotsByAccount = createSearchBuilder(Long.class);
@@ -182,7 +176,7 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements
         CountSnapshotsByAccount.done();
         
     	InstanceIdSearch = createSearchBuilder();
-    	InstanceIdSearch.and("status", InstanceIdSearch.entity().getStatus(), SearchCriteria.Op.IN);
+        InstanceIdSearch.and("status", InstanceIdSearch.entity().getState(), SearchCriteria.Op.IN);
     	
     	SearchBuilder<VMInstanceVO> instanceSearch = _instanceDao.createSearchBuilder();
     	instanceSearch.and("instanceId", instanceSearch.entity().getId(), SearchCriteria.Op.EQ);
@@ -274,7 +268,7 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements
     }
     
     @Override
-	public List<SnapshotVO> listByInstanceId(long instanceId, Snapshot.Status... status) {
+	public List<SnapshotVO> listByInstanceId(long instanceId, Snapshot.State... status) {
     	SearchCriteria<SnapshotVO> sc = this.InstanceIdSearch.create();
     	
     	if (status != null && status.length != 0) {
@@ -287,7 +281,7 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements
     }
     
     @Override
-    public List<SnapshotVO> listByStatus(long volumeId, Snapshot.Status... status) {
+    public List<SnapshotVO> listByStatus(long volumeId, Snapshot.State... status) {
     	SearchCriteria<SnapshotVO> sc = this.StatusSearch.create();
     	sc.setParameters("volumeId", volumeId);
     	sc.setParameters("status", (Object[])status);
@@ -309,9 +303,20 @@ public class SnapshotDaoImpl extends GenericDaoBase<SnapshotVO, Long> implements
     }
     
     @Override
-    public List<SnapshotVO> listAllByStatus(Snapshot.Status... status) {
+    public List<SnapshotVO> listAllByStatus(Snapshot.State... status) {
         SearchCriteria<SnapshotVO> sc = this.StatusSearch.create();
         sc.setParameters("status", (Object[])status);
         return listBy(sc, null);
     }
+
+    @Override
+    public boolean updateState(State currentState, Event event, State nextState, Snapshot snapshot, Object data) {
+        Transaction txn = Transaction.currentTxn();
+        txn.start();
+        SnapshotVO snapshotVO = (SnapshotVO)snapshot;
+        snapshotVO.setStatus(nextState);
+        super.update(snapshotVO.getId(), snapshotVO);
+        txn.commit();
+        return true;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/e7a554fc/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
index 2736777..cf51567 100755
--- a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
+++ b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
@@ -16,36 +16,14 @@
 // under the License.
 package com.cloud.storage.download;
 
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Timer;
-import java.util.concurrent.ConcurrentHashMap;
-
-import javax.ejb.Local;
-
-import org.apache.log4j.Logger;
-
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.Listener;
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.Command;
-import com.cloud.agent.api.storage.DeleteTemplateCommand;
-import com.cloud.agent.api.storage.DeleteVolumeCommand;
-import com.cloud.agent.api.storage.DownloadCommand;
-import com.cloud.agent.api.storage.ListVolumeAnswer;
-import com.cloud.agent.api.storage.ListVolumeCommand;
+import com.cloud.agent.api.storage.*;
 import com.cloud.agent.api.storage.DownloadCommand.Proxy;
 import com.cloud.agent.api.storage.DownloadCommand.ResourceType;
-import com.cloud.agent.api.storage.DownloadProgressCommand;
 import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType;
-import com.cloud.agent.api.storage.ListTemplateAnswer;
-import com.cloud.agent.api.storage.ListTemplateCommand;
 import com.cloud.agent.manager.Commands;
 import com.cloud.alert.AlertManager;
 import com.cloud.configuration.Config;
@@ -54,8 +32,7 @@ import com.cloud.dc.DataCenterVO;
 import com.cloud.dc.dao.ClusterDao;
 import com.cloud.dc.dao.DataCenterDao;
 import com.cloud.event.EventTypes;
-import com.cloud.event.UsageEventVO;
-import com.cloud.event.dao.UsageEventDao;
+import com.cloud.event.UsageEventUtils;
 import com.cloud.exception.AgentUnavailableException;
 import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.exception.StorageUnavailableException;
@@ -65,26 +42,9 @@ import com.cloud.host.dao.HostDao;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
 import com.cloud.resource.ResourceManager;
 import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.StorageManager;
-import com.cloud.storage.SwiftVO;
-import com.cloud.storage.VMTemplateHostVO;
-import com.cloud.storage.VMTemplateStorageResourceAssoc;
-import com.cloud.storage.Volume;
-import com.cloud.storage.VolumeHostVO;
-import com.cloud.storage.VolumeVO;
+import com.cloud.storage.*;
 import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
-import com.cloud.storage.Volume.Event;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.VMTemplateZoneVO;
-import com.cloud.storage.dao.StoragePoolHostDao;
-import com.cloud.storage.dao.SwiftDao;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VMTemplateHostDao;
-import com.cloud.storage.dao.VMTemplatePoolDao;
-import com.cloud.storage.dao.VMTemplateSwiftDao;
-import com.cloud.storage.dao.VMTemplateZoneDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.dao.VolumeHostDao;
+import com.cloud.storage.dao.*;
 import com.cloud.storage.secondary.SecondaryStorageVmManager;
 import com.cloud.storage.swift.SwiftManager;
 import com.cloud.storage.template.TemplateConstants;
@@ -92,19 +52,21 @@ import com.cloud.storage.template.TemplateInfo;
 import com.cloud.user.Account;
 import com.cloud.user.ResourceLimitService;
 import com.cloud.utils.component.Inject;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.JoinBuilder;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.*;
 import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.fsm.NoTransitionException;
 import com.cloud.vm.SecondaryStorageVm;
 import com.cloud.vm.SecondaryStorageVmVO;
 import com.cloud.vm.UserVmManager;
 import com.cloud.vm.VirtualMachine.State;
 import com.cloud.vm.dao.SecondaryStorageVmDao;
 import edu.emory.mathcs.backport.java.util.Collections;
+import org.apache.log4j.Logger;
+
+import javax.ejb.Local;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
 
 
 @Local(value={DownloadMonitor.class})
@@ -147,11 +109,6 @@ public class DownloadMonitorImpl implements  DownloadMonitor {
     ConfigurationDao _configDao;
     @Inject
     UserVmManager _vmMgr;
-
-    
-    @Inject 
-    private UsageEventDao _usageEventDao;
-    
     @Inject
     private ClusterDao _clusterDao;
     @Inject
@@ -517,8 +474,9 @@ public class DownloadMonitorImpl implements  DownloadMonitor {
                 eventType = EventTypes.EVENT_ISO_CREATE;
             }
             if(template.getAccountId() != Account.ACCOUNT_ID_SYSTEM){
-                UsageEventVO usageEvent = new UsageEventVO(eventType, template.getAccountId(), host.getDataCenterId(), template.getId(), template.getName(), null, template.getSourceTemplateId() , size);
-                _usageEventDao.persist(usageEvent);
+                UsageEventUtils.publishUsageEvent(eventType, template.getAccountId(), host.getDataCenterId(),
+                        template.getId(), template.getName(), null, template.getSourceTemplateId(), size,
+                        template.getClass().getName(), template.getUuid());
             }
         }
         txn.commit();
@@ -550,8 +508,8 @@ public class DownloadMonitorImpl implements  DownloadMonitor {
             }
             String eventType = EventTypes.EVENT_VOLUME_UPLOAD;            
             if(volume.getAccountId() != Account.ACCOUNT_ID_SYSTEM){
-               UsageEventVO usageEvent = new UsageEventVO(eventType, volume.getAccountId(), host.getDataCenterId(), volume.getId(), volume.getName(), null, 0l , size);
-               _usageEventDao.persist(usageEvent);
+                UsageEventUtils.publishUsageEvent(eventType, volume.getAccountId(), host.getDataCenterId(),
+                        volume.getId(), volume.getName(), null, 0l, size, volume.getClass().getName(), volume.getUuid());
             }
         }else if (dnldStatus == Status.DOWNLOAD_ERROR || dnldStatus == Status.ABANDONED || dnldStatus == Status.UNKNOWN){
             //Decrement the volume count

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/e7a554fc/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
new file mode 100644
index 0000000..2b19887
--- /dev/null
+++ b/server/src/com/cloud/storage/listener/SnapshotStateListener.java
@@ -0,0 +1,85 @@
+package com.cloud.storage.listener;
+
+import com.cloud.event.EventCategory;
+import com.cloud.storage.Snapshot;
+import com.cloud.storage.Snapshot.Event;
+import com.cloud.storage.Snapshot.State;
+import com.cloud.server.ManagementServer;
+import com.cloud.utils.component.Adapters;
+import com.cloud.utils.component.ComponentLocator;
+import com.cloud.utils.fsm.StateListener;
+import org.apache.cloudstack.framework.events.EventBus;
+import org.apache.cloudstack.framework.events.EventBusException;
+import org.apache.log4j.Logger;
+
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+public class SnapshotStateListener implements StateListener<State, Event, Snapshot> {
+
+    // get the event bus provider if configured
+    protected static EventBus _eventBus = null;
+    static {
+        Adapters<EventBus> eventBusImpls = ComponentLocator.getLocator(ManagementServer.Name).getAdapters(EventBus.class);
+        if (eventBusImpls != null) {
+            Enumeration<EventBus> eventBusenum = eventBusImpls.enumeration();
+            if (eventBusenum != null && eventBusenum.hasMoreElements()) {
+                _eventBus = eventBusenum.nextElement(); // configure event bus if configured
+            }
+        }
+    }
+
+    private static final Logger s_logger = Logger.getLogger(VolumeStateListener.class);
+
+    public SnapshotStateListener() {
+
+    }
+
+    @Override
+    public boolean preStateTransitionEvent(State oldState, Event event, State newState, Snapshot vo, boolean status, Object opaque) {
+        pubishOnEventBus(event.name(), "preStateTransitionEvent", vo, oldState, newState);
+        return true;
+    }
+
+    @Override
+    public boolean postStateTransitionEvent(State oldState, Event event, State newState, Snapshot vo, boolean status, Object opaque) {
+        pubishOnEventBus(event.name(), "postStateTransitionEvent", vo, oldState, newState);
+        return true;
+    }
+
+    private void pubishOnEventBus(String event, String status, Snapshot vo, State oldState, State newState) {
+
+        if (_eventBus == null) {
+            return;  // no provider is configured to provide events bus, so just return
+        }
+
+        String resourceName = getEntityFromClassName(Snapshot.class.getName());
+        org.apache.cloudstack.framework.events.Event eventMsg =  new org.apache.cloudstack.framework.events.Event(
+                ManagementServer.Name,
+                EventCategory.RESOURCE_STATE_CHANGE_EVENT.getName(),
+                event,
+                resourceName,
+                vo.getUuid());
+        Map<String, String> eventDescription = new HashMap<String, String>();
+        eventDescription.put("resource", resourceName);
+        eventDescription.put("id", vo.getUuid());
+        eventDescription.put("old-state", oldState.name());
+        eventDescription.put("new-state", newState.name());
+        eventMsg.setDescription(eventDescription);
+        try {
+            _eventBus.publish(eventMsg);
+        } catch (EventBusException e) {
+            s_logger.warn("Failed to publish state change event on the the event bus.");
+        }
+    }
+
+    private String getEntityFromClassName(String entityClassName) {
+        int index = entityClassName.lastIndexOf(".");
+        String entityName = entityClassName;
+        if (index != -1) {
+            entityName = entityClassName.substring(index+1);
+        }
+        return entityName;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/e7a554fc/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
new file mode 100644
index 0000000..c460016
--- /dev/null
+++ b/server/src/com/cloud/storage/listener/VolumeStateListener.java
@@ -0,0 +1,85 @@
+package com.cloud.storage.listener;
+
+import com.cloud.event.EventCategory;
+import com.cloud.storage.Volume;
+import com.cloud.storage.Volume.Event;
+import com.cloud.storage.Volume.State;
+import com.cloud.server.ManagementServer;
+import com.cloud.utils.component.Adapters;
+import com.cloud.utils.component.ComponentLocator;
+import com.cloud.utils.fsm.StateListener;
+import org.apache.cloudstack.framework.events.EventBus;
+import org.apache.cloudstack.framework.events.EventBusException;
+import org.apache.log4j.Logger;
+
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+public class VolumeStateListener implements StateListener<State, Event, Volume> {
+
+    // get the event bus provider if configured
+    protected static EventBus _eventBus = null;
+    static {
+        Adapters<EventBus> eventBusImpls = ComponentLocator.getLocator(ManagementServer.Name).getAdapters(EventBus.class);
+        if (eventBusImpls != null) {
+            Enumeration<EventBus> eventBusenum = eventBusImpls.enumeration();
+            if (eventBusenum != null && eventBusenum.hasMoreElements()) {
+                _eventBus = eventBusenum.nextElement(); // configure event bus if configured
+            }
+        }
+    }
+
+    private static final Logger s_logger = Logger.getLogger(VolumeStateListener.class);
+
+    public VolumeStateListener() {
+
+    }
+
+    @Override
+    public boolean preStateTransitionEvent(State oldState, Event event, State newState, Volume vo, boolean status, Object opaque) {
+        pubishOnEventBus(event.name(), "preStateTransitionEvent", vo, oldState, newState);
+        return true;
+    }
+
+    @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;
+    }
+
+    private void pubishOnEventBus(String event, String status, Volume vo, State oldState, State newState) {
+
+        if (_eventBus == null) {
+            return;  // no provider is configured to provide events bus, so just return
+        }
+
+        String resourceName = getEntityFromClassName(Volume.class.getName());
+        org.apache.cloudstack.framework.events.Event eventMsg =  new org.apache.cloudstack.framework.events.Event(
+                ManagementServer.Name,
+                EventCategory.RESOURCE_STATE_CHANGE_EVENT.getName(),
+                event,
+                resourceName,
+                vo.getUuid());
+        Map<String, String> eventDescription = new HashMap<String, String>();
+        eventDescription.put("resource", resourceName);
+        eventDescription.put("id", vo.getUuid());
+        eventDescription.put("old-state", oldState.name());
+        eventDescription.put("new-state", newState.name());
+        eventMsg.setDescription(eventDescription);
+        try {
+            _eventBus.publish(eventMsg);
+        } catch (EventBusException e) {
+            s_logger.warn("Failed to state change event on the the event bus.");
+        }
+    }
+
+    private String getEntityFromClassName(String entityClassName) {
+        int index = entityClassName.lastIndexOf(".");
+        String entityName = entityClassName;
+        if (index != -1) {
+            entityName = entityClassName.substring(index+1);
+        }
+        return entityName;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/e7a554fc/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
index 15d8c53..66eb8e1 100755
--- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
+++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
@@ -16,37 +16,12 @@
 // under the License.
 package com.cloud.storage.snapshot;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.TimeZone;
-
-import javax.ejb.Local;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.api.command.user.snapshot.CreateSnapshotPolicyCmd;
-import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotsCmd;
-import org.apache.log4j.Logger;
-
 import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.BackupSnapshotAnswer;
-import com.cloud.agent.api.BackupSnapshotCommand;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.DeleteSnapshotBackupCommand;
-import com.cloud.agent.api.DeleteSnapshotsDirCommand;
-import com.cloud.agent.api.DownloadSnapshotFromS3Command;
-import com.cloud.agent.api.ManageSnapshotAnswer;
-import com.cloud.agent.api.ManageSnapshotCommand;
-import com.cloud.agent.api.downloadSnapshotFromSwiftCommand;
+import com.cloud.agent.api.*;
 import com.cloud.agent.api.to.S3TO;
 import com.cloud.agent.api.to.SwiftTO;
 import com.cloud.alert.AlertManager;
-import org.apache.cloudstack.api.command.user.snapshot.DeleteSnapshotPoliciesCmd;
 import com.cloud.api.commands.ListRecurringSnapshotScheduleCmd;
-import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotPoliciesCmd;
 import com.cloud.configuration.Config;
 import com.cloud.configuration.Resource.ResourceType;
 import com.cloud.configuration.dao.ConfigurationDao;
@@ -55,11 +30,7 @@ import com.cloud.dc.DataCenter;
 import com.cloud.dc.dao.ClusterDao;
 import com.cloud.dc.dao.DataCenterDao;
 import com.cloud.domain.dao.DomainDao;
-import com.cloud.event.ActionEvent;
-import com.cloud.event.EventTypes;
-import com.cloud.event.EventUtils;
-import com.cloud.event.EventVO;
-import com.cloud.event.UsageEventVO;
+import com.cloud.event.*;
 import com.cloud.event.dao.EventDao;
 import com.cloud.event.dao.UsageEventDao;
 import com.cloud.exception.InvalidParameterValueException;
@@ -69,44 +40,21 @@ import com.cloud.exception.StorageUnavailableException;
 import com.cloud.host.HostVO;
 import com.cloud.host.dao.HostDao;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.network.PhysicalNetworkTrafficType;
 import com.cloud.org.Grouping;
 import com.cloud.projects.Project.ListProjectResourcesCriteria;
 import com.cloud.resource.ResourceManager;
 import com.cloud.server.ResourceTag.TaggedResourceType;
-import com.cloud.storage.Snapshot;
-import com.cloud.storage.Snapshot.Status;
+import com.cloud.storage.*;
 import com.cloud.storage.Snapshot.Type;
-import com.cloud.storage.SnapshotPolicyVO;
-import com.cloud.storage.SnapshotScheduleVO;
-import com.cloud.storage.SnapshotVO;
-import com.cloud.storage.Storage;
 import com.cloud.storage.Storage.StoragePoolType;
-import com.cloud.storage.StorageManager;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.StoragePoolVO;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.Volume;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.DiskOfferingDao;
-import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.dao.SnapshotPolicyDao;
-import com.cloud.storage.dao.SnapshotScheduleDao;
-import com.cloud.storage.dao.StoragePoolDao;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VolumeDao;
+import com.cloud.storage.dao.*;
+import com.cloud.storage.listener.SnapshotStateListener;
 import com.cloud.storage.s3.S3Manager;
 import com.cloud.storage.secondary.SecondaryStorageVmManager;
 import com.cloud.storage.swift.SwiftManager;
 import com.cloud.tags.ResourceTagVO;
 import com.cloud.tags.dao.ResourceTagDao;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.AccountVO;
-import com.cloud.user.DomainManager;
-import com.cloud.user.ResourceLimitService;
-import com.cloud.user.User;
-import com.cloud.user.UserContext;
+import com.cloud.user.*;
 import com.cloud.user.dao.AccountDao;
 import com.cloud.utils.DateUtil;
 import com.cloud.utils.DateUtil.IntervalType;
@@ -116,18 +64,24 @@ import com.cloud.utils.Ternary;
 import com.cloud.utils.component.ComponentLocator;
 import com.cloud.utils.component.Inject;
 import com.cloud.utils.component.Manager;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.Filter;
-import com.cloud.utils.db.JoinBuilder;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.*;
 import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.fsm.NoTransitionException;
+import com.cloud.utils.fsm.StateMachine2;
 import com.cloud.vm.UserVmVO;
 import com.cloud.vm.VMInstanceVO;
 import com.cloud.vm.VirtualMachine;
 import com.cloud.vm.VirtualMachine.State;
 import com.cloud.vm.dao.UserVmDao;
+import org.apache.cloudstack.api.command.user.snapshot.CreateSnapshotPolicyCmd;
+import org.apache.cloudstack.api.command.user.snapshot.DeleteSnapshotPoliciesCmd;
+import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotPoliciesCmd;
+import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotsCmd;
+import org.apache.log4j.Logger;
+
+import javax.ejb.Local;
+import javax.naming.ConfigurationException;
+import java.util.*;
 
 @Local(value = { SnapshotManager.class, SnapshotService.class })
 public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Manager {
@@ -195,6 +149,8 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
     private int _deltaSnapshotMax;
     private int _backupsnapshotwait;
 
+    private StateMachine2<Snapshot.State, Snapshot.Event, Snapshot> _snapshotFsm;
+
     protected SearchBuilder<SnapshotVO> PolicySnapshotSearch;
     protected SearchBuilder<SnapshotPolicyVO> PoliciesForSnapSearch;
 
@@ -259,6 +215,13 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
         if (snapshot == null) {
             throw new CloudRuntimeException("Can not find snapshot " + snapshotId);
         }
+
+        try {
+            stateTransitTo(snapshot, Snapshot.Event.CreateRequested);
+        } catch (NoTransitionException nte) {
+            s_logger.debug("Failed to update snapshot state due to " + nte.getMessage());
+        }
+
         // Send a ManageSnapshotCommand to the agent
         String vmName = _storageMgr.getVmNameOnVolume(volume);
         long volumeId = volume.getId();
@@ -289,14 +252,16 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
             if (preSnapshotPath != null && preSnapshotPath.equals(answer.getSnapshotPath())) {
                 // empty snapshot
                 s_logger.debug("CreateSnapshot: this is empty snapshot ");
-                snapshot.setPath(preSnapshotPath);
-                snapshot.setBackupSnapshotId(preSnapshotVO.getBackupSnapshotId());
-                snapshot.setSwiftId(preSnapshotVO.getSwiftId());
-
-                snapshot.setStatus(Snapshot.Status.BackedUp);
-                snapshot.setPrevSnapshotId(preId);
-                snapshot.setSecHostId(preSnapshotVO.getSecHostId());
-                _snapshotDao.update(snapshotId, snapshot);
+                try {
+                    snapshot.setPath(preSnapshotPath);
+                    snapshot.setBackupSnapshotId(preSnapshotVO.getBackupSnapshotId());
+                    snapshot.setSwiftId(preSnapshotVO.getSwiftId());
+                    snapshot.setPrevSnapshotId(preId);
+                    snapshot.setSecHostId(preSnapshotVO.getSecHostId());
+                    stateTransitTo(snapshot, Snapshot.Event.OperationNotPerformed);
+                }  catch (NoTransitionException nte) {
+                    s_logger.debug("CreateSnapshot: failed to update state of snapshot due to " + nte.getMessage());
+                }
             } else {
                 long preSnapshotId = 0;
 
@@ -346,6 +311,11 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
             if (answer != null) {
                 s_logger.error(answer.getDetails());
             }
+            try {
+                stateTransitTo(snapshot, Snapshot.Event.OperationFailed);
+            } catch (NoTransitionException nte) {
+                s_logger.debug("Failed to update snapshot state due to " + nte.getMessage());
+            }
             throw new CloudRuntimeException("Creating snapshot for volume " + volumeId + " on primary storage failed.");
         }
 
@@ -410,7 +380,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
                     }
 
                     if(userVm.getHypervisorType() == HypervisorType.VMware || userVm.getHypervisorType() == HypervisorType.KVM) {
-                        List<SnapshotVO> activeSnapshots = _snapshotDao.listByInstanceId(volume.getInstanceId(), Snapshot.Status.Creating,  Snapshot.Status.CreatedOnPrimary,  Snapshot.Status.BackingUp);
+                        List<SnapshotVO> activeSnapshots = _snapshotDao.listByInstanceId(volume.getInstanceId(), Snapshot.State.Creating,  Snapshot.State.CreatedOnPrimary,  Snapshot.State.BackingUp);
                         if(activeSnapshots.size() > 1)
                             throw new CloudRuntimeException("There is other active snapshot tasks on the instance to which the volume is attached, please try again later");
                     }
@@ -419,19 +389,15 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
 
             snapshot = createSnapshotOnPrimary(volume, policyId, snapshotId);
             if (snapshot != null) {
-                if (snapshot.getStatus() == Snapshot.Status.CreatedOnPrimary) {
+                if (snapshot.getState() == Snapshot.State.CreatedOnPrimary) {
                     backedUp = backupSnapshotToSecondaryStorage(snapshot);
-                } else if (snapshot.getStatus() == Snapshot.Status.BackedUp) {
+                } else if (snapshot.getState() == Snapshot.State.BackedUp) {
                     // For empty snapshot we set status to BackedUp in createSnapshotOnPrimary
                     backedUp = true;
                 } else {
-                    snapshot.setStatus(Status.Error);
-                    _snapshotDao.update(snapshot.getId(), snapshot);
                     throw new CloudRuntimeException("Failed to create snapshot: " + snapshot + " on primary storage");
                 }
                 if (!backedUp) {
-                    snapshot.setStatus(Status.Error);
-                    _snapshotDao.update(snapshot.getId(), snapshot);
                     throw new CloudRuntimeException("Created snapshot: " + snapshot + " on primary but failed to backup on secondary");
                 }
             } else {
@@ -444,23 +410,15 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
                 //Check if the snapshot was removed while backingUp. If yes, do not log snapshot create usage event
                 SnapshotVO freshSnapshot = _snapshotDao.findById(snapshot.getId());
                 if ((freshSnapshot != null) && backedUp) {
-                    UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_SNAPSHOT_CREATE, snapshot.getAccountId(), snapshot.getDataCenterId(), snapshotId, snapshot.getName(), null, null,
-                            volume.getSize());
-                    _usageEventDao.persist(usageEvent);
+                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_CREATE, snapshot.getAccountId(),
+                            snapshot.getDataCenterId(), snapshotId, snapshot.getName(), null, null,
+                            volume.getSize(), snapshot.getClass().getName(), snapshot.getUuid());
                 }
                 if( !backedUp ) {
 
-                    snapshot.setStatus(Status.Error);
-                    _snapshotDao.update(snapshot.getId(), snapshot);
                 } else {
                     _resourceLimitMgr.incrementResourceCount(snapshotOwner.getId(), ResourceType.snapshot);
                 }
-            } else {
-            	snapshot = _snapshotDao.findById(snapshotId);
-            	if (snapshot != null) {
-            		snapshot.setStatus(Status.Error);
-            		_snapshotDao.update(snapshotId, snapshot);
-            	}
             }
 
             /*
@@ -478,9 +436,12 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
     private SnapshotVO updateDBOnCreate(Long id, String snapshotPath, long preSnapshotId) {
         SnapshotVO createdSnapshot = _snapshotDao.findByIdIncludingRemoved(id);
         createdSnapshot.setPath(snapshotPath);
-        createdSnapshot.setStatus(Snapshot.Status.CreatedOnPrimary);
         createdSnapshot.setPrevSnapshotId(preSnapshotId);
-        _snapshotDao.update(id, createdSnapshot);
+        try {
+            stateTransitTo(createdSnapshot, Snapshot.Event.OperationSucceeded);
+        } catch (NoTransitionException nte) {
+            s_logger.debug("Faile to update state of snapshot due to " + nte.getMessage());
+        }
         return createdSnapshot;
     }
 
@@ -622,9 +583,11 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
             throw new CloudRuntimeException("Can not acquire lock for snapshot: " + ss);
         }
         try {
-
-            snapshot.setStatus(Snapshot.Status.BackingUp);
-            _snapshotDao.update(snapshot.getId(), snapshot);
+            try {
+                stateTransitTo(snapshot, Snapshot.Event.BackupToSecondary);
+            } catch (NoTransitionException nte) {
+                s_logger.debug("Failed to update the state of snapshot while backing up snapshot");
+            }
 
             long volumeId = snapshot.getVolumeId();
             VolumeVO volume = _volsDao.lockRow(volumeId, true);
@@ -705,10 +668,18 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
                 if (answer.isFull()) {
                     snapshot.setPrevSnapshotId(0);
                 }
-                snapshot.setStatus(Snapshot.Status.BackedUp);
-                _snapshotDao.update(snapshotId, snapshot);
+                try {
+                    stateTransitTo(snapshot, Snapshot.Event.OperationSucceeded);
+                } catch (NoTransitionException nte) {
+                    s_logger.debug("Failed to update the state of snapshot while backing up snapshot");
+                }
 
             } else {
+                try {
+                    stateTransitTo(snapshot, Snapshot.Event.OperationFailed);
+                } catch (NoTransitionException nte) {
+                    s_logger.debug("Failed to update the state of snapshot while backing up snapshot");
+                }
                 s_logger.warn("Failed to back up snapshot on secondary storage, deleting the record from the DB");
                 _snapshotDao.remove(snapshotId);
             }
@@ -766,8 +737,8 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
             long oldSnapId = oldestSnapshot.getId();
             s_logger.debug("Max snaps: " + policy.getMaxSnaps() + " exceeded for snapshot policy with Id: " + policyId + ". Deleting oldest snapshot: " + oldSnapId);
             if(deleteSnapshotInternal(oldSnapId)){
-            	//log Snapshot delete event
-            	EventUtils.saveEvent(User.UID_SYSTEM, oldestSnapshot.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_SNAPSHOT_DELETE, "Successfully deleted oldest snapshot: " + oldSnapId, 0);
+                //log Snapshot delete event
+                ActionEventUtils.onCompletedActionEvent(User.UID_SYSTEM, oldestSnapshot.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_SNAPSHOT_DELETE, "Successfully deleted oldest snapshot: " + oldSnapId, 0);
             }
             snaps.remove(oldestSnapshot);
         }
@@ -787,7 +758,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
 
         _accountMgr.checkAccess(caller, null, true, snapshotCheck);
 
-        if( !Status.BackedUp.equals(snapshotCheck.getStatus() ) ) {
+        if( !Snapshot.State.BackedUp.equals(snapshotCheck.getState() ) ) {
             throw new InvalidParameterValueException("Can't delete snapshotshot " + snapshotId + " due to it is not in BackedUp Status");
         }
 
@@ -812,9 +783,10 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
         Transaction txn = Transaction.currentTxn();
         txn.start();
         _snapshotDao.remove(snapshotId);
-        if (snapshot.getStatus() == Snapshot.Status.BackedUp) {
-        	UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_SNAPSHOT_DELETE, snapshot.getAccountId(), snapshot.getDataCenterId(), snapshotId, snapshot.getName(), null, null, 0L);
-        	_usageEventDao.persist(usageEvent);
+        if (snapshot.getState() == Snapshot.State.BackedUp) {
+            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_DELETE, snapshot.getAccountId(),
+                    snapshot.getDataCenterId(), snapshotId, snapshot.getName(), null, null, 0L,
+                    snapshot.getClass().getName(), snapshot.getUuid());
         }
         _resourceLimitMgr.decrementResourceCount(snapshot.getAccountId(), ResourceType.snapshot);
         txn.commit();
@@ -966,7 +938,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
         SearchBuilder<SnapshotVO> sb = _snapshotDao.createSearchBuilder();
         _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
 
-        sb.and("status", sb.entity().getStatus(), SearchCriteria.Op.EQ);
+        sb.and("status", sb.entity().getState(), SearchCriteria.Op.EQ);
         sb.and("volumeId", sb.entity().getVolumeId(), SearchCriteria.Op.EQ);
         sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
         sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
@@ -1115,9 +1087,9 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
                     }
 
                     // Log event after successful deletion
-                    UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_SNAPSHOT_DELETE, snapshot.getAccountId(), volume.getDataCenterId(), snapshot.getId(), snapshot.getName(), null, null,
-                            volume.getSize());
-                    _usageEventDao.persist(usageEvent);
+                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_DELETE, snapshot.getAccountId(),
+                            volume.getDataCenterId(), snapshot.getId(), snapshot.getName(), null, null,
+                            volume.getSize(), snapshot.getClass().getName(), snapshot.getUuid());
                 }
             }
         }
@@ -1452,6 +1424,9 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
 
         s_logger.info("Snapshot Manager is configured.");
 
+        _snapshotFsm = Snapshot.State.getStateMachine();
+        _snapshotFsm.registerListener(new SnapshotStateListener());
+
         return true;
     }
 
@@ -1538,11 +1513,15 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
 
     @Override
     public boolean canOperateOnVolume(VolumeVO volume) {
-    	List<SnapshotVO> snapshots = _snapshotDao.listByStatus(volume.getId(), Status.Creating, Status.CreatedOnPrimary, Status.BackingUp);
+        List<SnapshotVO> snapshots = _snapshotDao.listByStatus(volume.getId(), Snapshot.State.Creating,
+                Snapshot.State.CreatedOnPrimary, Snapshot.State.BackingUp);
     	if (snapshots.size() > 0) {
     		return false;
     	}
     	return true;
     }
 
+    protected boolean stateTransitTo(Snapshot snapshot, Snapshot.Event e) throws NoTransitionException {
+        return _snapshotFsm.transitTo(snapshot, e, null, _snapshotDao);
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/e7a554fc/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java
index d7deb6f..9389893 100644
--- a/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java
+++ b/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java
@@ -26,6 +26,7 @@ import java.util.TimerTask;
 import javax.ejb.Local;
 import javax.naming.ConfigurationException;
 
+import com.cloud.event.ActionEventUtils;
 import org.apache.cloudstack.api.command.user.snapshot.CreateSnapshotCmd;
 import org.apache.log4j.Logger;
 
@@ -39,7 +40,6 @@ import com.cloud.async.AsyncJobVO;
 import com.cloud.async.dao.AsyncJobDao;
 import com.cloud.configuration.dao.ConfigurationDao;
 import com.cloud.event.EventTypes;
-import com.cloud.event.EventUtils;
 import com.cloud.storage.Snapshot;
 import com.cloud.storage.SnapshotPolicyVO;
 import com.cloud.storage.SnapshotScheduleVO;
@@ -232,8 +232,8 @@ public class SnapshotSchedulerImpl implements SnapshotScheduler {
 
 
                 tmpSnapshotScheduleVO = _snapshotScheduleDao.acquireInLockTable(snapshotScheId);
-                Long eventId = EventUtils.saveScheduledEvent(User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM,
-                        EventTypes.EVENT_SNAPSHOT_CREATE, "creating snapshot for volume Id:"+volumeId,0);
+                Long eventId = ActionEventUtils.onScheduledActionEvent(User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM,
+                        EventTypes.EVENT_SNAPSHOT_CREATE, "creating snapshot for volume Id:" + volumeId, 0);
 
                 Map<String, String> params = new HashMap<String, String>();
                 params.put(ApiConstants.VOLUME_ID, "" + volumeId);

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/e7a554fc/server/src/com/cloud/template/HyervisorTemplateAdapter.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/template/HyervisorTemplateAdapter.java b/server/src/com/cloud/template/HyervisorTemplateAdapter.java
index c80d1de..81a482b 100755
--- a/server/src/com/cloud/template/HyervisorTemplateAdapter.java
+++ b/server/src/com/cloud/template/HyervisorTemplateAdapter.java
@@ -16,28 +16,13 @@
 // under the License.
 package com.cloud.template;
 
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.UnknownHostException;
-import java.util.List;
-
-import javax.ejb.Local;
-
-import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
-import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
-import org.apache.log4j.Logger;
-
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.storage.DeleteTemplateCommand;
-import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd;
-import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
 import com.cloud.configuration.Resource.ResourceType;
 import com.cloud.dc.DataCenterVO;
 import com.cloud.event.EventTypes;
-import com.cloud.event.UsageEventVO;
+import com.cloud.event.UsageEventUtils;
 import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.exception.ResourceAllocationException;
 import com.cloud.host.HostVO;
@@ -53,6 +38,15 @@ import com.cloud.user.Account;
 import com.cloud.utils.component.Inject;
 import com.cloud.utils.db.DB;
 import com.cloud.utils.exception.CloudRuntimeException;
+import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
+import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
+import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd;
+import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
+import org.apache.log4j.Logger;
+
+import javax.ejb.Local;
+import java.net.*;
+import java.util.List;
 
 @Local(value=TemplateAdapter.class)
 public class HyervisorTemplateAdapter extends TemplateAdapterBase implements TemplateAdapter {
@@ -202,8 +196,7 @@ public class HyervisorTemplateAdapter extends TemplateAdapterBase implements Tem
 						success = false;
 						break;
 					}
-					UsageEventVO usageEvent = new UsageEventVO(eventType, account.getId(), sZoneId, templateId, null);
-					_usageEventDao.persist(usageEvent);					
+					UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null);
                     templateHostVO.setDestroyed(true);
 					_tmpltHostDao.update(templateHostVO.getId(), templateHostVO);
                     String installPath = templateHostVO.getInstallPath();

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/e7a554fc/server/src/com/cloud/template/TemplateManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java
index 1372111..42106b3 100755
--- a/server/src/com/cloud/template/TemplateManagerImpl.java
+++ b/server/src/com/cloud/template/TemplateManagerImpl.java
@@ -16,41 +16,14 @@
 // under the License.
 package com.cloud.template;
 
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import javax.ejb.Local;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.api.BaseListTemplateOrIsoPermissionsCmd;
-import org.apache.cloudstack.api.BaseUpdateTemplateOrIsoPermissionsCmd;
-import org.apache.cloudstack.api.command.user.iso.*;
-import org.apache.cloudstack.api.command.user.template.*;
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.acl.SecurityChecker.AccessType;
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.downloadTemplateFromSwiftToSecondaryStorageCommand;
-import com.cloud.agent.api.uploadTemplateToSwiftFromSecondaryStorageCommand;
 import com.cloud.agent.api.storage.DestroyCommand;
 import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
 import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
 import com.cloud.agent.api.to.SwiftTO;
-import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
-import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
+import com.cloud.agent.api.uploadTemplateToSwiftFromSecondaryStorageCommand;
 import com.cloud.async.AsyncJobManager;
 import com.cloud.async.AsyncJobVO;
 import com.cloud.configuration.Config;
@@ -63,7 +36,7 @@ import com.cloud.dc.dao.DataCenterDao;
 import com.cloud.domain.dao.DomainDao;
 import com.cloud.event.ActionEvent;
 import com.cloud.event.EventTypes;
-import com.cloud.event.UsageEventVO;
+import com.cloud.event.UsageEventUtils;
 import com.cloud.event.dao.EventDao;
 import com.cloud.event.dao.UsageEventDao;
 import com.cloud.exception.InvalidParameterValueException;
@@ -77,51 +50,19 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType;
 import com.cloud.hypervisor.HypervisorGuruManager;
 import com.cloud.projects.Project;
 import com.cloud.projects.ProjectManager;
-import com.cloud.storage.LaunchPermissionVO;
-import com.cloud.storage.SnapshotVO;
-import com.cloud.storage.Storage;
+import com.cloud.storage.*;
 import com.cloud.storage.Storage.ImageFormat;
 import com.cloud.storage.Storage.TemplateType;
-import com.cloud.storage.StorageManager;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.StoragePoolHostVO;
-import com.cloud.storage.StoragePoolStatus;
-import com.cloud.storage.StoragePoolVO;
-import com.cloud.storage.Upload;
 import com.cloud.storage.Upload.Type;
-import com.cloud.storage.UploadVO;
-import com.cloud.storage.VMTemplateHostVO;
-import com.cloud.storage.VMTemplateStoragePoolVO;
-import com.cloud.storage.VMTemplateStorageResourceAssoc;
 import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
-import com.cloud.storage.VMTemplateSwiftVO;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.VMTemplateZoneVO;
-import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.LaunchPermissionDao;
-import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.dao.StoragePoolDao;
-import com.cloud.storage.dao.StoragePoolHostDao;
-import com.cloud.storage.dao.UploadDao;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VMTemplateHostDao;
-import com.cloud.storage.dao.VMTemplatePoolDao;
-import com.cloud.storage.dao.VMTemplateS3Dao;
-import com.cloud.storage.dao.VMTemplateSwiftDao;
-import com.cloud.storage.dao.VMTemplateZoneDao;
-import com.cloud.storage.dao.VolumeDao;
+import com.cloud.storage.dao.*;
 import com.cloud.storage.download.DownloadMonitor;
 import com.cloud.storage.s3.S3Manager;
 import com.cloud.storage.secondary.SecondaryStorageVmManager;
 import com.cloud.storage.swift.SwiftManager;
 import com.cloud.storage.upload.UploadMonitor;
 import com.cloud.template.TemplateAdapter.TemplateAdapterType;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.AccountService;
-import com.cloud.user.AccountVO;
-import com.cloud.user.ResourceLimitService;
-import com.cloud.user.UserContext;
+import com.cloud.user.*;
 import com.cloud.user.dao.AccountDao;
 import com.cloud.user.dao.UserAccountDao;
 import com.cloud.user.dao.UserDao;
@@ -132,12 +73,7 @@ import com.cloud.utils.component.ComponentLocator;
 import com.cloud.utils.component.Inject;
 import com.cloud.utils.component.Manager;
 import com.cloud.utils.concurrency.NamedThreadFactory;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.GlobalLock;
-import com.cloud.utils.db.JoinBuilder;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.*;
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.vm.UserVmManager;
 import com.cloud.vm.UserVmVO;
@@ -145,6 +81,21 @@ import com.cloud.vm.VMInstanceVO;
 import com.cloud.vm.VirtualMachine.State;
 import com.cloud.vm.dao.UserVmDao;
 import com.cloud.vm.dao.VMInstanceDao;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.BaseListTemplateOrIsoPermissionsCmd;
+import org.apache.cloudstack.api.BaseUpdateTemplateOrIsoPermissionsCmd;
+import org.apache.cloudstack.api.command.user.iso.*;
+import org.apache.cloudstack.api.command.user.template.*;
+import org.apache.log4j.Logger;
+
+import javax.ejb.Local;
+import javax.naming.ConfigurationException;
+import java.net.*;
+import java.util.*;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
 
 
 @Local(value={TemplateManager.class, TemplateService.class})
@@ -823,8 +774,8 @@ public class TemplateManagerImpl implements TemplateManager, Manager, TemplateSe
                 _tmpltDao.addTemplateToZone(template, dstZoneId);
             	
             	if(account.getId() != Account.ACCOUNT_ID_SYSTEM){
-            	    UsageEventVO usageEvent = new UsageEventVO(copyEventType, account.getId(), dstZoneId, tmpltId, null, null, null, srcTmpltHost.getSize());
-            	    _usageEventDao.persist(usageEvent);
+                    UsageEventUtils.publishUsageEvent(copyEventType, account.getId(), dstZoneId, tmpltId, null, null, null, srcTmpltHost.getSize(),
+                            template.getClass().getName(), template.getUuid());
             	}
             	return true;
             }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/e7a554fc/server/src/com/cloud/user/AccountManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java
index b910a03..f60d305 100755
--- a/server/src/com/cloud/user/AccountManagerImpl.java
+++ b/server/src/com/cloud/user/AccountManagerImpl.java
@@ -36,6 +36,7 @@ import javax.crypto.spec.SecretKeySpec;
 import javax.ejb.Local;
 import javax.naming.ConfigurationException;
 
+import com.cloud.event.ActionEventUtils;
 import org.apache.cloudstack.acl.ControlledEntity;
 import org.apache.cloudstack.acl.RoleType;
 import org.apache.cloudstack.acl.SecurityChecker;
@@ -64,7 +65,6 @@ import com.cloud.domain.DomainVO;
 import com.cloud.domain.dao.DomainDao;
 import com.cloud.event.ActionEvent;
 import com.cloud.event.EventTypes;
-import com.cloud.event.EventUtils;
 import com.cloud.exception.AgentUnavailableException;
 import com.cloud.exception.CloudAuthenticationException;
 import com.cloud.exception.ConcurrentOperationException;
@@ -1744,7 +1744,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag
     public void logoutUser(Long userId) {
         UserAccount userAcct = _userAccountDao.findById(userId);
         if (userAcct != null) {
-            EventUtils.saveEvent(userId, userAcct.getAccountId(), userAcct.getDomainId(), EventTypes.EVENT_USER_LOGOUT, "user has logged out");
+            ActionEventUtils.onActionEvent(userId, userAcct.getAccountId(), userAcct.getDomainId(), EventTypes.EVENT_USER_LOGOUT, "user has logged out");
         } // else log some kind of error event? This likely means the user doesn't exist, or has been deleted...
     }
 
@@ -1875,10 +1875,10 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag
                 s_logger.debug("User: " + username + " in domain " + domainId + " has successfully logged in");
             }
             if (NetUtils.isValidIp(loginIpAddress)) {
-                EventUtils.saveEvent(user.getId(), user.getAccountId(), user.getDomainId(), EventTypes.EVENT_USER_LOGIN,
+                ActionEventUtils.onActionEvent(user.getId(), user.getAccountId(), user.getDomainId(), EventTypes.EVENT_USER_LOGIN,
                         "user has logged in from IP Address " + loginIpAddress);
             } else {
-                EventUtils.saveEvent(user.getId(), user.getAccountId(), user.getDomainId(), EventTypes.EVENT_USER_LOGIN,
+                ActionEventUtils.onActionEvent(user.getId(), user.getAccountId(), user.getDomainId(), EventTypes.EVENT_USER_LOGIN,
                         "user has logged in. The IP Address cannot be determined");
             }
             return user;

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/e7a554fc/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 3737450..969539c 100644
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -54,7 +54,7 @@ import com.cloud.domain.DomainVO;
 import com.cloud.domain.dao.DomainDao;
 import com.cloud.event.ActionEvent;
 import com.cloud.event.EventTypes;
-import com.cloud.event.UsageEventVO;
+import com.cloud.event.UsageEventUtils;
 import com.cloud.event.dao.UsageEventDao;
 import com.cloud.exception.*;
 import com.cloud.ha.HighAvailabilityManager;
@@ -245,8 +245,6 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
     @Inject
     protected LoadBalancingRulesManager _lbMgr;
     @Inject
-    protected UsageEventDao _usageEventDao;
-    @Inject
     protected SSHKeyPairDao _sshKeyPairDao;
     @Inject
     protected UserVmDetailsDao _vmDetailsDao;
@@ -280,6 +278,8 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
     PhysicalNetworkDao _physicalNetworkDao;
     @Inject
     VpcManager _vpcMgr;
+    @Inject
+    UsageEventDao _usageEventDao;
 
     protected ScheduledExecutorService _executor = null;
     protected int _expungeInterval;
@@ -841,7 +841,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
     }
 
     @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_DETACH, eventDescription = "detaching volume", async = true)
+    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_DETACH, eventDescription = "detaching volume",  async = true)
     public Volume detachVolumeFromVM(DetachVolumeCmd cmmd) {
         Account caller = UserContext.current().getCaller();
         if ((cmmd.getId() == null && cmmd.getDeviceId() == null && cmmd.getVirtualMachineId() == null) || (cmmd.getId() != null && (cmmd.getDeviceId() != null || cmmd.getVirtualMachineId() != null))
@@ -1372,9 +1372,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
                         offeringId = offering.getId();
                     }
                 }
-                UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), offeringId, templateId,
-                        volume.getSize());
-                _usageEventDao.persist(usageEvent);
+                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(),
+                        volume.getDataCenterId(), volume.getId(), volume.getName(), offeringId, templateId,
+                        volume.getSize(), Volume.class.getName(), volume.getUuid());
             }
         }
 
@@ -1640,8 +1640,8 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
             //check permissions
             _accountMgr.checkAccess(caller, null, true, snapshot);
 
-            if (snapshot.getStatus() != Snapshot.Status.BackedUp) {
-                throw new InvalidParameterValueException("Snapshot id=" + snapshotId + " is not in " + Snapshot.Status.BackedUp + " state yet and can't be used for template creation");
+            if (snapshot.getState() != Snapshot.State.BackedUp) {
+                throw new InvalidParameterValueException("Snapshot id=" + snapshotId + " is not in " + Snapshot.State.BackedUp + " state yet and can't be used for template creation");
             }
 
             /*
@@ -1888,9 +1888,10 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
                 templateHostVO.setPhysicalSize(answer.getphysicalSize());
                 _templateHostDao.persist(templateHostVO);
 
-                UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_TEMPLATE_CREATE, privateTemplate.getAccountId(), secondaryStorageHost.getDataCenterId(), privateTemplate.getId(),
-                        privateTemplate.getName(), null, privateTemplate.getSourceTemplateId(), templateHostVO.getSize());
-                _usageEventDao.persist(usageEvent);
+                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_TEMPLATE_CREATE, privateTemplate.getAccountId(),
+                        secondaryStorageHost.getDataCenterId(), privateTemplate.getId(),
+                        privateTemplate.getName(), null, privateTemplate.getSourceTemplateId(),
+                        templateHostVO.getSize(), VirtualMachineTemplate.class.getName(), privateTemplate.getUuid());
                 txn.commit();
             }
         } finally {
@@ -2835,8 +2836,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
         }
         UserContext.current().setEventDetails("Vm Id: " + vm.getId());
 
-        UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VM_CREATE, accountId, zone.getId(), vm.getId(), vm.getHostName(), offering.getId(), template.getId(), hypervisorType.toString());
-        _usageEventDao.persist(usageEvent);
+        UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, accountId, zone.getId(), vm.getId(),
+                vm.getHostName(), offering.getId(), template.getId(), hypervisorType.toString(),
+                VirtualMachine.class.getName(), vm.getUuid());
 
         _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.user_vm);
         txn.commit();
@@ -3006,8 +3008,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
         for (NicVO nic : nics) {
             NetworkVO network = _networkDao.findById(nic.getNetworkId());
             long isDefault = (nic.isDefaultNic()) ? 1 : 0;
-            UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NETWORK_OFFERING_ASSIGN, vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(), vm.getHostName(), network.getNetworkOfferingId(), null, isDefault);
-            _usageEventDao.persist(usageEvent);
+            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_ASSIGN, vm.getAccountId(),
+                    vm.getDataCenterIdToDeployIn(), vm.getId(), vm.getHostName(), network.getNetworkOfferingId(),
+                    null, isDefault, VirtualMachine.class.getName(), vm.getUuid());
             if (network.getTrafficType() == TrafficType.Guest) {
                 originalIp = nic.getIp4Address();
                 guestNic = nic;
@@ -3270,8 +3273,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
             List<VolumeVO> volumes = _volsDao.findByInstance(vmId);
             for (VolumeVO volume : volumes) {
                 if (volume.getVolumeType().equals(Volume.Type.ROOT)) {
-                    UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName());
-                    _usageEventDao.persist(usageEvent);
+                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(),
+                            volume.getDataCenterId(), volume.getId(), volume.getName(), Volume.class.getName(),
+                            volume.getUuid());
                 }
             }
 
@@ -3721,8 +3725,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
         Transaction txn = Transaction.currentTxn();
         txn.start();
         //generate destroy vm event for usage
-        _usageEventDao.persist(new UsageEventVO(EventTypes.EVENT_VM_DESTROY, vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(),
-                vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(), vm.getHypervisorType().toString()));
+        UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_DESTROY, vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(),
+                vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(), vm.getHypervisorType().toString(),
+                VirtualMachine.class.getName(), vm.getUuid());
         // update resource counts
         _resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.user_vm);
 
@@ -3734,13 +3739,16 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
         // OS 2: update volume
         List<VolumeVO> volumes = _volsDao.findByInstance(cmd.getVmId());
         for (VolumeVO volume : volumes) {
-            _usageEventDao.persist(new UsageEventVO(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName()));
+            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(),
+                    volume.getDataCenterId(), volume.getId(), volume.getName(), Volume.class.getName(), volume.getUuid());
             _resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.volume);
             volume.setAccountId(newAccount.getAccountId());
             _volsDao.persist(volume);
             _resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.volume);
-            _usageEventDao.persist(new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
-                    volume.getDiskOfferingId(), volume.getTemplateId(), 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());
             //snapshots: mark these removed in db
             List<SnapshotVO> snapshots = _snapshotDao.listByVolumeIdIncludingRemoved(volume.getId());
             for (SnapshotVO snapshot: snapshots){
@@ -3750,8 +3758,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
 
         _resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.user_vm);
         //generate usage events to account for this change
-        _usageEventDao.persist(new UsageEventVO(EventTypes.EVENT_VM_CREATE, vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(),
-                vm.getHostName(), vm.getServiceOfferingId(),  vm.getTemplateId(), vm.getHypervisorType().toString()));
+        UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(),
+                vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(), vm.getHypervisorType().toString(),
+                VirtualMachine.class.getName(), vm.getUuid());
 
         txn.commit();
 

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/e7a554fc/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 4d9bcc5..786387f 100644
--- a/server/src/com/cloud/vm/UserVmStateListener.java
+++ b/server/src/com/cloud/vm/UserVmStateListener.java
@@ -16,24 +16,48 @@
 // under the License.
 package com.cloud.vm;
 
-import java.util.List;
-
+import com.cloud.event.EventCategory;
 import com.cloud.event.EventTypes;
-import com.cloud.event.UsageEventVO;
+import com.cloud.event.UsageEventUtils;
 import com.cloud.event.dao.UsageEventDao;
+import com.cloud.network.Network;
 import com.cloud.network.NetworkVO;
 import com.cloud.network.dao.NetworkDao;
+import com.cloud.server.ManagementServer;
+import com.cloud.utils.component.Adapters;
+import com.cloud.utils.component.ComponentLocator;
 import com.cloud.utils.fsm.StateListener;
 import com.cloud.vm.VirtualMachine.Event;
 import com.cloud.vm.VirtualMachine.State;
 import com.cloud.vm.dao.NicDao;
+import org.apache.cloudstack.framework.events.EventBus;
+import org.apache.cloudstack.framework.events.EventBusException;
+import org.apache.log4j.Logger;
+
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 public class UserVmStateListener implements StateListener<State, VirtualMachine.Event, VirtualMachine> {
 
     protected UsageEventDao _usageEventDao;
     protected NetworkDao _networkDao;
     protected NicDao _nicDao;
-    
+    private static final Logger s_logger = Logger.getLogger(UserVmStateListener.class);
+
+    // get the event bus provider if configured
+    protected static EventBus _eventBus = null;
+    static {
+        Adapters<EventBus> eventBusImpls = ComponentLocator.getLocator(ManagementServer.Name).getAdapters(EventBus.class);
+        if (eventBusImpls != null) {
+            Enumeration<EventBus> eventBusenum = eventBusImpls.enumeration();
+            if (eventBusenum != null && eventBusenum.hasMoreElements()) {
+                _eventBus = eventBusenum.nextElement(); // configure event bus if configured
+            }
+        }
+    }
+
     public UserVmStateListener(UsageEventDao usageEventDao, NetworkDao networkDao, NicDao nicDao) {
         this._usageEventDao = usageEventDao;
         this._networkDao = networkDao;
@@ -42,6 +66,7 @@ public class UserVmStateListener implements StateListener<State, VirtualMachine.
     
     @Override
     public boolean preStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vo, boolean status, Object opaque) {
+        pubishOnEventBus(event.name(), "preStateTransitionEvent", vo, oldState, newState);
         return true;
     }
 
@@ -54,29 +79,62 @@ public class UserVmStateListener implements StateListener<State, VirtualMachine.
         if(vo.getType() != VirtualMachine.Type.User){
             return true;
         }
-        
+
+        pubishOnEventBus(event.name(), "postStateTransitionEvent", vo, oldState, newState);
+
         if (VirtualMachine.State.isVmCreated(oldState, event, newState)) {
-            UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VM_CREATE, vo.getAccountId(), vo.getDataCenterIdToDeployIn(), vo.getId(), vo.getHostName(), vo.getServiceOfferingId(), 
+            UsageEventUtils.saveUsageEvent(EventTypes.EVENT_VM_CREATE, vo.getAccountId(), vo.getDataCenterIdToDeployIn(), vo.getId(), vo.getHostName(), vo.getServiceOfferingId(),
                     vo.getTemplateId(), vo.getHypervisorType().toString());
-            _usageEventDao.persist(usageEvent);
         } else if (VirtualMachine.State.isVmStarted(oldState, event, newState)) {
-            UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VM_START, vo.getAccountId(), vo.getDataCenterIdToDeployIn(), vo.getId(), vo.getHostName(), vo.getServiceOfferingId(), 
+            UsageEventUtils.saveUsageEvent(EventTypes.EVENT_VM_START, vo.getAccountId(), vo.getDataCenterIdToDeployIn(), vo.getId(), vo.getHostName(), vo.getServiceOfferingId(),
                     vo.getTemplateId(), vo.getHypervisorType().toString());
-            _usageEventDao.persist(usageEvent);
         } else if (VirtualMachine.State.isVmStopped(oldState, event, newState)) {
-            UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VM_STOP, vo.getAccountId(), vo.getDataCenterIdToDeployIn(), vo.getId(), vo.getHostName());
-            _usageEventDao.persist(usageEvent);
+            UsageEventUtils.saveUsageEvent(EventTypes.EVENT_VM_STOP, vo.getAccountId(), vo.getDataCenterIdToDeployIn(), vo.getId(), vo.getHostName());
             List<NicVO> nics = _nicDao.listByVmId(vo.getId());
             for (NicVO nic : nics) {
                 NetworkVO network = _networkDao.findById(nic.getNetworkId());
-                usageEvent = new UsageEventVO(EventTypes.EVENT_NETWORK_OFFERING_REMOVE, vo.getAccountId(), vo.getDataCenterIdToDeployIn(), vo.getId(), null, network.getNetworkOfferingId(), null, 0L);
-                _usageEventDao.persist(usageEvent);
+                UsageEventUtils.saveUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_REMOVE, vo.getAccountId(), vo.getDataCenterIdToDeployIn(), vo.getId(), null, network.getNetworkOfferingId(), null, 0L);
             }
         } else if (VirtualMachine.State.isVmDestroyed(oldState, event, newState)) {
-            UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VM_DESTROY, vo.getAccountId(), vo.getDataCenterIdToDeployIn(), vo.getId(), vo.getHostName(), vo.getServiceOfferingId(), 
+            UsageEventUtils.saveUsageEvent(EventTypes.EVENT_VM_DESTROY, vo.getAccountId(), vo.getDataCenterIdToDeployIn(), vo.getId(), vo.getHostName(), vo.getServiceOfferingId(),
                     vo.getTemplateId(), vo.getHypervisorType().toString());
-            _usageEventDao.persist(usageEvent);
         } 
         return true;
     }
+
+    private void pubishOnEventBus(String event, String status, VirtualMachine vo, VirtualMachine.State oldState, VirtualMachine.State newState) {
+
+        if (_eventBus == null) {
+            return; // no provider is configured to provide events bus, so just return
+        }
+
+        String resourceName = getEntityFromClassName(Network.class.getName());
+        org.apache.cloudstack.framework.events.Event eventMsg =  new org.apache.cloudstack.framework.events.Event(
+                ManagementServer.Name,
+                EventCategory.RESOURCE_STATE_CHANGE_EVENT.getName(),
+                event,
+                resourceName,
+                vo.getUuid());
+        Map<String, String> eventDescription = new HashMap<String, String>();
+        eventDescription.put("resource", resourceName);
+        eventDescription.put("id", vo.getUuid());
+        eventDescription.put("old-state", oldState.name());
+        eventDescription.put("new-state", newState.name());
+        eventMsg.setDescription(eventDescription);
+        try {
+            _eventBus.publish(eventMsg);
+        } catch (EventBusException e) {
+            s_logger.warn("Failed to publish state change event on the the event bus.");
+        }
+
+    }
+
+    private String getEntityFromClassName(String entityClassName) {
+        int index = entityClassName.lastIndexOf(".");
+        String entityName = entityClassName;
+        if (index != -1) {
+            entityName = entityClassName.substring(index+1);
+        }
+        return entityName;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/e7a554fc/server/test/com/cloud/snapshot/SnapshotDaoTest.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/snapshot/SnapshotDaoTest.java b/server/test/com/cloud/snapshot/SnapshotDaoTest.java
index c412f49..5dc9b91 100644
--- a/server/test/com/cloud/snapshot/SnapshotDaoTest.java
+++ b/server/test/com/cloud/snapshot/SnapshotDaoTest.java
@@ -16,24 +16,23 @@
 // under the License.
 package com.cloud.snapshot;
 
-import java.util.List;
-
 import com.cloud.storage.Snapshot;
 import com.cloud.storage.SnapshotVO;
 import com.cloud.storage.dao.SnapshotDaoImpl;
 import com.cloud.utils.component.ComponentLocator;
-
 import junit.framework.Assert;
 import junit.framework.TestCase;
 
+import java.util.List;
+
 public class SnapshotDaoTest extends TestCase {
 	
     public void testListBy() {
         SnapshotDaoImpl dao = ComponentLocator.inject(SnapshotDaoImpl.class);
         
-        List<SnapshotVO> snapshots = dao.listByInstanceId(3, Snapshot.Status.BackedUp);
+        List<SnapshotVO> snapshots = dao.listByInstanceId(3, Snapshot.State.BackedUp);
         for(SnapshotVO snapshot : snapshots) {
-            Assert.assertTrue(snapshot.getStatus() == Snapshot.Status.BackedUp);
+            Assert.assertTrue(snapshot.getState() == Snapshot.State.BackedUp);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/e7a554fc/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java b/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java
index 7c9a582..f0e4b54 100644
--- a/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java
+++ b/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java
@@ -16,12 +16,7 @@
 // under the License.
 package com.cloud.vpc.dao;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import javax.ejb.Local;
-
+import com.cloud.network.Network;
 import com.cloud.network.Network.GuestType;
 import com.cloud.network.NetworkAccountVO;
 import com.cloud.network.NetworkVO;
@@ -31,6 +26,11 @@ import com.cloud.utils.db.DB;
 import com.cloud.utils.db.GenericDaoBase;
 import com.cloud.utils.db.SearchBuilder;
 
+import javax.ejb.Local;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
 @Local(value = NetworkDao.class)
 @DB(txn = false)
 public class MockNetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements NetworkDao{
@@ -342,6 +342,11 @@ public class MockNetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implemen
         return 0;
     }
 
+    @Override
+    public boolean updateState(Network.State currentState, Network.Event event, Network.State nextState, Network vo, Object data) {
+        return true;
+    }
+
     /* (non-Javadoc)
      * @see com.cloud.network.dao.NetworkDao#listNetworksByAccount(long, long, com.cloud.network.Network.GuestType, boolean)
      */