diff --git a/api/src/com/cloud/vm/VirtualMachine.java b/api/src/com/cloud/vm/VirtualMachine.java index 82b09762016..6021846c376 100755 --- a/api/src/com/cloud/vm/VirtualMachine.java +++ b/api/src/com/cloud/vm/VirtualMachine.java @@ -127,6 +127,21 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, StateObject } return false; } + + public static boolean isVmCreated(State oldState, Event e, State newState) { + if (oldState == State.Destroyed && newState == State.Stopped) { + // VM recover + return true; + } + return false; + } + + public static boolean isVmDestroyed(State oldState, Event e, State newState) { + if (oldState == State.Stopped && newState == State.Destroyed) { + return true; + } + return false; + } } public enum Event { diff --git a/core/src/com/cloud/event/dao/UsageEventDao.java b/core/src/com/cloud/event/dao/UsageEventDao.java index 045721f0646..64b374ea746 100644 --- a/core/src/com/cloud/event/dao/UsageEventDao.java +++ b/core/src/com/cloud/event/dao/UsageEventDao.java @@ -23,9 +23,7 @@ import java.util.List; import com.cloud.event.UsageEventVO; import com.cloud.exception.UsageServerException; -import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericDao; -import com.cloud.utils.db.SearchCriteria; public interface UsageEventDao extends GenericDao { diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index b835f4fe26b..dedff4e399a 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -581,11 +581,11 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag VolumeVO createdVolume = null; SnapshotVO snapshot = _snapshotDao.findById(snapshotId); // Precondition: snapshot is not null and not removed. + Transaction txn = Transaction.currentTxn(); + txn.start(); Pair volumeDetails = createVolumeFromSnapshot(volume, snapshot); createdVolume = volumeDetails.first(); - Transaction txn = Transaction.currentTxn(); - txn.start(); Long diskOfferingId = volume.getDiskOfferingId(); if (createdVolume.getPath() != null) { @@ -1756,11 +1756,10 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag volume.setDomainId((account == null) ? Domain.ROOT_DOMAIN : account.getDomainId()); volume.setState(Volume.State.Allocated); volume = _volsDao.persist(volume); - UserContext.current().setEventDetails("Volume Id: " + volume.getId()); - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), diskOfferingId, null, size); - _usageEventDao.persist(usageEvent); + + UserContext.current().setEventDetails("Volume Id: " + volume.getId()); // Increment resource count during allocation; if actual creation fails, decrement it _accountMgr.incrementResourceCount(volume.getAccountId(), ResourceType.volume); diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index a4fbab2d016..69d08658465 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -596,9 +596,9 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma } else { s_logger.warn("Failed to back up snapshot on secondary storage, deleting the record from the DB"); + _snapshotDao.remove(snapshotId); UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_SNAPSHOT_DELETE, snapshot.getAccountId(), snapshot.getDataCenterId(), snapshotId, snapshot.getName(), null, null, 0L); _usageEventDao.persist(usageEvent); - _snapshotDao.remove(snapshotId); } txn.commit(); diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java index 4a8a4c4c436..3c1f138ec13 100755 --- a/server/src/com/cloud/user/AccountManagerImpl.java +++ b/server/src/com/cloud/user/AccountManagerImpl.java @@ -1087,9 +1087,6 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag s_logger.error("Unable to destroy vm: " + vm.getId()); accountCleanupNeeded = true; } - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VM_DESTROY, vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(), vm.getHostName(), vm.getServiceOfferingId(), - vm.getTemplateId(), vm.getHypervisorType().toString()); - _usageEventDao.persist(usageEvent); } // Mark the account's volumes as destroyed diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index a229b97836d..037c955ccfb 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -1113,10 +1113,6 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager _accountMgr.incrementResourceCount(account.getId(), ResourceType.volume, new Long(volumes.size())); - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VM_CREATE, vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(), vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(), vm - .getHypervisorType().toString()); - _usageEventDao.persist(usageEvent); - _accountMgr.incrementResourceCount(account.getId(), ResourceType.user_vm); txn.commit(); @@ -1153,6 +1149,8 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager _executor = Executors.newScheduledThreadPool(wrks, new NamedThreadFactory("UserVm-Scavenger")); _itMgr.registerGuru(VirtualMachine.Type.User, this); + + VirtualMachine.State.getStateMachine().registerListener(new UserVmStateListener(_usageEventDao, _networkDao, _nicDao)); s_logger.info("User VM Manager is configured."); @@ -1659,8 +1657,6 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager s_logger.warn("Unable to delete volume:" + volume.getId() + " for vm:" + vmId + " whilst transitioning to error state"); } } - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VM_DESTROY, vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(), vm.getHostName()); - _usageEventDao.persist(usageEvent); String msg = "Failed to deploy Vm with Id: " + vmId; _alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterIdToDeployIn(), vm.getPodIdToDeployIn(), msg, msg); @@ -2526,9 +2522,10 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager s_logger.debug("Successfully allocated DB entry for " + vm); } 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); - + _accountMgr.incrementResourceCount(accountId, ResourceType.user_vm); // Assign instance to the group @@ -2715,9 +2712,6 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager @Override public boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, ReservationContext context) { UserVmVO vm = profile.getVirtualMachine(); - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VM_START, vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(), vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(), vm - .getHypervisorType().toString()); - _usageEventDao.persist(usageEvent); Answer startAnswer = cmds.getAnswer(StartAnswer.class); String returnedIp = null; String originalIp = null; @@ -2736,7 +2730,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager for (NicVO nic : nics) { NetworkVO network = _networkDao.findById(nic.getNetworkId()); long isDefault = (nic.isDefaultNic()) ? 1 : 0; - usageEvent = new UsageEventVO(EventTypes.EVENT_NETWORK_OFFERING_ASSIGN, vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(), vm.getHostName(), network.getNetworkOfferingId(), null, isDefault); + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NETWORK_OFFERING_ASSIGN, vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(), vm.getHostName(), network.getNetworkOfferingId(), null, isDefault); _usageEventDao.persist(usageEvent); if (network.getTrafficType() == TrafficType.Guest) { originalIp = nic.getIp4Address(); @@ -2827,16 +2821,6 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager @Override public void finalizeStop(VirtualMachineProfile profile, StopAnswer answer) { - VMInstanceVO vm = profile.getVirtualMachine(); - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VM_STOP, vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(), vm.getHostName()); - _usageEventDao.persist(usageEvent); - - List nics = _nicDao.listByVmId(vm.getId()); - for (NicVO nic : nics) { - NetworkVO network = _networkDao.findById(nic.getNetworkId()); - usageEvent = new UsageEventVO(EventTypes.EVENT_NETWORK_OFFERING_REMOVE, vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(), null, network.getNetworkOfferingId(), null, 0L); - _usageEventDao.persist(usageEvent); - } } public String generateRandomPassword() { @@ -2912,8 +2896,6 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager _usageEventDao.persist(usageEvent); } } - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VM_DESTROY, vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(), vm.getHostName()); - _usageEventDao.persist(usageEvent); if (vmState != State.Error) { _accountMgr.decrementResourceCount(vm.getAccountId(), ResourceType.user_vm); diff --git a/server/src/com/cloud/vm/UserVmStateListener.java b/server/src/com/cloud/vm/UserVmStateListener.java new file mode 100644 index 00000000000..44fcef7fe3c --- /dev/null +++ b/server/src/com/cloud/vm/UserVmStateListener.java @@ -0,0 +1,83 @@ +/** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.cloud.vm; + +import java.util.List; + +import com.cloud.event.EventTypes; +import com.cloud.event.UsageEventVO; +import com.cloud.event.dao.UsageEventDao; +import com.cloud.network.NetworkVO; +import com.cloud.network.dao.NetworkDao; +import com.cloud.utils.fsm.StateListener; +import com.cloud.vm.VirtualMachine.Event; +import com.cloud.vm.VirtualMachine.State; +import com.cloud.vm.dao.NicDao; + +public class UserVmStateListener implements StateListener { + + protected UsageEventDao _usageEventDao; + protected NetworkDao _networkDao; + protected NicDao _nicDao; + + public UserVmStateListener(UsageEventDao usageEventDao, NetworkDao networkDao, NicDao nicDao) { + this._usageEventDao = usageEventDao; + this._networkDao = networkDao; + this._nicDao = nicDao; + } + + @Override + public boolean preStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vo, boolean status, Long id) { + return true; + } + + @Override + public boolean postStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vo, boolean status, Long id) { + if(!status){ + return false; + } + + if(vo.getType() != VirtualMachine.Type.User){ + return true; + } + + 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(), + 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(), + 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); + List 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); + } + } 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(), + vo.getTemplateId(), vo.getHypervisorType().toString()); + _usageEventDao.persist(usageEvent); + } + return true; + } +} diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index ed01e94d0a5..a2ef6fee5a6 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -65,7 +65,6 @@ import com.cloud.cluster.ClusterManager; import com.cloud.cluster.StackMaid; import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; -import com.cloud.configuration.ResourceCount.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.consoleproxy.ConsoleProxyManager; import com.cloud.dc.DataCenter; @@ -79,7 +78,6 @@ import com.cloud.deploy.DeploymentPlan; import com.cloud.deploy.DeploymentPlanner; import com.cloud.deploy.DeploymentPlanner.ExcludeList; import com.cloud.domain.dao.DomainDao; -import com.cloud.event.dao.UsageEventDao; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.ConnectionException; @@ -185,8 +183,6 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene @Inject protected SecondaryStorageVmDao _secondaryDao; @Inject - protected UsageEventDao _usageEventDao; - @Inject protected NicDao _nicsDao; @Inject protected AccountManager _accountMgr;