mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
refactor vmstatelistener
This commit is contained in:
parent
5be450ff47
commit
fc97034000
@ -18,20 +18,19 @@
|
||||
package com.cloud.vm;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.cloud.acl.ControlledEntity;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.utils.fsm.FiniteState;
|
||||
import com.cloud.utils.fsm.StateMachine;
|
||||
import com.cloud.utils.fsm.StateMachine2;
|
||||
import com.cloud.utils.fsm.StateObject;
|
||||
|
||||
|
||||
/**
|
||||
* VirtualMachine describes the properties held by a virtual machine
|
||||
*
|
||||
*/
|
||||
public interface VirtualMachine extends RunningOn, ControlledEntity {
|
||||
public enum State implements FiniteState<State, Event> {
|
||||
public interface VirtualMachine extends RunningOn, ControlledEntity, StateObject<VirtualMachine.State> {
|
||||
public enum State {
|
||||
Starting(true, "VM is being started. At this state, you should find host id filled which means it's being started on that host."),
|
||||
Running(false, "VM is running. host id has the host that it is running on."),
|
||||
Stopping(true, "VM is being stopped. host id has the host that it is being stopped on."),
|
||||
@ -52,7 +51,6 @@ public interface VirtualMachine extends RunningOn, ControlledEntity {
|
||||
_description = description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return _description;
|
||||
}
|
||||
@ -61,68 +59,71 @@ public interface VirtualMachine extends RunningOn, ControlledEntity {
|
||||
return _transitional;
|
||||
}
|
||||
|
||||
@Override
|
||||
public State getNextState(VirtualMachine.Event e) {
|
||||
return s_fsm.getNextState(this, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<State> getFromStates(VirtualMachine.Event e) {
|
||||
return s_fsm.getFromStates(this, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Event> getPossibleEvents() {
|
||||
return s_fsm.getPossibleEvents(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StateMachine<State, Event> getStateMachine() {
|
||||
public static StateMachine2<State, VirtualMachine.Event, VirtualMachine> getStateMachine() {
|
||||
return s_fsm;
|
||||
}
|
||||
|
||||
|
||||
protected static final StateMachine<State, VirtualMachine.Event> s_fsm = new StateMachine<State, VirtualMachine.Event>();
|
||||
protected static final StateMachine2<State, VirtualMachine.Event, VirtualMachine> s_fsm = new StateMachine2<State, VirtualMachine.Event, VirtualMachine>();
|
||||
static {
|
||||
// s_fsm.addTransition(null, VirtualMachine.Event.CreateRequested, State.Creating);
|
||||
// s_fsm.addTransition(State.Creating, VirtualMachine.Event.OperationSucceeded, State.Stopped);
|
||||
// s_fsm.addTransition(State.Creating, VirtualMachine.Event.OperationFailed, State.Error);
|
||||
s_fsm.addTransition(State.Stopped, VirtualMachine.Event.StartRequested, State.Starting);
|
||||
s_fsm.addTransition(State.Stopped, VirtualMachine.Event.DestroyRequested, State.Destroyed);
|
||||
s_fsm.addTransition(State.Error, VirtualMachine.Event.DestroyRequested, State.Destroyed);
|
||||
s_fsm.addTransition(State.Stopped, VirtualMachine.Event.StopRequested, State.Stopped);
|
||||
s_fsm.addTransition(State.Stopped, VirtualMachine.Event.AgentReportStopped, State.Stopped);
|
||||
s_fsm.addTransition(State.Stopped, VirtualMachine.Event.StartRequested, State.Starting);
|
||||
s_fsm.addTransition(State.Stopped, VirtualMachine.Event.DestroyRequested, State.Destroyed);
|
||||
s_fsm.addTransition(State.Stopped, VirtualMachine.Event.StopRequested, State.Stopped);
|
||||
s_fsm.addTransition(State.Stopped, VirtualMachine.Event.AgentReportStopped, State.Stopped);
|
||||
s_fsm.addTransition(State.Stopped, VirtualMachine.Event.OperationFailed, State.Error);
|
||||
s_fsm.addTransition(State.Stopped, VirtualMachine.Event.ExpungeOperation, State.Expunging);
|
||||
s_fsm.addTransition(State.Stopped, VirtualMachine.Event.AgentReportShutdowned, State.Stopped);
|
||||
s_fsm.addTransition(State.Starting, VirtualMachine.Event.OperationRetry, State.Starting);
|
||||
s_fsm.addTransition(State.Starting, VirtualMachine.Event.OperationSucceeded, State.Running);
|
||||
s_fsm.addTransition(State.Starting, VirtualMachine.Event.OperationFailed, State.Stopped);
|
||||
s_fsm.addTransition(State.Starting, VirtualMachine.Event.AgentReportRunning, State.Running);
|
||||
s_fsm.addTransition(State.Starting, VirtualMachine.Event.AgentReportStopped, State.Stopped);
|
||||
s_fsm.addTransition(State.Starting, VirtualMachine.Event.OperationRetry, State.Starting);
|
||||
s_fsm.addTransition(State.Starting, VirtualMachine.Event.OperationSucceeded, State.Running);
|
||||
s_fsm.addTransition(State.Starting, VirtualMachine.Event.OperationFailed, State.Stopped);
|
||||
s_fsm.addTransition(State.Starting, VirtualMachine.Event.AgentReportRunning, State.Running);
|
||||
s_fsm.addTransition(State.Starting, VirtualMachine.Event.AgentReportStopped, State.Stopped);
|
||||
s_fsm.addTransition(State.Starting, VirtualMachine.Event.AgentReportShutdowned, State.Stopped);
|
||||
s_fsm.addTransition(State.Destroyed, VirtualMachine.Event.RecoveryRequested, State.Stopped);
|
||||
s_fsm.addTransition(State.Destroyed, VirtualMachine.Event.ExpungeOperation, State.Expunging);
|
||||
// s_fsm.addTransition(State.Creating, VirtualMachine.Event.MigrationRequested, State.Destroyed);
|
||||
s_fsm.addTransition(State.Running, VirtualMachine.Event.MigrationRequested, State.Migrating);
|
||||
s_fsm.addTransition(State.Running, VirtualMachine.Event.AgentReportRunning, State.Running);
|
||||
s_fsm.addTransition(State.Running, VirtualMachine.Event.AgentReportStopped, State.Stopped);
|
||||
s_fsm.addTransition(State.Running, VirtualMachine.Event.StopRequested, State.Stopping);
|
||||
s_fsm.addTransition(State.Destroyed, VirtualMachine.Event.RecoveryRequested, State.Stopped);
|
||||
s_fsm.addTransition(State.Destroyed, VirtualMachine.Event.ExpungeOperation, State.Expunging);
|
||||
s_fsm.addTransition(State.Running, VirtualMachine.Event.MigrationRequested, State.Migrating);
|
||||
s_fsm.addTransition(State.Running, VirtualMachine.Event.AgentReportRunning, State.Running);
|
||||
s_fsm.addTransition(State.Running, VirtualMachine.Event.AgentReportStopped, State.Stopped);
|
||||
s_fsm.addTransition(State.Running, VirtualMachine.Event.StopRequested, State.Stopping);
|
||||
s_fsm.addTransition(State.Running, VirtualMachine.Event.AgentReportShutdowned, State.Stopped);
|
||||
s_fsm.addTransition(State.Migrating, VirtualMachine.Event.MigrationRequested, State.Migrating);
|
||||
s_fsm.addTransition(State.Migrating, VirtualMachine.Event.OperationSucceeded, State.Running);
|
||||
s_fsm.addTransition(State.Migrating, VirtualMachine.Event.OperationFailed, State.Running);
|
||||
s_fsm.addTransition(State.Migrating, VirtualMachine.Event.MigrationFailedOnSource, State.Running);
|
||||
s_fsm.addTransition(State.Migrating, VirtualMachine.Event.MigrationFailedOnDest, State.Running);
|
||||
s_fsm.addTransition(State.Migrating, VirtualMachine.Event.AgentReportRunning, State.Running);
|
||||
s_fsm.addTransition(State.Migrating, VirtualMachine.Event.AgentReportStopped, State.Stopped);
|
||||
s_fsm.addTransition(State.Migrating, VirtualMachine.Event.MigrationRequested, State.Migrating);
|
||||
s_fsm.addTransition(State.Migrating, VirtualMachine.Event.OperationSucceeded, State.Running);
|
||||
s_fsm.addTransition(State.Migrating, VirtualMachine.Event.OperationFailed, State.Running);
|
||||
s_fsm.addTransition(State.Migrating, VirtualMachine.Event.MigrationFailedOnSource, State.Running);
|
||||
s_fsm.addTransition(State.Migrating, VirtualMachine.Event.MigrationFailedOnDest, State.Running);
|
||||
s_fsm.addTransition(State.Migrating, VirtualMachine.Event.AgentReportRunning, State.Running);
|
||||
s_fsm.addTransition(State.Migrating, VirtualMachine.Event.AgentReportStopped, State.Stopped);
|
||||
s_fsm.addTransition(State.Migrating, VirtualMachine.Event.AgentReportShutdowned, State.Stopped);
|
||||
s_fsm.addTransition(State.Stopping, VirtualMachine.Event.OperationSucceeded, State.Stopped);
|
||||
s_fsm.addTransition(State.Stopping, VirtualMachine.Event.OperationFailed, State.Running);
|
||||
s_fsm.addTransition(State.Stopping, VirtualMachine.Event.AgentReportRunning, State.Running);
|
||||
s_fsm.addTransition(State.Stopping, VirtualMachine.Event.AgentReportStopped, State.Stopped);
|
||||
s_fsm.addTransition(State.Stopping, VirtualMachine.Event.StopRequested, State.Stopping);
|
||||
s_fsm.addTransition(State.Stopping, VirtualMachine.Event.OperationSucceeded, State.Stopped);
|
||||
s_fsm.addTransition(State.Stopping, VirtualMachine.Event.OperationFailed, State.Running);
|
||||
s_fsm.addTransition(State.Stopping, VirtualMachine.Event.AgentReportRunning, State.Running);
|
||||
s_fsm.addTransition(State.Stopping, VirtualMachine.Event.AgentReportStopped, State.Stopped);
|
||||
s_fsm.addTransition(State.Stopping, VirtualMachine.Event.StopRequested, State.Stopping);
|
||||
s_fsm.addTransition(State.Stopping, VirtualMachine.Event.AgentReportShutdowned, State.Stopped);
|
||||
s_fsm.addTransition(State.Expunging, VirtualMachine.Event.OperationFailed, State.Expunging);
|
||||
s_fsm.addTransition(State.Expunging, VirtualMachine.Event.ExpungeOperation, State.Expunging);
|
||||
s_fsm.addTransition(State.Expunging, VirtualMachine.Event.OperationFailed, State.Expunging);
|
||||
s_fsm.addTransition(State.Expunging, VirtualMachine.Event.ExpungeOperation, State.Expunging);
|
||||
s_fsm.addTransition(State.Error, VirtualMachine.Event.DestroyRequested, State.Expunging);
|
||||
s_fsm.addTransition(State.Error, VirtualMachine.Event.ExpungeOperation, State.Expunging);
|
||||
}
|
||||
|
||||
public static boolean isVmStarted(State oldState, Event e, State newState) {
|
||||
if (oldState == State.Starting && newState == State.Running) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isVmStopped(State oldState, Event e, State newState) {
|
||||
if (oldState == State.Stopping && newState == State.Stopped) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isVmMigrated(State oldState, Event e, State newState) {
|
||||
if (oldState == State.Migrating && newState == State.Running && (e == Event.OperationSucceeded || e == Event.AgentReportRunning)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -182,7 +183,7 @@ public interface VirtualMachine extends RunningOn, ControlledEntity {
|
||||
/**
|
||||
* @return the state of the virtual machine
|
||||
*/
|
||||
public State getState();
|
||||
//public State getState();
|
||||
|
||||
/**
|
||||
* @return template id.
|
||||
@ -209,7 +210,9 @@ public interface VirtualMachine extends RunningOn, ControlledEntity {
|
||||
* @return id of the host it was assigned last time.
|
||||
*/
|
||||
public Long getLastHostId();
|
||||
|
||||
|
||||
public void setLastHostId(Long lastHostId);
|
||||
|
||||
/**
|
||||
* @return should HA be enabled for this machine?
|
||||
*/
|
||||
|
||||
@ -74,9 +74,6 @@
|
||||
<adapters key="com.cloud.deploy.DeploymentPlanner">
|
||||
<adapter name="First Fit" class="com.cloud.deploy.FirstFitPlanner"/>
|
||||
</adapters>
|
||||
<adapters key="com.cloud.utils.fsm.StateListener">
|
||||
<adapter name="VMStateListener" class="com.cloud.stateListener.VMStateListener"/>
|
||||
</adapters>
|
||||
<adapters key="com.cloud.network.element.NetworkElement">
|
||||
<adapter name="DomainRouter" class="com.cloud.network.element.VirtualRouterElement"/>
|
||||
<adapter name="Dhcp" class="com.cloud.network.element.DhcpElement"/>
|
||||
|
||||
@ -39,14 +39,13 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import com.cloud.utils.db.StateMachine;
|
||||
import com.cloud.utils.fsm.FiniteStateObject;
|
||||
import com.cloud.utils.fsm.StateObject;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
|
||||
@Entity
|
||||
@Table(name="vm_instance")
|
||||
@Inheritance(strategy=InheritanceType.JOINED)
|
||||
@DiscriminatorColumn(name="type", discriminatorType=DiscriminatorType.STRING, length=32)
|
||||
public class VMInstanceVO implements VirtualMachine, FiniteStateObject<State, VirtualMachine.Event>, StateObject<State> {
|
||||
public class VMInstanceVO implements VirtualMachine, FiniteStateObject<State, VirtualMachine.Event> {
|
||||
@Id
|
||||
@TableGenerator(name="vm_instance_sq", table="sequence", pkColumnName="name", valueColumnName="value", pkColumnValue="vm_instance_seq", allocationSize=1)
|
||||
@Column(name="id", updatable=false, nullable = false)
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package com.cloud.capacity;
|
||||
|
||||
import com.cloud.utils.component.Manager;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
|
||||
/**
|
||||
* Capacity Manager manages the different capacities
|
||||
@ -8,5 +9,7 @@ import com.cloud.utils.component.Manager;
|
||||
*
|
||||
*/
|
||||
public interface CapacityManager extends Manager {
|
||||
public boolean releaseVmCapacity(VirtualMachine vm, boolean moveFromReserved, boolean moveToReservered, Long hostId);
|
||||
|
||||
boolean allocateVmCapacity(long hostId, Integer cpu, long ram, boolean fromLastHost);
|
||||
}
|
||||
|
||||
@ -17,30 +17,75 @@
|
||||
*/
|
||||
package com.cloud.capacity;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
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.capacity.dao.CapacityDao;
|
||||
import com.cloud.utils.component.Inject;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.capacity.dao.CapacityDao;
|
||||
import com.cloud.configuration.Config;
|
||||
import com.cloud.configuration.dao.ConfigurationDao;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.Status;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.service.ServiceOfferingVO;
|
||||
import com.cloud.service.dao.ServiceOfferingDao;
|
||||
import com.cloud.utils.DateUtil;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.component.Inject;
|
||||
import com.cloud.utils.concurrency.NamedThreadFactory;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
|
||||
@Local(value=CapacityManager.class)
|
||||
public class CapacityManagerImpl implements CapacityManager {
|
||||
private static final Logger s_logger = Logger.getLogger(CapacityManagerImpl.class);
|
||||
String _name;
|
||||
@Inject CapacityDao _capacityDao;
|
||||
@Inject ConfigurationDao _configDao;
|
||||
@Inject ServiceOfferingDao _offeringsDao;
|
||||
@Inject HostDao _hostDao;
|
||||
@Inject VMInstanceDao _vmDao;
|
||||
private int _hostCapacityCheckerDelay;
|
||||
private int _hostCapacityCheckerInterval;
|
||||
private int _vmCapacityReleaseInterval;
|
||||
private ScheduledExecutorService _executor;
|
||||
private boolean _stopped;
|
||||
|
||||
|
||||
@Override
|
||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
_name = name;
|
||||
_hostCapacityCheckerDelay = NumbersUtil.parseInt(_configDao.getValue(Config.HostCapacityCheckerWait.key()), 3600);
|
||||
_hostCapacityCheckerInterval = NumbersUtil.parseInt(_configDao.getValue(Config.HostCapacityCheckerInterval.key()), 3600);
|
||||
_vmCapacityReleaseInterval = NumbersUtil.parseInt(_configDao.getValue(Config.VmHostCapacityReleaseInterval.key()), 86400);
|
||||
_executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("HostCapacity-Checker"));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean start() {
|
||||
_executor.schedule(new HostCapacityCollector(), _hostCapacityCheckerDelay, TimeUnit.SECONDS);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stop() {
|
||||
_executor.shutdownNow();
|
||||
_stopped = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -48,4 +93,241 @@ public class CapacityManagerImpl implements CapacityManager {
|
||||
public String getName() {
|
||||
return _name;
|
||||
}
|
||||
|
||||
@DB
|
||||
@Override
|
||||
public boolean releaseVmCapacity(VirtualMachine vm, boolean moveFromReserved, boolean moveToReservered, Long hostId) {
|
||||
ServiceOfferingVO svo = _offeringsDao.findById(vm.getServiceOfferingId());
|
||||
CapacityVO capacityCpu = _capacityDao.findByHostIdType(hostId, CapacityVO.CAPACITY_TYPE_CPU);
|
||||
CapacityVO capacityMemory = _capacityDao.findByHostIdType(hostId, CapacityVO.CAPACITY_TYPE_MEMORY);
|
||||
|
||||
if (capacityCpu == null || capacityMemory == null || svo == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
try {
|
||||
txn.start();
|
||||
|
||||
int vmCPU = svo.getCpu() * svo.getSpeed();
|
||||
long vmMem = svo.getRamSize() * 1024L * 1024L;
|
||||
|
||||
capacityCpu = _capacityDao.lockRow(capacityCpu.getId(), true);
|
||||
capacityMemory = _capacityDao.lockRow(capacityMemory.getId(), true);
|
||||
|
||||
long usedCpu = capacityCpu.getUsedCapacity();
|
||||
long usedMem = capacityMemory.getUsedCapacity();
|
||||
long reservedCpu = capacityCpu.getReservedCapacity();
|
||||
long reservedMem = capacityMemory.getReservedCapacity();
|
||||
long totalCpu = capacityCpu.getTotalCapacity();
|
||||
long totalMem = capacityMemory.getTotalCapacity();
|
||||
|
||||
if (!moveFromReserved) {
|
||||
/*move resource from used*/
|
||||
if (usedCpu >= vmCPU) {
|
||||
capacityCpu.setUsedCapacity(usedCpu - vmCPU);
|
||||
}
|
||||
if (usedMem >= vmMem) {
|
||||
capacityMemory.setUsedCapacity(usedMem - vmMem);
|
||||
}
|
||||
|
||||
if (moveToReservered) {
|
||||
if (reservedCpu + vmCPU <= totalCpu) {
|
||||
capacityCpu.setReservedCapacity(reservedCpu + vmCPU);
|
||||
}
|
||||
if (reservedMem + vmMem <= totalMem) {
|
||||
capacityMemory.setReservedCapacity(reservedMem + vmMem);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (reservedCpu >= vmCPU) {
|
||||
capacityCpu.setReservedCapacity(reservedCpu - vmCPU);
|
||||
}
|
||||
if (reservedMem >= vmMem) {
|
||||
capacityMemory.setReservedCapacity(reservedMem - vmMem);
|
||||
}
|
||||
}
|
||||
|
||||
s_logger.debug("release cpu from host: " + hostId + ", old used: " + usedCpu + ",reserved: " + reservedCpu + ", total: " + totalCpu +
|
||||
"; new used: " + capacityCpu.getUsedCapacity() + ",reserved:" + capacityCpu.getReservedCapacity() + ",total: " + capacityCpu.getTotalCapacity() +
|
||||
"; movedfromreserved: " + moveFromReserved + ",moveToReservered" + moveToReservered);
|
||||
|
||||
s_logger.debug("release mem from host: " + hostId + ", old used: " + usedMem + ",reserved: " + reservedMem + ", total: " + totalMem +
|
||||
"; new used: " + capacityMemory.getUsedCapacity() + ",reserved:" + capacityMemory.getReservedCapacity() + ",total: " + capacityMemory.getTotalCapacity() +
|
||||
"; movedfromreserved: " + moveFromReserved + ",moveToReservered" + moveToReservered);
|
||||
|
||||
_capacityDao.update(capacityCpu.getId(), capacityCpu);
|
||||
_capacityDao.update(capacityMemory.getId(), capacityMemory);
|
||||
txn.commit();
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
s_logger.debug("Failed to transit vm's state, due to " + e.getMessage());
|
||||
txn.rollback();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@DB
|
||||
@Override
|
||||
public boolean allocateVmCapacity(long hostId, Integer cpu, long ram, boolean fromLastHost) {
|
||||
CapacityVO capacityCpu = _capacityDao.findByHostIdType(hostId, CapacityVO.CAPACITY_TYPE_CPU);
|
||||
CapacityVO capacityMem = _capacityDao.findByHostIdType(hostId, CapacityVO.CAPACITY_TYPE_MEMORY);
|
||||
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
|
||||
try {
|
||||
txn.start();
|
||||
capacityCpu = _capacityDao.lockRow(capacityCpu.getId(), true);
|
||||
capacityMem = _capacityDao.lockRow(capacityMem.getId(), true);
|
||||
|
||||
long usedCpu = capacityCpu.getUsedCapacity();
|
||||
long usedMem = capacityMem.getUsedCapacity();
|
||||
long reservedCpu = capacityCpu.getReservedCapacity();
|
||||
long reservedMem = capacityMem.getReservedCapacity();
|
||||
long totalCpu = capacityCpu.getTotalCapacity();
|
||||
long totalMem = capacityMem.getTotalCapacity();
|
||||
|
||||
boolean success = false;
|
||||
if (fromLastHost) {
|
||||
/*alloc from reserved*/
|
||||
if (reservedCpu >= cpu && reservedMem >= ram) {
|
||||
capacityCpu.setReservedCapacity(reservedCpu - cpu);
|
||||
capacityMem.setReservedCapacity(reservedMem - ram);
|
||||
if ((usedCpu + reservedCpu + cpu <= totalCpu) && (reservedMem + usedMem + ram <= totalMem)) {
|
||||
capacityCpu.setUsedCapacity(usedCpu + cpu);
|
||||
capacityMem.setUsedCapacity(usedMem + ram);
|
||||
}
|
||||
success = true;
|
||||
}
|
||||
} else {
|
||||
/*alloc from free resource*/
|
||||
if ((reservedCpu + usedCpu + cpu <= totalCpu) && (reservedMem + usedMem + ram <= totalMem)) {
|
||||
capacityCpu.setUsedCapacity(usedCpu + cpu);
|
||||
capacityMem.setUsedCapacity(usedMem + ram);
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (success) {
|
||||
s_logger.debug("alloc cpu from host: " + hostId + ", old used: " + usedCpu + ", old reserved: " +
|
||||
reservedCpu + ", old total: " + totalCpu +
|
||||
"; new used:" + capacityCpu.getUsedCapacity() + ", reserved:" + capacityCpu.getReservedCapacity() + ", total: " + capacityCpu.getTotalCapacity() +
|
||||
"; requested cpu:" + cpu + ",alloc_from_last:" + fromLastHost);
|
||||
|
||||
s_logger.debug("alloc mem from host: " + hostId + ", old used: " + usedMem + ", old reserved: " +
|
||||
reservedMem + ", old total: " + totalMem + "; new used: " + capacityMem.getUsedCapacity() + ", reserved: " +
|
||||
capacityMem.getReservedCapacity() + ", total: " + capacityMem.getTotalCapacity() + "; requested mem: " + ram + ",alloc_from_last:" + fromLastHost);
|
||||
|
||||
_capacityDao.update(capacityCpu.getId(), capacityCpu);
|
||||
_capacityDao.update(capacityMem.getId(), capacityMem);
|
||||
} else {
|
||||
if (fromLastHost) {
|
||||
s_logger.debug("Failed to alloc resource from host: " + hostId + " reservedCpu: " + reservedCpu + ", requested cpu: " + cpu +
|
||||
", reservedMem: " + reservedMem + ", requested mem: " + ram);
|
||||
} else {
|
||||
s_logger.debug("Failed to alloc resource from host: " + hostId + " reservedCpu: " + reservedCpu + ", used cpu: " + usedCpu + ", requested cpu: " + cpu +
|
||||
", total cpu: " + totalCpu +
|
||||
", reservedMem: " + reservedMem + ", used Mem: " + usedMem + ", requested mem: " + ram + ", total Mem:" + totalMem);
|
||||
}
|
||||
}
|
||||
|
||||
txn.commit();
|
||||
return success;
|
||||
} catch (Exception e) {
|
||||
txn.rollback();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public class HostCapacityCollector implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (!_stopped) {
|
||||
try {
|
||||
Thread.sleep(_hostCapacityCheckerInterval * 1000);
|
||||
} catch (InterruptedException e1) {
|
||||
|
||||
}
|
||||
// get all hosts..
|
||||
SearchCriteria<HostVO> sc = _hostDao.createSearchCriteria();
|
||||
sc.addAnd("status", SearchCriteria.Op.EQ, Status.Up.toString());
|
||||
List<HostVO> hosts = _hostDao.search(sc, null);
|
||||
|
||||
// prep the service offerings
|
||||
List<ServiceOfferingVO> offerings = _offeringsDao.listAllIncludingRemoved();
|
||||
Map<Long, ServiceOfferingVO> offeringsMap = new HashMap<Long, ServiceOfferingVO>();
|
||||
for (ServiceOfferingVO offering : offerings) {
|
||||
offeringsMap.put(offering.getId(), offering);
|
||||
}
|
||||
|
||||
for (HostVO host : hosts) {
|
||||
if (host.getType() != Host.Type.Routing) {
|
||||
continue;
|
||||
}
|
||||
|
||||
long usedCpu = 0;
|
||||
long usedMemory = 0;
|
||||
long reservedMemory = 0;
|
||||
long reservedCpu = 0;
|
||||
|
||||
List<VMInstanceVO> vms = _vmDao.listUpByHostId(host.getId());
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Found " + vms.size() + " VMs on host " + host.getId());
|
||||
}
|
||||
|
||||
for (VMInstanceVO vm : vms) {
|
||||
ServiceOffering so = offeringsMap.get(vm.getServiceOfferingId());
|
||||
usedMemory += so.getRamSize() * 1024L * 1024L;
|
||||
usedCpu += so.getCpu() * so.getSpeed();
|
||||
}
|
||||
|
||||
List<VMInstanceVO> vmsByLastHostId = _vmDao.listByLastHostId(host.getId());
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Found " + vmsByLastHostId.size() + " VM, not running on host " + host.getId());
|
||||
}
|
||||
for (VMInstanceVO vm : vmsByLastHostId) {
|
||||
long secondsSinceLastUpdate = (DateUtil.currentGMTTime().getTime() - vm.getUpdateTime().getTime())/1000;
|
||||
if (secondsSinceLastUpdate < _vmCapacityReleaseInterval) {
|
||||
ServiceOffering so = offeringsMap.get(vm.getServiceOfferingId());
|
||||
reservedMemory += so.getRamSize() * 1024L * 1024L;
|
||||
reservedCpu += so.getCpu() * so.getSpeed();
|
||||
}
|
||||
}
|
||||
|
||||
CapacityVO cpuCap = _capacityDao.findByHostIdType(host.getId(), CapacityVO.CAPACITY_TYPE_CPU);
|
||||
CapacityVO memCap = _capacityDao.findByHostIdType(host.getId(), CapacityVO.CAPACITY_TYPE_MEMORY);
|
||||
|
||||
if (cpuCap.getUsedCapacity() == usedCpu && cpuCap.getReservedCapacity() == reservedCpu) {
|
||||
s_logger.debug("Cool, no need to calibrate cpu capacity, host:" + host.getId() + " usedCpu: " + cpuCap.getUsedCapacity() + " reservedCpu: " + cpuCap.getReservedCapacity());
|
||||
} else if (cpuCap.getReservedCapacity() != reservedCpu) {
|
||||
s_logger.debug("Calibrate reserved cpu for host: " + host.getId() + " old reservedCpu:" + cpuCap.getReservedCapacity() + " new reservedCpu:" + reservedCpu);
|
||||
cpuCap.setReservedCapacity(reservedCpu);
|
||||
} else if (cpuCap.getUsedCapacity() != usedCpu) {
|
||||
s_logger.debug("Calibrate used cpu for host: " + host.getId() + " old usedCpu:" + cpuCap.getUsedCapacity() + " new usedCpu:" + usedCpu);
|
||||
cpuCap.setUsedCapacity(usedCpu);
|
||||
}
|
||||
|
||||
if (memCap.getUsedCapacity() == usedMemory && memCap.getReservedCapacity() == reservedMemory) {
|
||||
s_logger.debug("Cool, no need to calibrate memory capacity, host:" + host.getId() + " usedMem: " + memCap.getUsedCapacity() + " reservedMem: " + memCap.getReservedCapacity());
|
||||
} else if (memCap.getReservedCapacity() != reservedMemory) {
|
||||
s_logger.debug("Calibrate reserved memory for host: " + host.getId() + " old reservedMem:" + memCap.getReservedCapacity() + " new reservedMem:" + reservedMemory);
|
||||
memCap.setReservedCapacity(reservedMemory);
|
||||
} else if (memCap.getUsedCapacity() != usedMemory) {
|
||||
/*Didn't calibrate for used memory, because VMs can be in state(starting/migrating) that I don't know on which host they are allocated*/
|
||||
s_logger.debug("Calibrate used memory for host: " + host.getId() + " old usedMem: " + memCap.getUsedCapacity() + " new usedMem: " + usedMemory);
|
||||
memCap.setUsedCapacity(usedMemory);
|
||||
}
|
||||
|
||||
try {
|
||||
_capacityDao.update(cpuCap.getId(), cpuCap);
|
||||
_capacityDao.update(memCap.getId(), memCap);
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,6 +33,7 @@ import com.cloud.async.SyncQueueManagerImpl;
|
||||
import com.cloud.async.dao.AsyncJobDaoImpl;
|
||||
import com.cloud.async.dao.SyncQueueDaoImpl;
|
||||
import com.cloud.async.dao.SyncQueueItemDaoImpl;
|
||||
import com.cloud.capacity.CapacityManagerImpl;
|
||||
import com.cloud.capacity.dao.CapacityDaoImpl;
|
||||
import com.cloud.certificate.dao.CertificateDaoImpl;
|
||||
import com.cloud.cluster.DummyClusterManagerImpl;
|
||||
@ -313,6 +314,7 @@ public class DefaultComponentLibrary implements ComponentLibrary {
|
||||
addManager("RemoteAccessVpnManager", RemoteAccessVpnManagerImpl.class);
|
||||
addManager("OvsNetworkManager", OvsNetworkManagerImpl.class);
|
||||
addManager("OvsTunnelManager", OvsTunnelManagerImpl.class);
|
||||
addManager("Capacity Manager", CapacityManagerImpl.class);
|
||||
}
|
||||
|
||||
protected <T> List<ComponentInfo<Adapter>> addAdapterChain(Class<T> interphace, List<Pair<String, Class<? extends T>>> adapters) {
|
||||
|
||||
@ -7,6 +7,7 @@ import javax.ejb.Local;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.capacity.CapacityManager;
|
||||
import com.cloud.capacity.CapacityVO;
|
||||
import com.cloud.capacity.dao.CapacityDao;
|
||||
import com.cloud.dc.ClusterVO;
|
||||
@ -47,6 +48,7 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner {
|
||||
@Inject DetailsDao _hostDetailsDao = null;
|
||||
@Inject GuestOSDao _guestOSDao = null;
|
||||
@Inject GuestOSCategoryDao _guestOSCategoryDao = null;
|
||||
@Inject CapacityManager _capacityMgr;
|
||||
|
||||
@Override
|
||||
public DeployDestination plan(VirtualMachineProfile vmProfile,
|
||||
@ -162,73 +164,7 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner {
|
||||
return false;
|
||||
}
|
||||
|
||||
CapacityVO capacityCpu = _capacityDao.findByHostIdType(host.getId(), CapacityVO.CAPACITY_TYPE_CPU);
|
||||
CapacityVO capacityMem = _capacityDao.findByHostIdType(host.getId(), CapacityVO.CAPACITY_TYPE_MEMORY);
|
||||
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
|
||||
try {
|
||||
txn.start();
|
||||
capacityCpu = _capacityDao.lockRow(capacityCpu.getId(), true);
|
||||
capacityMem = _capacityDao.lockRow(capacityMem.getId(), true);
|
||||
|
||||
long usedCpu = capacityCpu.getUsedCapacity();
|
||||
long usedMem = capacityMem.getUsedCapacity();
|
||||
long reservedCpu = capacityCpu.getReservedCapacity();
|
||||
long reservedMem = capacityMem.getReservedCapacity();
|
||||
long totalCpu = capacityCpu.getTotalCapacity();
|
||||
long totalMem = capacityMem.getTotalCapacity();
|
||||
|
||||
boolean success = false;
|
||||
if (fromLastHost) {
|
||||
/*alloc from reserved*/
|
||||
if (reservedCpu >= cpu && reservedMem >= ram) {
|
||||
capacityCpu.setReservedCapacity(reservedCpu - cpu);
|
||||
capacityMem.setReservedCapacity(reservedMem - ram);
|
||||
if ((usedCpu + reservedCpu + cpu <= totalCpu) && (reservedMem + usedMem + ram <= totalMem)) {
|
||||
capacityCpu.setUsedCapacity(usedCpu + cpu);
|
||||
capacityMem.setUsedCapacity(usedMem + ram);
|
||||
}
|
||||
success = true;
|
||||
}
|
||||
} else {
|
||||
/*alloc from free resource*/
|
||||
if ((reservedCpu + usedCpu + cpu <= totalCpu) && (reservedMem + usedMem + ram <= totalMem)) {
|
||||
capacityCpu.setUsedCapacity(usedCpu + cpu);
|
||||
capacityMem.setUsedCapacity(usedMem + ram);
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (success) {
|
||||
s_logger.debug("alloc cpu from host: " + host.getId() + ", old used: " + usedCpu + ", old reserved: " +
|
||||
reservedCpu + ", old total: " + totalCpu +
|
||||
"; new used:" + capacityCpu.getUsedCapacity() + ", reserved:" + capacityCpu.getReservedCapacity() + ", total: " + capacityCpu.getTotalCapacity() +
|
||||
"; requested cpu:" + cpu + ",alloc_from_last:" + fromLastHost);
|
||||
|
||||
s_logger.debug("alloc mem from host: " + host.getId() + ", old used: " + usedMem + ", old reserved: " +
|
||||
reservedMem + ", old total: " + totalMem + "; new used: " + capacityMem.getUsedCapacity() + ", reserved: " +
|
||||
capacityMem.getReservedCapacity() + ", total: " + capacityMem.getTotalCapacity() + "; requested mem: " + ram + ",alloc_from_last:" + fromLastHost);
|
||||
|
||||
_capacityDao.update(capacityCpu.getId(), capacityCpu);
|
||||
_capacityDao.update(capacityMem.getId(), capacityMem);
|
||||
} else {
|
||||
if (fromLastHost) {
|
||||
s_logger.debug("Failed to alloc resource from host: " + host.getId() + " reservedCpu: " + reservedCpu + ", requested cpu: " + cpu +
|
||||
", reservedMem: " + reservedMem + ", requested mem: " + ram);
|
||||
} else {
|
||||
s_logger.debug("Failed to alloc resource from host: " + host.getId() + " reservedCpu: " + reservedCpu + ", used cpu: " + usedCpu + ", requested cpu: " + cpu +
|
||||
", total cpu: " + totalCpu +
|
||||
", reservedMem: " + reservedMem + ", used Mem: " + usedMem + ", requested mem: " + ram + ", total Mem:" + totalMem);
|
||||
}
|
||||
}
|
||||
|
||||
txn.commit();
|
||||
return success;
|
||||
} catch (Exception e) {
|
||||
txn.rollback();
|
||||
return false;
|
||||
}
|
||||
return _capacityMgr.allocateVmCapacity(host.getId(), cpu, ram, fromLastHost);
|
||||
}
|
||||
|
||||
protected List<HostVO> prioritizeHosts(VirtualMachineTemplate template, List<HostVO> hosts) {
|
||||
|
||||
@ -20,9 +20,8 @@ package com.cloud.network.security;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.uservm.UserVm;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
|
||||
|
||||
/**
|
||||
* Ensures that network firewall rules stay updated as VMs go up and down
|
||||
@ -32,8 +31,6 @@ public interface SecurityGroupManager {
|
||||
|
||||
public static final String DEFAULT_GROUP_NAME = "default";
|
||||
public static final String DEFAULT_GROUP_DESCRIPTION = "Default Security Group";
|
||||
|
||||
public void handleVmStateTransition(UserVm userVm, State vmState);
|
||||
|
||||
public SecurityGroupVO createSecurityGroup(String name, String description, Long domainId, Long accountId, String accountName);
|
||||
|
||||
|
||||
@ -40,6 +40,7 @@ import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.api.NetworkRulesSystemVmCommand;
|
||||
import com.cloud.agent.api.SecurityIngressRulesCmd;
|
||||
import com.cloud.agent.api.SecurityIngressRulesCmd.IpPortAndProto;
|
||||
import com.cloud.agent.manager.Commands;
|
||||
@ -55,6 +56,7 @@ import com.cloud.domain.DomainVO;
|
||||
import com.cloud.domain.dao.DomainDao;
|
||||
import com.cloud.exception.AgentUnavailableException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.OperationTimedoutException;
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.exception.ResourceInUseException;
|
||||
import com.cloud.network.security.SecurityGroupWorkVO.Step;
|
||||
@ -82,13 +84,18 @@ import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.fsm.StateListener;
|
||||
import com.cloud.utils.net.NetUtils;
|
||||
import com.cloud.vm.UserVmVO;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachine.Event;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
import com.cloud.vm.VirtualMachineManager;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
|
||||
@Local(value={SecurityGroupManager.class, SecurityGroupService.class})
|
||||
public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityGroupService, Manager {
|
||||
public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityGroupService, Manager, StateListener<State, VirtualMachine.Event, VirtualMachine> {
|
||||
public static final Logger s_logger = Logger.getLogger(SecurityGroupManagerImpl.class);
|
||||
|
||||
@Inject SecurityGroupDao _securityGroupDao;
|
||||
@ -102,6 +109,7 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG
|
||||
@Inject VmRulesetLogDao _rulesetLogDao;
|
||||
@Inject DomainDao _domainDao;
|
||||
@Inject AgentManager _agentMgr;
|
||||
@Inject VirtualMachineManager _itMgr;
|
||||
ScheduledExecutorService _executorPool;
|
||||
ScheduledExecutorService _cleanupExecutor;
|
||||
|
||||
@ -242,29 +250,7 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleVmStateTransition(UserVm userVm, State vmState) {
|
||||
if (!_enabled) {
|
||||
return;
|
||||
}
|
||||
switch (vmState) {
|
||||
case Destroyed:
|
||||
case Error:
|
||||
case Migrating:
|
||||
case Expunging:
|
||||
case Starting:
|
||||
case Unknown:
|
||||
return;
|
||||
case Running:
|
||||
handleVmStarted(userVm);
|
||||
break;
|
||||
case Stopping:
|
||||
case Stopped:
|
||||
handleVmStopped(userVm);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static class CidrComparator implements Comparator<String> {
|
||||
|
||||
@ -315,8 +301,8 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG
|
||||
return DigestUtils.md5Hex(ruleset);
|
||||
}
|
||||
|
||||
protected void handleVmStarted(UserVm userVm) {
|
||||
Set<Long> affectedVms = getAffectedVmsForVmStart(userVm);
|
||||
protected void handleVmStarted(VMInstanceVO vm) {
|
||||
Set<Long> affectedVms = getAffectedVmsForVmStart(vm);
|
||||
scheduleRulesetUpdateToHosts(affectedVms, true, null);
|
||||
}
|
||||
|
||||
@ -372,10 +358,10 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG
|
||||
}
|
||||
}
|
||||
|
||||
protected Set<Long> getAffectedVmsForVmStart(UserVm userVm) {
|
||||
protected Set<Long> getAffectedVmsForVmStart(VMInstanceVO vm) {
|
||||
Set<Long> affectedVms = new HashSet<Long>();
|
||||
affectedVms.add(userVm.getId());
|
||||
List<SecurityGroupVMMapVO> groupsForVm = _securityGroupVMMapDao.listByInstanceId(userVm.getId());
|
||||
affectedVms.add(vm.getId());
|
||||
List<SecurityGroupVMMapVO> groupsForVm = _securityGroupVMMapDao.listByInstanceId(vm.getId());
|
||||
//For each group, find the ingress rules that allow the group
|
||||
for (SecurityGroupVMMapVO mapVO: groupsForVm) {//FIXME: use custom sql in the dao
|
||||
List<IngressRuleVO> allowingRules = _ingressRuleDao.listByAllowedSecurityGroupId(mapVO.getSecurityGroupId());
|
||||
@ -385,9 +371,9 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG
|
||||
return affectedVms;
|
||||
}
|
||||
|
||||
protected Set<Long> getAffectedVmsForVmStop(UserVm userVm) {
|
||||
protected Set<Long> getAffectedVmsForVmStop(VMInstanceVO vm) {
|
||||
Set<Long> affectedVms = new HashSet<Long>();
|
||||
List<SecurityGroupVMMapVO> groupsForVm = _securityGroupVMMapDao.listByInstanceId(userVm.getId());
|
||||
List<SecurityGroupVMMapVO> groupsForVm = _securityGroupVMMapDao.listByInstanceId(vm.getId());
|
||||
//For each group, find the ingress rules that allow the group
|
||||
for (SecurityGroupVMMapVO mapVO: groupsForVm) {//FIXME: use custom sql in the dao
|
||||
List<IngressRuleVO> allowingRules = _ingressRuleDao.listByAllowedSecurityGroupId(mapVO.getSecurityGroupId());
|
||||
@ -426,11 +412,22 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG
|
||||
return new SecurityIngressRulesCmd(guestIp, guestMac, vmName, vmId, signature, seqnum, result.toArray(new IpPortAndProto[result.size()]));
|
||||
}
|
||||
|
||||
protected void handleVmStopped(UserVm userVm) {
|
||||
Set<Long> affectedVms = getAffectedVmsForVmStop(userVm);
|
||||
protected void handleVmStopped(VMInstanceVO vm) {
|
||||
Set<Long> affectedVms = getAffectedVmsForVmStop(vm);
|
||||
scheduleRulesetUpdateToHosts(affectedVms, true, null);
|
||||
}
|
||||
|
||||
protected void handleVmMigrated(VMInstanceVO vm) {
|
||||
NetworkRulesSystemVmCommand nrc = new NetworkRulesSystemVmCommand(vm.getInstanceName(), vm.getType());
|
||||
Commands cmds = new Commands(nrc);
|
||||
try {
|
||||
_agentMgr.send(vm.getHostId(), cmds);
|
||||
} catch (AgentUnavailableException e) {
|
||||
s_logger.debug(e.toString());
|
||||
} catch (OperationTimedoutException e) {
|
||||
s_logger.debug(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Override @DB @SuppressWarnings("rawtypes")
|
||||
public List<IngressRuleVO> authorizeSecurityGroupIngress(AuthorizeSecurityGroupIngressCmd cmd) throws InvalidParameterValueException, PermissionDeniedException{
|
||||
@ -969,7 +966,7 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG
|
||||
_executorPool = Executors.newScheduledThreadPool(10, new NamedThreadFactory("NWGRP"));
|
||||
_cleanupExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("NWGRP-Cleanup"));
|
||||
|
||||
|
||||
VirtualMachine.State.getStateMachine().registerListener(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1428,4 +1425,27 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@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 vm, boolean status) {
|
||||
if (!_enabled || !status || vm.getType() != VirtualMachine.Type.User) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (VirtualMachine.State.isVmStarted(oldState, event, newState)) {
|
||||
handleVmStarted((VMInstanceVO)vm);
|
||||
} else if (VirtualMachine.State.isVmStopped(oldState, event, newState)) {
|
||||
handleVmStopped((VMInstanceVO)vm);
|
||||
} else if (VirtualMachine.State.isVmMigrated(oldState, event, newState)) {
|
||||
handleVmMigrated((VMInstanceVO)vm);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,341 +0,0 @@
|
||||
package com.cloud.stateListener;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
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.log4j.Logger;
|
||||
|
||||
import com.cloud.capacity.CapacityVO;
|
||||
import com.cloud.capacity.dao.CapacityDao;
|
||||
import com.cloud.configuration.Config;
|
||||
import com.cloud.configuration.dao.ConfigurationDao;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.Status;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.service.ServiceOfferingVO;
|
||||
import com.cloud.service.dao.ServiceOfferingDao;
|
||||
import com.cloud.utils.DateUtil;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.component.AdapterBase;
|
||||
import com.cloud.utils.component.Inject;
|
||||
import com.cloud.utils.concurrency.NamedThreadFactory;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.fsm.StateDao;
|
||||
import com.cloud.utils.fsm.StateListener;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachine.Event;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
|
||||
@Local(value=StateListener.class)
|
||||
public class VMStateListener extends AdapterBase implements StateListener<State, VirtualMachine.Event, VMInstanceVO> {
|
||||
private static final Logger s_logger = Logger.getLogger(VMStateListener.class);
|
||||
@Inject CapacityDao _capacityDao = null;
|
||||
@Inject ServiceOfferingDao _offeringsDao = null;
|
||||
@Inject HostDao _hostDao = null;
|
||||
@Inject VMInstanceDao _vmDao = null;
|
||||
@Inject ConfigurationDao _configDao = null;
|
||||
|
||||
ScheduledExecutorService _executor;
|
||||
int _hostCapacityCheckerDelay;
|
||||
int _hostCapacityCheckerInterval;
|
||||
int _vmCapacityReleaseInterval;
|
||||
boolean _stopped = false;
|
||||
|
||||
@DB
|
||||
@Override
|
||||
public boolean processStateTransitionEvent(State oldState,
|
||||
Event event, State newState, VMInstanceVO vm, boolean transitionStatus, Long id, StateDao<State, VirtualMachine.Event, VMInstanceVO> vmDao) {
|
||||
s_logger.debug("VM state transitted from :" + oldState + " to " + newState + " with event: " + event +
|
||||
"vm's original host id: " + vm.getHostId() + " new host id: " + id);
|
||||
if (!transitionStatus) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
try {
|
||||
txn.start();
|
||||
|
||||
if (oldState == State.Starting) {
|
||||
if (event == Event.OperationSucceeded) {
|
||||
if (vm.getLastHostId() != null && vm.getLastHostId() != id) {
|
||||
/*need to release the reserved capacity on lasthost*/
|
||||
releaseResource(vm, true, false, vm.getLastHostId());
|
||||
}
|
||||
vm.setLastHostId(id);
|
||||
} else if (event == Event.OperationFailed) {
|
||||
releaseResource(vm, false, false, vm.getHostId());
|
||||
} else if (event == Event.OperationRetry) {
|
||||
releaseResource(vm, false, false, vm.getHostId());
|
||||
} else if (event == Event.AgentReportStopped) {
|
||||
releaseResource(vm, false, true, vm.getHostId());
|
||||
}
|
||||
} else if (oldState == State.Running) {
|
||||
if (event == Event.AgentReportStopped) {
|
||||
releaseResource(vm, false, true, vm.getHostId());
|
||||
}
|
||||
} else if (oldState == State.Migrating) {
|
||||
if (event == Event.AgentReportStopped) {
|
||||
/*Release capacity from original host*/
|
||||
releaseResource(vm, false, true, vm.getHostId());
|
||||
} else if (event == Event.MigrationFailedOnSource) {
|
||||
/*release capacity from dest host*/
|
||||
releaseResource(vm, false, false, id);
|
||||
id = vm.getHostId();
|
||||
} else if (event == Event.MigrationFailedOnDest) {
|
||||
/*release capacify from original host*/
|
||||
releaseResource(vm, false, false, vm.getHostId());
|
||||
} else if (event == Event.OperationSucceeded) {
|
||||
releaseResource(vm, false, false, vm.getHostId());
|
||||
/*set lasthost id to migration destination host id*/
|
||||
vm.setLastHostId(id);
|
||||
}
|
||||
} else if (oldState == State.Stopping) {
|
||||
if (event == Event.AgentReportStopped || event == Event.OperationSucceeded) {
|
||||
releaseResource(vm, false, true, vm.getHostId());
|
||||
}
|
||||
} else if (oldState == State.Stopped) {
|
||||
if (event == Event.DestroyRequested) {
|
||||
releaseResource(vm, true, false, vm.getLastHostId());
|
||||
vm.setLastHostId(null);
|
||||
}
|
||||
}
|
||||
|
||||
transitionStatus = vmDao.updateState(oldState, event, newState, vm, id);
|
||||
if (transitionStatus) {
|
||||
txn.commit();
|
||||
} else {
|
||||
s_logger.debug("Failed to transit vm's state");
|
||||
txn.rollback();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
s_logger.debug("Failed to transit vm's state, due to " + e.getMessage());
|
||||
txn.rollback();
|
||||
}
|
||||
|
||||
return transitionStatus;
|
||||
}
|
||||
|
||||
private void releaseResource(VMInstanceVO vm, boolean moveFromReserved, boolean moveToReservered, Long hostId) {
|
||||
ServiceOfferingVO svo = _offeringsDao.findById(vm.getServiceOfferingId());
|
||||
CapacityVO capacityCpu = _capacityDao.findByHostIdType(hostId, CapacityVO.CAPACITY_TYPE_CPU);
|
||||
CapacityVO capacityMemory = _capacityDao.findByHostIdType(hostId, CapacityVO.CAPACITY_TYPE_MEMORY);
|
||||
|
||||
if (capacityCpu == null || capacityMemory == null || svo == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int vmCPU = svo.getCpu() * svo.getSpeed();
|
||||
long vmMem = svo.getRamSize() * 1024L * 1024L;
|
||||
|
||||
capacityCpu = _capacityDao.lockRow(capacityCpu.getId(), true);
|
||||
capacityMemory = _capacityDao.lockRow(capacityMemory.getId(), true);
|
||||
|
||||
long usedCpu = capacityCpu.getUsedCapacity();
|
||||
long usedMem = capacityMemory.getUsedCapacity();
|
||||
long reservedCpu = capacityCpu.getReservedCapacity();
|
||||
long reservedMem = capacityMemory.getReservedCapacity();
|
||||
long totalCpu = capacityCpu.getTotalCapacity();
|
||||
long totalMem = capacityMemory.getTotalCapacity();
|
||||
|
||||
if (!moveFromReserved) {
|
||||
/*move resource from used*/
|
||||
if (usedCpu >= vmCPU) {
|
||||
capacityCpu.setUsedCapacity(usedCpu - vmCPU);
|
||||
}
|
||||
if (usedMem >= vmMem) {
|
||||
capacityMemory.setUsedCapacity(usedMem - vmMem);
|
||||
}
|
||||
|
||||
if (moveToReservered) {
|
||||
if (reservedCpu + vmCPU <= totalCpu) {
|
||||
capacityCpu.setReservedCapacity(reservedCpu + vmCPU);
|
||||
}
|
||||
if (reservedMem + vmMem <= totalMem) {
|
||||
capacityMemory.setReservedCapacity(reservedMem + vmMem);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (reservedCpu >= vmCPU) {
|
||||
capacityCpu.setReservedCapacity(reservedCpu - vmCPU);
|
||||
}
|
||||
if (reservedMem >= vmMem) {
|
||||
capacityMemory.setReservedCapacity(reservedMem - vmMem);
|
||||
}
|
||||
}
|
||||
|
||||
s_logger.debug("release cpu from host: " + hostId + ", old used: " + usedCpu + ",reserved: " + reservedCpu + ", total: " + totalCpu +
|
||||
"; new used: " + capacityCpu.getUsedCapacity() + ",reserved:" + capacityCpu.getReservedCapacity() + ",total: " + capacityCpu.getTotalCapacity() +
|
||||
"; movedfromreserved: " + moveFromReserved + ",moveToReservered" + moveToReservered);
|
||||
|
||||
s_logger.debug("release mem from host: " + hostId + ", old used: " + usedMem + ",reserved: " + reservedMem + ", total: " + totalMem +
|
||||
"; new used: " + capacityMemory.getUsedCapacity() + ",reserved:" + capacityMemory.getReservedCapacity() + ",total: " + capacityMemory.getTotalCapacity() +
|
||||
"; movedfromreserved: " + moveFromReserved + ",moveToReservered" + moveToReservered);
|
||||
|
||||
_capacityDao.update(capacityCpu.getId(), capacityCpu);
|
||||
_capacityDao.update(capacityMemory.getId(), capacityMemory);
|
||||
|
||||
}
|
||||
|
||||
/*Add capacity to destination host, for migration*/
|
||||
private void addResource(VMInstanceVO vm, Long destHostId) {
|
||||
ServiceOfferingVO svo = _offeringsDao.findById(vm.getServiceOfferingId());
|
||||
CapacityVO capacityCpu = _capacityDao.findByHostIdType(destHostId, CapacityVO.CAPACITY_TYPE_CPU);
|
||||
CapacityVO capacityMemory = _capacityDao.findByHostIdType(destHostId, CapacityVO.CAPACITY_TYPE_MEMORY);
|
||||
int vmCPU = svo.getCpu() * svo.getSpeed();
|
||||
long vmMem = svo.getRamSize() * 1024L * 1024L;
|
||||
|
||||
capacityCpu = _capacityDao.lockRow(capacityCpu.getId(), true);
|
||||
capacityMemory = _capacityDao.lockRow(capacityMemory.getId(), true);
|
||||
|
||||
long usedCpu = capacityCpu.getUsedCapacity();
|
||||
long usedMem = capacityMemory.getUsedCapacity();
|
||||
long reservedCpu = capacityCpu.getReservedCapacity();
|
||||
long reservedMem = capacityMemory.getReservedCapacity();
|
||||
long totalCpu = capacityCpu.getTotalCapacity();
|
||||
long totalMem = capacityMemory.getTotalCapacity();
|
||||
|
||||
if (usedCpu + reservedCpu + vmCPU <= totalCpu) {
|
||||
capacityCpu.setUsedCapacity(usedCpu + vmCPU);
|
||||
} else {
|
||||
s_logger.debug("What's the heck? :u:" + usedCpu + ",r:" + reservedCpu + ",vm:" + vmCPU + " > " + totalCpu);
|
||||
}
|
||||
|
||||
if (usedMem + reservedMem + vmMem <= totalMem) {
|
||||
capacityMemory.setUsedCapacity(usedMem + vmMem);
|
||||
} else {
|
||||
s_logger.debug("What's the heck? :u:" + usedMem + ",r:" + reservedMem + ",vm:" + vmMem + " > " + totalMem);
|
||||
}
|
||||
|
||||
_capacityDao.update(capacityCpu.getId(), capacityCpu);
|
||||
_capacityDao.update(capacityMemory.getId(), capacityMemory);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
super.configure(name, params);
|
||||
_hostCapacityCheckerDelay = NumbersUtil.parseInt(_configDao.getValue(Config.HostCapacityCheckerWait.key()), 3600);
|
||||
_hostCapacityCheckerInterval = NumbersUtil.parseInt(_configDao.getValue(Config.HostCapacityCheckerInterval.key()), 3600);
|
||||
_vmCapacityReleaseInterval = NumbersUtil.parseInt(_configDao.getValue(Config.VmHostCapacityReleaseInterval.key()), 86400);
|
||||
_executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("HostCapacity-Checker"));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean start() {
|
||||
_executor.schedule(new HostCapacityCollector(), _hostCapacityCheckerDelay, TimeUnit.SECONDS);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stop() {
|
||||
_executor.shutdownNow();
|
||||
_stopped = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public class HostCapacityCollector implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (!_stopped) {
|
||||
try {
|
||||
Thread.sleep(_hostCapacityCheckerInterval * 1000);
|
||||
} catch (InterruptedException e1) {
|
||||
|
||||
}
|
||||
// get all hosts..
|
||||
SearchCriteria<HostVO> sc = _hostDao.createSearchCriteria();
|
||||
sc.addAnd("status", SearchCriteria.Op.EQ, Status.Up.toString());
|
||||
List<HostVO> hosts = _hostDao.search(sc, null);
|
||||
|
||||
// prep the service offerings
|
||||
List<ServiceOfferingVO> offerings = _offeringsDao.listAllIncludingRemoved();
|
||||
Map<Long, ServiceOfferingVO> offeringsMap = new HashMap<Long, ServiceOfferingVO>();
|
||||
for (ServiceOfferingVO offering : offerings) {
|
||||
offeringsMap.put(offering.getId(), offering);
|
||||
}
|
||||
|
||||
for (HostVO host : hosts) {
|
||||
if (host.getType() != Host.Type.Routing) {
|
||||
continue;
|
||||
}
|
||||
|
||||
long usedCpu = 0;
|
||||
long usedMemory = 0;
|
||||
long reservedMemory = 0;
|
||||
long reservedCpu = 0;
|
||||
|
||||
List<VMInstanceVO> vms = _vmDao.listUpByHostId(host.getId());
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Found " + vms.size() + " VMs on host " + host.getId());
|
||||
}
|
||||
|
||||
for (VMInstanceVO vm : vms) {
|
||||
ServiceOffering so = offeringsMap.get(vm.getServiceOfferingId());
|
||||
usedMemory += so.getRamSize() * 1024L * 1024L;
|
||||
usedCpu += so.getCpu() * so.getSpeed();
|
||||
}
|
||||
|
||||
List<VMInstanceVO> vmsByLastHostId = _vmDao.listByLastHostId(host.getId());
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Found " + vmsByLastHostId.size() + " VM, not running on host " + host.getId());
|
||||
}
|
||||
for (VMInstanceVO vm : vmsByLastHostId) {
|
||||
long secondsSinceLastUpdate = (DateUtil.currentGMTTime().getTime() - vm.getUpdateTime().getTime())/1000;
|
||||
if (secondsSinceLastUpdate < _vmCapacityReleaseInterval) {
|
||||
ServiceOffering so = offeringsMap.get(vm.getServiceOfferingId());
|
||||
reservedMemory += so.getRamSize() * 1024L * 1024L;
|
||||
reservedCpu += so.getCpu() * so.getSpeed();
|
||||
}
|
||||
}
|
||||
|
||||
CapacityVO cpuCap = _capacityDao.findByHostIdType(host.getId(), CapacityVO.CAPACITY_TYPE_CPU);
|
||||
CapacityVO memCap = _capacityDao.findByHostIdType(host.getId(), CapacityVO.CAPACITY_TYPE_MEMORY);
|
||||
|
||||
if (cpuCap.getUsedCapacity() == usedCpu && cpuCap.getReservedCapacity() == reservedCpu) {
|
||||
s_logger.debug("Cool, no need to calibrate cpu capacity, host:" + host.getId() + " usedCpu: " + cpuCap.getUsedCapacity() + " reservedCpu: " + cpuCap.getReservedCapacity());
|
||||
} else if (cpuCap.getReservedCapacity() != reservedCpu) {
|
||||
s_logger.debug("Calibrate reserved cpu for host: " + host.getId() + " old reservedCpu:" + cpuCap.getReservedCapacity() + " new reservedCpu:" + reservedCpu);
|
||||
cpuCap.setReservedCapacity(reservedCpu);
|
||||
} else if (cpuCap.getUsedCapacity() != usedCpu) {
|
||||
s_logger.debug("Calibrate used cpu for host: " + host.getId() + " old usedCpu:" + cpuCap.getUsedCapacity() + " new usedCpu:" + usedCpu);
|
||||
cpuCap.setUsedCapacity(usedCpu);
|
||||
}
|
||||
|
||||
if (memCap.getUsedCapacity() == usedMemory && memCap.getReservedCapacity() == reservedMemory) {
|
||||
s_logger.debug("Cool, no need to calibrate memory capacity, host:" + host.getId() + " usedMem: " + memCap.getUsedCapacity() + " reservedMem: " + memCap.getReservedCapacity());
|
||||
} else if (memCap.getReservedCapacity() != reservedMemory) {
|
||||
s_logger.debug("Calibrate reserved memory for host: " + host.getId() + " old reservedMem:" + memCap.getReservedCapacity() + " new reservedMem:" + reservedMemory);
|
||||
memCap.setReservedCapacity(reservedMemory);
|
||||
} else if (memCap.getUsedCapacity() != usedMemory) {
|
||||
/*Didn't calibrate for used memory, because VMs can be in state(starting/migrating) that I don't know on which host they are allocated*/
|
||||
s_logger.debug("Calibrate used memory for host: " + host.getId() + " old usedMem: " + memCap.getUsedCapacity() + " new usedMem: " + usedMemory);
|
||||
memCap.setUsedCapacity(usedMemory);
|
||||
}
|
||||
|
||||
try {
|
||||
_capacityDao.update(cpuCap.getId(), cpuCap);
|
||||
_capacityDao.update(memCap.getId(), memCap);
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2199,7 +2199,6 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
|
||||
@Override
|
||||
public boolean finalizeStart(VirtualMachineProfile<UserVmVO> profile, long hostId, Commands cmds, ReservationContext context) {
|
||||
UserVmVO vm = profile.getVirtualMachine();
|
||||
_networkGroupMgr.handleVmStateTransition(vm, State.Running);
|
||||
_ovsNetworkMgr.handleVmStateTransition(vm, State.Running);
|
||||
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VM_START, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), vm.getName(), vm.getServiceOfferingId(), vm.getTemplateId(), null);
|
||||
_usageEventDao.persist(usageEvent);
|
||||
@ -2257,7 +2256,6 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
|
||||
@Override
|
||||
public void finalizeStop(VirtualMachineProfile<UserVmVO> profile, StopAnswer answer) {
|
||||
UserVmVO vm = profile.getVirtualMachine();
|
||||
_networkGroupMgr.handleVmStateTransition(vm, State.Stopped);
|
||||
_ovsNetworkMgr.handleVmStateTransition(vm, State.Stopped);
|
||||
_ovsTunnelMgr.CheckAndDestroyTunnel(vm);
|
||||
}
|
||||
|
||||
@ -37,6 +37,9 @@ import com.cloud.user.Account;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.component.Manager;
|
||||
import com.cloud.utils.fsm.StateListener;
|
||||
import com.cloud.vm.VirtualMachine.Event;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
|
||||
/**
|
||||
* Manages allocating resources to vms.
|
||||
|
||||
@ -51,6 +51,7 @@ import com.cloud.agent.api.StopCommand;
|
||||
import com.cloud.agent.api.to.VirtualMachineTO;
|
||||
import com.cloud.agent.manager.Commands;
|
||||
import com.cloud.alert.AlertManager;
|
||||
import com.cloud.capacity.CapacityManager;
|
||||
import com.cloud.cluster.ClusterManager;
|
||||
import com.cloud.configuration.Config;
|
||||
import com.cloud.configuration.ConfigurationManager;
|
||||
@ -121,7 +122,7 @@ import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
|
||||
@Local(value=VirtualMachineManager.class)
|
||||
public class VirtualMachineManagerImpl implements VirtualMachineManager {
|
||||
public class VirtualMachineManagerImpl implements VirtualMachineManager, StateListener<State, VirtualMachine.Event, VirtualMachine> {
|
||||
private static final Logger s_logger = Logger.getLogger(VirtualMachineManagerImpl.class);
|
||||
|
||||
String _name;
|
||||
@ -150,16 +151,14 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager {
|
||||
@Inject protected VolumeDao _volsDao;
|
||||
@Inject protected ConsoleProxyManager _consoleProxyMgr;
|
||||
@Inject protected ConfigurationManager _configMgr;
|
||||
@Inject protected CapacityManager _capacityMgr;
|
||||
|
||||
@Inject(adapter=DeploymentPlanner.class)
|
||||
protected Adapters<DeploymentPlanner> _planners;
|
||||
@Inject(adapter=StateListener.class)
|
||||
protected Adapters<StateListener<State, VirtualMachine.Event, VMInstanceVO>> _stateListner;
|
||||
|
||||
|
||||
Map<VirtualMachine.Type, VirtualMachineGuru<? extends VMInstanceVO>> _vmGurus = new HashMap<VirtualMachine.Type, VirtualMachineGuru<? extends VMInstanceVO>>();
|
||||
Map<HypervisorType, HypervisorGuru> _hvGurus = new HashMap<HypervisorType, HypervisorGuru>();
|
||||
protected StateMachine2<State, VirtualMachine.Event, VMInstanceVO> _stateMachine;
|
||||
protected StateMachine2<State, VirtualMachine.Event, VirtualMachine> _stateMachine;
|
||||
|
||||
ScheduledExecutorService _executor = null;
|
||||
|
||||
@ -426,8 +425,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager {
|
||||
_executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Vm-Operations-Cleanup"));
|
||||
_nodeId = _clusterMgr.getId();
|
||||
|
||||
setStateMachine();
|
||||
|
||||
_stateMachine.registerListener(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -437,6 +435,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager {
|
||||
}
|
||||
|
||||
protected VirtualMachineManagerImpl() {
|
||||
setStateMachine();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -868,48 +867,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager {
|
||||
}
|
||||
|
||||
private void setStateMachine() {
|
||||
_stateMachine = new StateMachine2<State, VirtualMachine.Event, VMInstanceVO>();
|
||||
|
||||
_stateMachine.addTransition(State.Stopped, VirtualMachine.Event.StartRequested, State.Starting);
|
||||
_stateMachine.addTransition(State.Stopped, VirtualMachine.Event.DestroyRequested, State.Destroyed);
|
||||
_stateMachine.addTransition(State.Stopped, VirtualMachine.Event.StopRequested, State.Stopped);
|
||||
_stateMachine.addTransition(State.Stopped, VirtualMachine.Event.AgentReportStopped, State.Stopped);
|
||||
_stateMachine.addTransition(State.Stopped, VirtualMachine.Event.OperationFailed, State.Error);
|
||||
_stateMachine.addTransition(State.Stopped, VirtualMachine.Event.ExpungeOperation, State.Expunging);
|
||||
_stateMachine.addTransition(State.Stopped, VirtualMachine.Event.AgentReportShutdowned, State.Stopped);
|
||||
_stateMachine.addTransition(State.Starting, VirtualMachine.Event.OperationRetry, State.Starting);
|
||||
_stateMachine.addTransition(State.Starting, VirtualMachine.Event.OperationSucceeded, State.Running);
|
||||
_stateMachine.addTransition(State.Starting, VirtualMachine.Event.OperationFailed, State.Stopped);
|
||||
_stateMachine.addTransition(State.Starting, VirtualMachine.Event.AgentReportRunning, State.Running);
|
||||
_stateMachine.addTransition(State.Starting, VirtualMachine.Event.AgentReportStopped, State.Stopped);
|
||||
_stateMachine.addTransition(State.Starting, VirtualMachine.Event.AgentReportShutdowned, State.Stopped);
|
||||
_stateMachine.addTransition(State.Destroyed, VirtualMachine.Event.RecoveryRequested, State.Stopped);
|
||||
_stateMachine.addTransition(State.Destroyed, VirtualMachine.Event.ExpungeOperation, State.Expunging);
|
||||
_stateMachine.addTransition(State.Running, VirtualMachine.Event.MigrationRequested, State.Migrating);
|
||||
_stateMachine.addTransition(State.Running, VirtualMachine.Event.AgentReportRunning, State.Running);
|
||||
_stateMachine.addTransition(State.Running, VirtualMachine.Event.AgentReportStopped, State.Stopped);
|
||||
_stateMachine.addTransition(State.Running, VirtualMachine.Event.StopRequested, State.Stopping);
|
||||
_stateMachine.addTransition(State.Running, VirtualMachine.Event.AgentReportShutdowned, State.Stopped);
|
||||
_stateMachine.addTransition(State.Migrating, VirtualMachine.Event.MigrationRequested, State.Migrating);
|
||||
_stateMachine.addTransition(State.Migrating, VirtualMachine.Event.OperationSucceeded, State.Running);
|
||||
_stateMachine.addTransition(State.Migrating, VirtualMachine.Event.OperationFailed, State.Running);
|
||||
_stateMachine.addTransition(State.Migrating, VirtualMachine.Event.MigrationFailedOnSource, State.Running);
|
||||
_stateMachine.addTransition(State.Migrating, VirtualMachine.Event.MigrationFailedOnDest, State.Running);
|
||||
_stateMachine.addTransition(State.Migrating, VirtualMachine.Event.AgentReportRunning, State.Running);
|
||||
_stateMachine.addTransition(State.Migrating, VirtualMachine.Event.AgentReportStopped, State.Stopped);
|
||||
_stateMachine.addTransition(State.Migrating, VirtualMachine.Event.AgentReportShutdowned, State.Stopped);
|
||||
_stateMachine.addTransition(State.Stopping, VirtualMachine.Event.OperationSucceeded, State.Stopped);
|
||||
_stateMachine.addTransition(State.Stopping, VirtualMachine.Event.OperationFailed, State.Running);
|
||||
_stateMachine.addTransition(State.Stopping, VirtualMachine.Event.AgentReportRunning, State.Running);
|
||||
_stateMachine.addTransition(State.Stopping, VirtualMachine.Event.AgentReportStopped, State.Stopped);
|
||||
_stateMachine.addTransition(State.Stopping, VirtualMachine.Event.StopRequested, State.Stopping);
|
||||
_stateMachine.addTransition(State.Stopping, VirtualMachine.Event.AgentReportShutdowned, State.Stopped);
|
||||
_stateMachine.addTransition(State.Expunging, VirtualMachine.Event.OperationFailed, State.Expunging);
|
||||
_stateMachine.addTransition(State.Expunging, VirtualMachine.Event.ExpungeOperation, State.Expunging);
|
||||
_stateMachine.addTransition(State.Error, VirtualMachine.Event.DestroyRequested, State.Expunging);
|
||||
_stateMachine.addTransition(State.Error, VirtualMachine.Event.ExpungeOperation, State.Expunging);
|
||||
|
||||
_stateMachine.registerListeners(_stateListner);
|
||||
_stateMachine = VirtualMachine.State.getStateMachine();
|
||||
}
|
||||
|
||||
protected boolean stateTransitTo(VMInstanceVO vm, VirtualMachine.Event e, Long hostId, String reservationId) {
|
||||
@ -1019,11 +977,6 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager {
|
||||
Commands cmds = new Commands(OnError.Revert);
|
||||
CheckVirtualMachineCommand cvm = new CheckVirtualMachineCommand(vm.getInstanceName());
|
||||
cmds.addCommand(cvm);
|
||||
|
||||
if (vm.getType() != VirtualMachine.Type.User) {
|
||||
NetworkRulesSystemVmCommand nrc = new NetworkRulesSystemVmCommand(vm.getInstanceName(), vm.getType());
|
||||
cmds.addCommand(nrc);
|
||||
}
|
||||
|
||||
_agentMgr.send(dstHostId, cmds);
|
||||
CheckVirtualMachineAnswer answer = cmds.getAnswer(CheckVirtualMachineAnswer.class);
|
||||
@ -1040,7 +993,6 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
// FIXME: _networkGroupMgr.handleVmStateTransition(vm, State.Running);
|
||||
stateTransitTo(vm, VirtualMachine.Event.OperationSucceeded, dstHostId);
|
||||
migrated = true;
|
||||
return vm;
|
||||
@ -1176,5 +1128,65 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager {
|
||||
|
||||
return rebootedVm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean preStateTransitionEvent(State oldState,
|
||||
Event event, State newState, VirtualMachine vm, boolean transitionStatus, Long id) {
|
||||
s_logger.debug("VM state transitted from :" + oldState + " to " + newState + " with event: " + event +
|
||||
"vm's original host id: " + vm.getHostId() + " new host id: " + id);
|
||||
if (!transitionStatus) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (oldState == State.Starting) {
|
||||
if (event == Event.OperationSucceeded) {
|
||||
if (vm.getLastHostId() != null && vm.getLastHostId() != id) {
|
||||
/*need to release the reserved capacity on lasthost*/
|
||||
_capacityMgr.releaseVmCapacity(vm, true, false, vm.getLastHostId());
|
||||
}
|
||||
vm.setLastHostId(id);
|
||||
} else if (event == Event.OperationFailed) {
|
||||
_capacityMgr.releaseVmCapacity(vm, false, false, vm.getHostId());
|
||||
} else if (event == Event.OperationRetry) {
|
||||
_capacityMgr.releaseVmCapacity(vm, false, false, vm.getHostId());
|
||||
} else if (event == Event.AgentReportStopped) {
|
||||
_capacityMgr.releaseVmCapacity(vm, false, true, vm.getHostId());
|
||||
}
|
||||
} else if (oldState == State.Running) {
|
||||
if (event == Event.AgentReportStopped) {
|
||||
_capacityMgr.releaseVmCapacity(vm, false, true, vm.getHostId());
|
||||
}
|
||||
} else if (oldState == State.Migrating) {
|
||||
if (event == Event.AgentReportStopped) {
|
||||
/*Release capacity from original host*/
|
||||
_capacityMgr.releaseVmCapacity(vm, false, true, vm.getHostId());
|
||||
} else if (event == Event.MigrationFailedOnSource) {
|
||||
/*release capacity from dest host*/
|
||||
_capacityMgr.releaseVmCapacity(vm, false, false, id);
|
||||
id = vm.getHostId();
|
||||
} else if (event == Event.MigrationFailedOnDest) {
|
||||
/*release capacify from original host*/
|
||||
_capacityMgr.releaseVmCapacity(vm, false, false, vm.getHostId());
|
||||
} else if (event == Event.OperationSucceeded) {
|
||||
_capacityMgr.releaseVmCapacity(vm, false, false, vm.getHostId());
|
||||
/*set lasthost id to migration destination host id*/
|
||||
vm.setLastHostId(id);
|
||||
}
|
||||
} else if (oldState == State.Stopping) {
|
||||
if (event == Event.AgentReportStopped || event == Event.OperationSucceeded) {
|
||||
_capacityMgr.releaseVmCapacity(vm, false, true, vm.getHostId());
|
||||
}
|
||||
} else if (oldState == State.Stopped) {
|
||||
if (event == Event.DestroyRequested) {
|
||||
_capacityMgr.releaseVmCapacity(vm, true, false, vm.getLastHostId());
|
||||
vm.setLastHostId(null);
|
||||
}
|
||||
}
|
||||
return transitionStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean postStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vo, boolean status) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,17 +21,13 @@ import java.util.List;
|
||||
|
||||
import com.cloud.network.router.VirtualRouter.Role;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import com.cloud.utils.fsm.StateDao;
|
||||
import com.cloud.vm.DomainRouterVO;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
|
||||
/**
|
||||
*
|
||||
* DomainRouterDao implements
|
||||
*/
|
||||
public interface DomainRouterDao extends GenericDao<DomainRouterVO, Long>, StateDao<State, VirtualMachine.Event, VMInstanceVO> {
|
||||
public interface DomainRouterDao extends GenericDao<DomainRouterVO, Long>{
|
||||
/**
|
||||
* gets the DomainRouterVO by user id and data center
|
||||
* @Param dcId data center Id.
|
||||
@ -55,16 +51,6 @@ public interface DomainRouterDao extends GenericDao<DomainRouterVO, Long>, State
|
||||
*/
|
||||
public List<DomainRouterVO> listBy(long userId);
|
||||
|
||||
/**
|
||||
* Update the domainrouterVO only if the state is correct and the hostId is set.
|
||||
*
|
||||
* @param router router object
|
||||
* @param event event that forces this update
|
||||
* @param hostId host id to set to.
|
||||
* @return true if update worked; false if not.
|
||||
*/
|
||||
public boolean updateIf(DomainRouterVO router, VirtualMachine.Event event, Long hostId);
|
||||
|
||||
/**
|
||||
* list virtual machine routers by host id. pass in null to get all
|
||||
* virtual machine routers.
|
||||
|
||||
@ -20,7 +20,6 @@ package com.cloud.vm.dao;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.ejb.Local;
|
||||
@ -36,9 +35,6 @@ import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.db.UpdateBuilder;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.vm.DomainRouterVO;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachine.Event;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
|
||||
@Local(value = { DomainRouterDao.class })
|
||||
@ -148,57 +144,6 @@ public class DomainRouterDaoImpl extends GenericDaoBase<DomainRouterVO, Long> im
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateIf(DomainRouterVO router, VirtualMachine.Event event, Long hostId) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("updateIf called on " + router.toString() + " event " + event.toString() + " host " + hostId);
|
||||
}
|
||||
State oldState = router.getState();
|
||||
State newState = oldState.getNextState(event);
|
||||
long oldDate = router.getUpdated();
|
||||
|
||||
Long oldHostId = router.getHostId();
|
||||
|
||||
if (newState == null) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("There's no way to transition from old state: " + oldState.toString() + " event: " + event.toString());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
SearchCriteria<DomainRouterVO> sc = StateChangeSearch.create();
|
||||
sc.setParameters("id", router.getId());
|
||||
sc.setParameters("states", oldState);
|
||||
sc.setParameters("host", router.getHostId());
|
||||
sc.setParameters("update", router.getUpdated());
|
||||
|
||||
router.incrUpdated();
|
||||
UpdateBuilder ub = getUpdateBuilder(router);
|
||||
if(newState == State.Running) {
|
||||
// save current running host id
|
||||
ub.set(router, "lastHostId", router.getHostId());
|
||||
}
|
||||
|
||||
ub.set(router, "state", newState);
|
||||
ub.set(router, "hostId", hostId);
|
||||
ub.set(router, _updateTimeAttr, new Date());
|
||||
|
||||
int result = update(router, sc);
|
||||
if (result == 0 && s_logger.isDebugEnabled()) {
|
||||
DomainRouterVO vo = findById(router.getId());
|
||||
StringBuilder str = new StringBuilder("Unable to update ").append(vo.toString());
|
||||
str.append(": DB Data={Host=").append(vo.getHostId()).append("; State=").append(vo.getState().toString()).append("; updated=").append(
|
||||
vo.getUpdated());
|
||||
str.append("} New Data: {Host=").append(router.getHostId()).append("; State=").append(router.getState().toString()).append("; updated=").append(
|
||||
router.getUpdated());
|
||||
str.append("} Stale Data: {Host=").append(oldHostId).append("; State=").append(oldState.toString()).append("; updated=").append(oldDate)
|
||||
.append("}");
|
||||
s_logger.debug(str.toString());
|
||||
}
|
||||
|
||||
return result > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DomainRouterVO> listByDataCenter(long dcId) {
|
||||
SearchCriteria<DomainRouterVO> sc = DcSearch.create();
|
||||
@ -294,41 +239,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase<DomainRouterVO, Long> im
|
||||
return findOneIncludingRemovedBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateState(State oldState, Event event,
|
||||
State newState, VMInstanceVO vm, Long hostId) {
|
||||
if (newState == null) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("There's no way to transition from old state: " + oldState.toString() + " event: " + event.toString());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
DomainRouterVO routerVM = (DomainRouterVO)vm;
|
||||
|
||||
SearchCriteria<DomainRouterVO> sc = StateChangeSearch.create();
|
||||
sc.setParameters("id", routerVM.getId());
|
||||
sc.setParameters("states", oldState);
|
||||
sc.setParameters("host", routerVM.getHostId());
|
||||
sc.setParameters("update", routerVM.getUpdated());
|
||||
|
||||
vm.incrUpdated();
|
||||
UpdateBuilder ub = getUpdateBuilder(routerVM);
|
||||
ub.set(routerVM, "state", newState);
|
||||
ub.set(routerVM, "hostId", hostId);
|
||||
ub.set(routerVM, _updateTimeAttr, new Date());
|
||||
|
||||
int result = update(routerVM, sc);
|
||||
if (result == 0 && s_logger.isDebugEnabled()) {
|
||||
DomainRouterVO vo = findById(routerVM.getId());
|
||||
StringBuilder str = new StringBuilder("Unable to update ").append(vo.toString());
|
||||
str.append(": DB Data={Host=").append(vo.getHostId()).append("; State=").append(vo.getState().toString()).append("; updated=").append(vo.getUpdated());
|
||||
str.append("} Stale Data: {Host=").append(routerVM.getHostId()).append("; State=").append(routerVM.getState().toString()).append("; updated=").append(routerVM.getUpdated()).append("}");
|
||||
s_logger.debug(str.toString());
|
||||
}
|
||||
return result > 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<DomainRouterVO> listByLastHostId(Long hostId) {
|
||||
SearchCriteria<DomainRouterVO> sc = LastHostSearch.create();
|
||||
|
||||
@ -31,7 +31,7 @@ import com.cloud.vm.VirtualMachine.State;
|
||||
/*
|
||||
* Data Access Object for vm_instance table
|
||||
*/
|
||||
public interface VMInstanceDao extends GenericDao<VMInstanceVO, Long>, StateDao<State, VirtualMachine.Event, VMInstanceVO> {
|
||||
public interface VMInstanceDao extends GenericDao<VMInstanceVO, Long>, StateDao<State, VirtualMachine.Event, VirtualMachine> {
|
||||
/**
|
||||
* What are the vms running on this host?
|
||||
* @param hostId host.
|
||||
|
||||
@ -280,32 +280,33 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
|
||||
|
||||
@Override
|
||||
public boolean updateState(State oldState, Event event,
|
||||
State newState, VMInstanceVO vm, Long hostId) {
|
||||
State newState, VirtualMachine vm, Long hostId) {
|
||||
if (newState == null) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("There's no way to transition from old state: " + oldState.toString() + " event: " + event.toString());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
VMInstanceVO vmi = (VMInstanceVO)vm;
|
||||
|
||||
SearchCriteria<VMInstanceVO> sc = StateChangeSearch.create();
|
||||
sc.setParameters("id", vm.getId());
|
||||
sc.setParameters("id", vmi.getId());
|
||||
sc.setParameters("states", oldState);
|
||||
sc.setParameters("host", vm.getHostId());
|
||||
sc.setParameters("update", vm.getUpdated());
|
||||
sc.setParameters("host", vmi.getHostId());
|
||||
sc.setParameters("update", vmi.getUpdated());
|
||||
|
||||
vm.incrUpdated();
|
||||
UpdateBuilder ub = getUpdateBuilder(vm);
|
||||
ub.set(vm, "state", newState);
|
||||
ub.set(vm, "hostId", hostId);
|
||||
ub.set(vm, _updateTimeAttr, new Date());
|
||||
vmi.incrUpdated();
|
||||
UpdateBuilder ub = getUpdateBuilder(vmi);
|
||||
ub.set(vmi, "state", newState);
|
||||
ub.set(vmi, "hostId", hostId);
|
||||
ub.set(vmi, _updateTimeAttr, new Date());
|
||||
|
||||
int result = update(vm, sc);
|
||||
int result = update(vmi, sc);
|
||||
if (result == 0 && s_logger.isDebugEnabled()) {
|
||||
VMInstanceVO vo = findById(vm.getId());
|
||||
StringBuilder str = new StringBuilder("Unable to update ").append(vo.toString());
|
||||
str.append(": DB Data={Host=").append(vo.getHostId()).append("; State=").append(vo.getState().toString()).append("; updated=").append(vo.getUpdated());
|
||||
str.append("} Stale Data: {Host=").append(vm.getHostId()).append("; State=").append(vm.getState().toString()).append("; updated=").append(vm.getUpdated()).append("}");
|
||||
str.append("} Stale Data: {Host=").append(vm.getHostId()).append("; State=").append(vm.getState().toString()).append("; updated=").append(vmi.getUpdated()).append("}");
|
||||
s_logger.debug(str.toString());
|
||||
}
|
||||
return result > 0;
|
||||
|
||||
@ -52,6 +52,5 @@ public interface FiniteState<S, E> {
|
||||
* @return array of events.
|
||||
*/
|
||||
Set<E> getPossibleEvents();
|
||||
|
||||
String getDescription();
|
||||
}
|
||||
|
||||
@ -18,10 +18,6 @@
|
||||
package com.cloud.utils.fsm;
|
||||
|
||||
public interface FiniteStateObject<S, E> {
|
||||
/**
|
||||
* @return finite state.
|
||||
*/
|
||||
FiniteState<S, E> getState();
|
||||
|
||||
|
||||
void setState(S state);
|
||||
}
|
||||
|
||||
@ -1,8 +1,28 @@
|
||||
package com.cloud.utils.fsm;
|
||||
|
||||
import com.cloud.utils.component.Adapter;
|
||||
|
||||
|
||||
public interface StateListener <S,E,V> extends Adapter{
|
||||
public boolean processStateTransitionEvent(S oldState, E event, S newState, V vo, boolean status, Long id, StateDao<S,E,V> vmDao);
|
||||
public interface StateListener <S,E,V> {
|
||||
/**
|
||||
* Event is triggered before state machine transition finished.
|
||||
* If you want to get the state of vm before state machine changed, you need to listen on this event
|
||||
* @param oldState VM's old state
|
||||
* @param event that triggered this VM state change
|
||||
* @param newState VM's new state
|
||||
* @param vo the VM instance
|
||||
* @param status the state transition is allowed or not
|
||||
* @param id host id
|
||||
* @param vmDao VM dao
|
||||
* @return
|
||||
*/
|
||||
public boolean preStateTransitionEvent(S oldState, E event, S newState, V vo, boolean status, Long id);
|
||||
|
||||
/**
|
||||
* Event is triggered after state machine transition finished
|
||||
* @param oldState VM's old state
|
||||
* @param event that triggered this VM state change
|
||||
* @param newState VM's new state
|
||||
* @param vo the VM instance
|
||||
* @param status the state transition is allowed or not
|
||||
* @return
|
||||
*/
|
||||
public boolean postStateTransitionEvent(S oldState, E event, S newState, V vo, boolean status);
|
||||
}
|
||||
@ -24,10 +24,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.cloud.utils.component.Adapters;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* StateMachine is a partial implementation of a finite state machine.
|
||||
* Specifically, it implements the Moore machine.
|
||||
@ -109,21 +105,22 @@ public class StateMachine2<S, E, V extends StateObject<S>> {
|
||||
}
|
||||
|
||||
for (StateListener<S,E, V> listener : _listeners) {
|
||||
transitionStatus = listener.processStateTransitionEvent(currentState, e, nextState, vo, transitionStatus, id, dao);
|
||||
listener.preStateTransitionEvent(currentState, e, nextState, vo, transitionStatus, id);
|
||||
}
|
||||
|
||||
transitionStatus = dao.updateState(currentState, e, nextState, vo, id);
|
||||
|
||||
for (StateListener<S,E, V> listener : _listeners) {
|
||||
listener.postStateTransitionEvent(currentState, e, nextState, vo, transitionStatus);
|
||||
}
|
||||
|
||||
return transitionStatus;
|
||||
}
|
||||
|
||||
public boolean registerListener(StateListener<S,E,V> listener) {
|
||||
return _listeners.add(listener);
|
||||
}
|
||||
|
||||
public boolean registerListeners(Adapters<StateListener<S,E,V>> listeners) {
|
||||
for (StateListener<S,E,V> listener : listeners) {
|
||||
_listeners.add(listener);
|
||||
}
|
||||
return true;
|
||||
synchronized (_listeners) {
|
||||
return _listeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user