diff --git a/api/src/com/cloud/storage/Volume.java b/api/src/com/cloud/storage/Volume.java index 82b673b1bac..f0c7000748b 100755 --- a/api/src/com/cloud/storage/Volume.java +++ b/api/src/com/cloud/storage/Volume.java @@ -16,6 +16,7 @@ // under the License. package com.cloud.storage; +import java.util.Arrays; import java.util.Date; import org.apache.cloudstack.acl.ControlledEntity; @@ -64,38 +65,42 @@ public interface Volume extends ControlledEntity, Identity, InternalIdentity, Ba private final static StateMachine2 s_fsm = new StateMachine2(); static { - s_fsm.addTransition(Allocated, Event.CreateRequested, Creating); - s_fsm.addTransition(Allocated, Event.DestroyRequested, Destroy); - s_fsm.addTransition(Creating, Event.OperationRetry, Creating); - s_fsm.addTransition(Creating, Event.OperationFailed, Allocated); - s_fsm.addTransition(Creating, Event.OperationSucceeded, Ready); - s_fsm.addTransition(Creating, Event.CreateRequested, Creating); - s_fsm.addTransition(Ready, Event.ResizeRequested, Resizing); - s_fsm.addTransition(Resizing, Event.OperationSucceeded, Ready); - s_fsm.addTransition(Resizing, Event.OperationFailed, Ready); - s_fsm.addTransition(Allocated, Event.UploadRequested, UploadOp); - s_fsm.addTransition(Uploaded, Event.CopyRequested, Copying); - s_fsm.addTransition(Copying, Event.OperationSucceeded, Ready); - s_fsm.addTransition(Copying, Event.OperationFailed, Uploaded); - s_fsm.addTransition(UploadOp, Event.DestroyRequested, Destroy); - s_fsm.addTransition(Ready, Event.DestroyRequested, Destroy); - s_fsm.addTransition(Destroy, Event.ExpungingRequested, Expunging); - s_fsm.addTransition(Expunging, Event.ExpungingRequested, Expunging); - s_fsm.addTransition(Expunging, Event.OperationSucceeded, Expunged); - s_fsm.addTransition(Expunging, Event.OperationFailed, Destroy); - s_fsm.addTransition(Ready, Event.SnapshotRequested, Snapshotting); - s_fsm.addTransition(Snapshotting, Event.OperationSucceeded, Ready); - s_fsm.addTransition(Snapshotting, Event.OperationFailed, Ready); - s_fsm.addTransition(Ready, Event.MigrationRequested, Migrating); - s_fsm.addTransition(Migrating, Event.OperationSucceeded, Ready); - s_fsm.addTransition(Migrating, Event.OperationFailed, Ready); - s_fsm.addTransition(Destroy, Event.OperationSucceeded, Destroy); - s_fsm.addTransition(UploadOp, Event.OperationSucceeded, Uploaded); - s_fsm.addTransition(UploadOp, Event.OperationFailed, Allocated); - s_fsm.addTransition(Uploaded, Event.DestroyRequested, Destroy); - s_fsm.addTransition(Expunged, Event.ExpungingRequested, Expunged); - s_fsm.addTransition(Expunged, Event.OperationSucceeded, Expunged); - s_fsm.addTransition(Expunged, Event.OperationFailed, Expunged); + s_fsm.addTransition(new StateMachine2.Transition(Allocated, Event.CreateRequested, Creating, null)); + s_fsm.addTransition(new StateMachine2.Transition(Allocated, Event.DestroyRequested, Destroy, null)); + s_fsm.addTransition(new StateMachine2.Transition(Creating, Event.OperationRetry, Creating, null)); + s_fsm.addTransition(new StateMachine2.Transition(Creating, Event.OperationFailed, Allocated, null)); + s_fsm.addTransition(new StateMachine2.Transition(Creating, Event.OperationSucceeded, Ready, null)); + s_fsm.addTransition(new StateMachine2.Transition(Creating, Event.DestroyRequested, Destroy, null)); + s_fsm.addTransition(new StateMachine2.Transition(Creating, Event.CreateRequested, Creating, null)); + s_fsm.addTransition(new StateMachine2.Transition(Ready, Event.ResizeRequested, Resizing, null)); + s_fsm.addTransition(new StateMachine2.Transition(Resizing, Event.OperationSucceeded, Ready, Arrays.asList(new StateMachine2.Transition.Impact[]{StateMachine2.Transition.Impact.USAGE}))); + s_fsm.addTransition(new StateMachine2.Transition(Resizing, Event.OperationFailed, Ready, null)); + s_fsm.addTransition(new StateMachine2.Transition(Allocated, Event.UploadRequested, UploadOp, null)); + s_fsm.addTransition(new StateMachine2.Transition(Uploaded, Event.CopyRequested, Copying, null)); + s_fsm.addTransition(new StateMachine2.Transition(Copying, Event.OperationSucceeded, Ready, Arrays.asList(new StateMachine2.Transition.Impact[]{StateMachine2.Transition.Impact.USAGE}))); + s_fsm.addTransition(new StateMachine2.Transition(Copying, Event.OperationFailed, Uploaded, null)); + s_fsm.addTransition(new StateMachine2.Transition(UploadOp, Event.DestroyRequested, Destroy, null)); + s_fsm.addTransition(new StateMachine2.Transition(Ready, Event.DestroyRequested, Destroy, null)); + s_fsm.addTransition(new StateMachine2.Transition(Destroy, Event.ExpungingRequested, Expunging, null)); + s_fsm.addTransition(new StateMachine2.Transition(Expunging, Event.ExpungingRequested, Expunging, null)); + s_fsm.addTransition(new StateMachine2.Transition(Expunging, Event.OperationSucceeded, Expunged,null)); + s_fsm.addTransition(new StateMachine2.Transition(Expunging, Event.OperationFailed, Destroy, null)); + s_fsm.addTransition(new StateMachine2.Transition(Ready, Event.SnapshotRequested, Snapshotting, null)); + s_fsm.addTransition(new StateMachine2.Transition(Snapshotting, Event.OperationSucceeded, Ready, null)); + s_fsm.addTransition(new StateMachine2.Transition(Snapshotting, Event.OperationFailed, Ready,null)); + s_fsm.addTransition(new StateMachine2.Transition(Allocated, Event.MigrationCopyRequested, Creating, null)); + s_fsm.addTransition(new StateMachine2.Transition(Creating, Event.MigrationCopyFailed, Allocated, null)); + s_fsm.addTransition(new StateMachine2.Transition(Creating, Event.MigrationCopySucceeded, Ready, Arrays.asList(new StateMachine2.Transition.Impact[]{StateMachine2.Transition.Impact.USAGE}))); + s_fsm.addTransition(new StateMachine2.Transition(Ready, Event.MigrationRequested, Migrating, null)); + s_fsm.addTransition(new StateMachine2.Transition(Migrating, Event.OperationSucceeded, Ready, null)); + s_fsm.addTransition(new StateMachine2.Transition(Migrating, Event.OperationFailed, Ready, null)); + s_fsm.addTransition(new StateMachine2.Transition(Destroy, Event.OperationSucceeded, Destroy, Arrays.asList(new StateMachine2.Transition.Impact[]{StateMachine2.Transition.Impact.USAGE}))); + s_fsm.addTransition(new StateMachine2.Transition(UploadOp, Event.OperationSucceeded, Uploaded, null)); + s_fsm.addTransition(new StateMachine2.Transition(UploadOp, Event.OperationFailed, Allocated, null)); + s_fsm.addTransition(new StateMachine2.Transition(Uploaded, Event.DestroyRequested, Destroy, null)); + s_fsm.addTransition(new StateMachine2.Transition(Expunged, Event.ExpungingRequested, Expunged, null)); + s_fsm.addTransition(new StateMachine2.Transition(Expunged, Event.OperationSucceeded, Expunged, null)); + s_fsm.addTransition(new StateMachine2.Transition(Expunged, Event.OperationFailed, Expunged,null)); } } @@ -109,6 +114,9 @@ public interface Volume extends ControlledEntity, Identity, InternalIdentity, Ba OperationRetry, UploadRequested, MigrationRequested, + MigrationCopyRequested, + MigrationCopySucceeded, + MigrationCopyFailed, SnapshotRequested, DestroyRequested, ExpungingRequested, diff --git a/api/src/com/cloud/vm/VirtualMachine.java b/api/src/com/cloud/vm/VirtualMachine.java index 99152d65fd1..2a6039fac36 100755 --- a/api/src/com/cloud/vm/VirtualMachine.java +++ b/api/src/com/cloud/vm/VirtualMachine.java @@ -98,7 +98,7 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, Identity, I s_fsm.addTransition(new Transition(State.Starting, VirtualMachine.Event.AgentReportRunning, State.Running, Arrays.asList(new Impact[]{Impact.USAGE}))); s_fsm.addTransition(new Transition(State.Starting, VirtualMachine.Event.AgentReportStopped, State.Stopped, null)); s_fsm.addTransition(new Transition(State.Starting, VirtualMachine.Event.AgentReportShutdowned, State.Stopped, null)); - s_fsm.addTransition(new Transition(State.Destroyed, VirtualMachine.Event.RecoveryRequested, State.Stopped, null)); + s_fsm.addTransition(new Transition(State.Destroyed, VirtualMachine.Event.RecoveryRequested, State.Stopped, Arrays.asList(new Impact[]{Impact.USAGE}))); s_fsm.addTransition(new Transition(State.Destroyed, VirtualMachine.Event.ExpungeOperation, State.Expunging, null)); s_fsm.addTransition(new Transition(State.Running, VirtualMachine.Event.MigrationRequested, State.Migrating, null)); s_fsm.addTransition(new Transition(State.Running, VirtualMachine.Event.AgentReportRunning, State.Running, null)); diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ObjectInDataStoreStateMachine.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ObjectInDataStoreStateMachine.java index b21616a5094..204cab0bd74 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ObjectInDataStoreStateMachine.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ObjectInDataStoreStateMachine.java @@ -51,6 +51,9 @@ public interface ObjectInDataStoreStateMachine extends StateObject context = new CopyVolumeContext(null, future, srcVolume, destVolume, destStore); @@ -1009,7 +1009,7 @@ public class VolumeServiceImpl implements VolumeService { try { if (result.isFailed()) { res.setResult(result.getResult()); - destVolume.processEvent(Event.OperationFailed); + destVolume.processEvent(Event.MigrationCopyFailed); srcVolume.processEvent(Event.OperationFailed); destroyVolume(destVolume.getId()); destVolume = volFactory.getVolume(destVolume.getId()); @@ -1019,7 +1019,7 @@ public class VolumeServiceImpl implements VolumeService { return null; } srcVolume.processEvent(Event.OperationSuccessed); - destVolume.processEvent(Event.OperationSuccessed, result.getAnswer()); + destVolume.processEvent(Event.MigrationCopySucceeded, result.getAnswer()); volDao.updateUuid(srcVolume.getId(), destVolume.getId()); try { destroyVolume(srcVolume.getId()); 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 dc71e5b0467..f95ad80a175 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalManagerImpl.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalManagerImpl.java @@ -18,33 +18,24 @@ // Automatically generated by addcopyright.py at 01/29/2013 package com.cloud.baremetal.manager; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import javax.ejb.Local; -import javax.inject.Inject; -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; -import org.apache.log4j.Logger; - -import org.apache.cloudstack.api.AddBaremetalHostCmd; - import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.fsm.StateListener; +import com.cloud.utils.fsm.StateMachine2; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.Event; import com.cloud.vm.VirtualMachine.State; +import org.apache.cloudstack.api.AddBaremetalHostCmd; +import org.apache.log4j.Logger; + +import javax.ejb.Local; +import javax.inject.Inject; +import javax.naming.ConfigurationException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; @Local(value = {BaremetalManager.class}) public class BaremetalManagerImpl extends ManagerBase implements BaremetalManager, StateListener { diff --git a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java index 15c4f085282..97cbf623b6d 100644 --- a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java @@ -120,6 +120,7 @@ import com.cloud.utils.Pair; import com.cloud.utils.db.DB; import com.cloud.utils.db.EntityManager; import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.fsm.StateMachine2; import com.cloud.utils.net.NetUtils; import com.cloud.vm.DomainRouterVO; import com.cloud.vm.Nic; @@ -1483,7 +1484,7 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian } @Override - public boolean postStateTransitionEvent(State oldState, VirtualMachine.Event event, State newState, VirtualMachine vo, boolean status, Object opaque) { + public boolean postStateTransitionEvent(final StateMachine2.Transition transition, final VirtualMachine vo, final boolean status, final Object opaque) { // Without this VirtualNetworkApplianceManagerImpl.postStateTransitionEvent() gets called twice as part of listeners - // once from VpcVirtualNetworkApplianceManagerImpl and once from VirtualNetworkApplianceManagerImpl itself return true; diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 5ea44a2330f..c7b3c3502eb 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -499,7 +499,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C LocalStorageSearch.and("type", LocalStorageSearch.entity().getPoolType(), SearchCriteria.Op.IN); LocalStorageSearch.done(); - Volume.State.getStateMachine().registerListener(new VolumeStateListener(_configDao)); + Volume.State.getStateMachine().registerListener(new VolumeStateListener(_configDao, _vmInstanceDao)); return true; } diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java index 219a48299c7..7fe8893d890 100644 --- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java @@ -1057,9 +1057,6 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic } _volsDao.update(volume.getId(), volume); - // Log usage event for volumes belonging user VM's only - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_RESIZE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), - volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(), volume.getUuid()); /* Update resource count for the account on primary storage resource */ if (!shrinkOk) { @@ -1125,10 +1122,6 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic } else { _resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(), ResourceType.secondary_storage.getOrdinal()); } - - // Log usage event for volumes belonging user VM's only - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), - Volume.class.getName(), volume.getUuid(), volume.isDisplayVolume()); } } // Mark volume as removed if volume has not been created on primary or secondary diff --git a/server/src/com/cloud/storage/listener/VolumeStateListener.java b/server/src/com/cloud/storage/listener/VolumeStateListener.java index 0ba2969a76a..9fd1423d1fe 100644 --- a/server/src/com/cloud/storage/listener/VolumeStateListener.java +++ b/server/src/com/cloud/storage/listener/VolumeStateListener.java @@ -22,7 +22,12 @@ import java.util.Date; import java.util.HashMap; import java.util.Map; +import com.cloud.event.EventTypes; +import com.cloud.event.UsageEventUtils; import com.cloud.utils.fsm.StateMachine2; +import com.cloud.vm.VMInstanceVO; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.dao.VMInstanceDao; import org.apache.log4j.Logger; import org.springframework.beans.factory.NoSuchBeanDefinitionException; @@ -43,11 +48,13 @@ public class VolumeStateListener implements StateListener protected static EventBus s_eventBus = null; protected ConfigurationDao _configDao; + protected VMInstanceDao _vmInstanceDao; private static final Logger s_logger = Logger.getLogger(VolumeStateListener.class); - public VolumeStateListener(ConfigurationDao configDao) { + public VolumeStateListener(ConfigurationDao configDao, VMInstanceDao vmInstanceDao) { this._configDao = configDao; + this._vmInstanceDao = vmInstanceDao; } @Override @@ -57,8 +64,32 @@ public class VolumeStateListener implements StateListener } @Override - public boolean postStateTransitionEvent(StateMachine2.Transition transition, Volume vo, boolean status, Object opaque) { - pubishOnEventBus(transition.getEvent().name(), "postStateTransitionEvent", vo, transition.getCurrentState(), transition.getToState()); + public boolean postStateTransitionEvent(StateMachine2.Transition transition, Volume vol, boolean status, Object opaque) { + pubishOnEventBus(transition.getEvent().name(), "postStateTransitionEvent", vol, transition.getCurrentState(), transition.getToState()); + if(transition.isImpacted(StateMachine2.Transition.Impact.USAGE)) { + Long instanceId = vol.getInstanceId(); + VMInstanceVO vmInstanceVO = null; + if(instanceId != null) { + vmInstanceVO = _vmInstanceDao.findById(instanceId); + } + if(instanceId == null || vmInstanceVO.getType() == VirtualMachine.Type.User) { + if (transition.getToState() == State.Ready) { + if (transition.getCurrentState() == State.Resizing) { + // Log usage event for volumes belonging user VM's only + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_RESIZE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), + vol.getDiskOfferingId(), vol.getTemplateId(), vol.getSize(), Volume.class.getName(), vol.getUuid()); + } else { + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), vol.getDiskOfferingId(), null, vol.getSize(), + Volume.class.getName(), vol.getUuid(), vol.isDisplayVolume()); + } + } else if (transition.getToState() == State.Destroy) { + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), + Volume.class.getName(), vol.getUuid(), vol.isDisplayVolume()); + } else if (transition.getToState() == State.Uploaded) { + //Currently we are not capturing Usage for Secondary Storage so Usage for this operation will be captured when it is moved to primary storage + } + } + } return true; }