From db2ba816a46730b65d7b73aeac3d67ccace5438e Mon Sep 17 00:00:00 2001 From: Murali Reddy Date: Mon, 28 Jan 2013 17:21:56 +0530 Subject: [PATCH] adding a state listener to volume resource , and publish resource state change event on both pre and post state transition --- .../com/cloud/storage/StorageManagerImpl.java | 142 ++++-------------- .../storage/listener/VolumeStateListener.java | 84 +++++++++++ 2 files changed, 116 insertions(+), 110 deletions(-) create mode 100644 server/src/com/cloud/storage/listener/VolumeStateListener.java diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index d38537f651f..9897fa1cfb2 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -16,69 +16,14 @@ // under the License. package com.cloud.storage; -import java.math.BigDecimal; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.UnknownHostException; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; - -import com.cloud.event.UsageEventUtils; -import org.apache.cloudstack.api.command.admin.storage.*; -import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd; -import org.apache.cloudstack.api.command.user.volume.UploadVolumeCmd; -import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd; -import org.apache.log4j.Logger; - import com.cloud.agent.AgentManager; -import com.cloud.agent.api.Answer; -import com.cloud.agent.api.BackupSnapshotCommand; -import com.cloud.agent.api.CleanupSnapshotBackupCommand; -import com.cloud.agent.api.Command; -import com.cloud.agent.api.CreateStoragePoolCommand; -import com.cloud.agent.api.CreateVolumeFromSnapshotAnswer; -import com.cloud.agent.api.CreateVolumeFromSnapshotCommand; -import com.cloud.agent.api.DeleteStoragePoolCommand; -import com.cloud.agent.api.ManageSnapshotCommand; -import com.cloud.agent.api.ModifyStoragePoolAnswer; -import com.cloud.agent.api.ModifyStoragePoolCommand; -import com.cloud.agent.api.UpgradeSnapshotCommand; -import com.cloud.agent.api.storage.CopyVolumeAnswer; -import com.cloud.agent.api.storage.CopyVolumeCommand; -import com.cloud.agent.api.storage.CreateAnswer; -import com.cloud.agent.api.storage.CreateCommand; -import com.cloud.agent.api.storage.DeleteTemplateCommand; -import com.cloud.agent.api.storage.DeleteVolumeCommand; -import com.cloud.agent.api.storage.DestroyCommand; -import com.cloud.agent.api.storage.ResizeVolumeCommand; -import com.cloud.agent.api.storage.ResizeVolumeAnswer; +import com.cloud.agent.api.*; +import com.cloud.agent.api.storage.*; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.VolumeTO; import com.cloud.agent.manager.Commands; import com.cloud.alert.AlertManager; import com.cloud.api.ApiDBUtils; -import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd; import com.cloud.async.AsyncJobManager; import com.cloud.capacity.Capacity; import com.cloud.capacity.CapacityManager; @@ -105,19 +50,9 @@ import com.cloud.domain.Domain; import com.cloud.domain.dao.DomainDao; import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; +import com.cloud.event.UsageEventUtils; import com.cloud.event.dao.EventDao; -import com.cloud.exception.AgentUnavailableException; -import com.cloud.exception.ConcurrentOperationException; -import com.cloud.exception.DiscoveryException; -import com.cloud.exception.InsufficientCapacityException; -import com.cloud.exception.InsufficientStorageCapacityException; -import com.cloud.exception.InvalidParameterValueException; -import com.cloud.exception.OperationTimedoutException; -import com.cloud.exception.PermissionDeniedException; -import com.cloud.exception.ResourceAllocationException; -import com.cloud.exception.ResourceInUseException; -import com.cloud.exception.ResourceUnavailableException; -import com.cloud.exception.StorageUnavailableException; +import com.cloud.exception.*; import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.Status; @@ -139,32 +74,17 @@ import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Volume.Event; import com.cloud.storage.Volume.Type; import com.cloud.storage.allocator.StoragePoolAllocator; -import com.cloud.storage.dao.DiskOfferingDao; -import com.cloud.storage.dao.SnapshotDao; -import com.cloud.storage.dao.SnapshotPolicyDao; -import com.cloud.storage.dao.StoragePoolDao; -import com.cloud.storage.dao.StoragePoolHostDao; -import com.cloud.storage.dao.StoragePoolWorkDao; -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.VolumeDao; -import com.cloud.storage.dao.VolumeHostDao; +import com.cloud.storage.dao.*; import com.cloud.storage.download.DownloadMonitor; import com.cloud.storage.listener.StoragePoolMonitor; +import com.cloud.storage.listener.VolumeStateListener; import com.cloud.storage.s3.S3Manager; import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.storage.snapshot.SnapshotScheduler; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.template.TemplateManager; -import com.cloud.user.Account; -import com.cloud.user.AccountManager; -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.user.dao.UserDao; import com.cloud.uservm.UserVm; @@ -177,36 +97,35 @@ 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.GenericSearchBuilder; -import com.cloud.utils.db.GlobalLock; -import com.cloud.utils.db.JoinBuilder; +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.Op; -import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.ExecutionException; import com.cloud.utils.fsm.NoTransitionException; import com.cloud.utils.fsm.StateMachine2; -import com.cloud.vm.ConsoleProxyVO; -import com.cloud.vm.DiskProfile; -import com.cloud.vm.DomainRouterVO; -import com.cloud.vm.SecondaryStorageVmVO; -import com.cloud.vm.UserVmManager; -import com.cloud.vm.UserVmVO; -import com.cloud.vm.VMInstanceVO; -import com.cloud.vm.VirtualMachine; +import com.cloud.vm.*; import com.cloud.vm.VirtualMachine.State; -import com.cloud.vm.VirtualMachineManager; -import com.cloud.vm.VirtualMachineProfile; -import com.cloud.vm.VirtualMachineProfileImpl; -import com.cloud.vm.dao.ConsoleProxyDao; -import com.cloud.vm.dao.DomainRouterDao; -import com.cloud.vm.dao.SecondaryStorageVmDao; -import com.cloud.vm.dao.UserVmDao; -import com.cloud.vm.dao.VMInstanceDao; +import com.cloud.vm.dao.*; +import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaintenanceCmd; +import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd; +import org.apache.cloudstack.api.command.admin.storage.DeletePoolCmd; +import org.apache.cloudstack.api.command.admin.storage.UpdateStoragePoolCmd; +import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd; +import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd; +import org.apache.cloudstack.api.command.user.volume.UploadVolumeCmd; +import org.apache.log4j.Logger; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; +import java.math.BigDecimal; +import java.net.*; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.util.*; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; @Local(value = { StorageManager.class, StorageService.class }) public class StorageManagerImpl implements StorageManager, Manager, ClusterManagerListener { @@ -1048,6 +967,9 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag LocalStorageSearch.join("poolHost", storageHostSearch, storageHostSearch.entity().getPoolId(), LocalStorageSearch.entity().getId(), JoinBuilder.JoinType.INNER); LocalStorageSearch.and("type", LocalStorageSearch.entity().getPoolType(), SearchCriteria.Op.IN); LocalStorageSearch.done(); + + Volume.State.getStateMachine().registerListener( new VolumeStateListener()); + return true; } 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 00000000000..da0ed113d3c --- /dev/null +++ b/server/src/com/cloud/storage/listener/VolumeStateListener.java @@ -0,0 +1,84 @@ +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 { + + protected static EventBus _eventBus = null; + + private static final Logger s_logger = Logger.getLogger(VolumeStateListener.class); + + public VolumeStateListener() { + initEventBusProvider(); + } + + @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) { + 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 eventDescription = new HashMap(); + 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 action 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; + } + + private void initEventBusProvider() { + ComponentLocator locator = ComponentLocator.getLocator(ManagementServer.Name); + Adapters eventBusImpls = locator.getAdapters(EventBus.class); + if (eventBusImpls != null) { + Enumeration eventBusenum = eventBusImpls.enumeration(); + if (eventBusenum != null && eventBusenum.hasMoreElements()) { + _eventBus = eventBusenum.nextElement(); + } + } + } + +}