mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
CLOUDSTACK-7648: There are new VM State Machine changes introduced which were missed to capture the usage events
This commit is contained in:
parent
b6cacb3d67
commit
50185b7c3a
@ -16,6 +16,7 @@
|
||||
// under the License.
|
||||
package com.cloud.vm;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
@ -26,6 +27,8 @@ import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.utils.fsm.StateMachine2;
|
||||
import com.cloud.utils.fsm.StateMachine2.Transition;
|
||||
import com.cloud.utils.fsm.StateMachine2.Transition.Impact;
|
||||
import com.cloud.utils.fsm.StateObject;
|
||||
|
||||
/**
|
||||
@ -75,63 +78,63 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, Identity, I
|
||||
|
||||
protected static final StateMachine2<State, VirtualMachine.Event, VirtualMachine> s_fsm = new StateMachine2<State, VirtualMachine.Event, VirtualMachine>();
|
||||
static {
|
||||
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(new Transition<State, Event>(State.Stopped, VirtualMachine.Event.StartRequested, State.Starting, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Stopped, VirtualMachine.Event.DestroyRequested, State.Destroyed, Arrays.asList(new Impact[]{Impact.USAGE})));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Stopped, VirtualMachine.Event.StopRequested, State.Stopped, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Stopped, VirtualMachine.Event.AgentReportStopped, State.Stopped, null));
|
||||
|
||||
// please pay attention about state transition to Error state, there should be only one case (failed in VM
|
||||
// creation process)
|
||||
// that can have such transition
|
||||
s_fsm.addTransition(State.Stopped, VirtualMachine.Event.OperationFailedToError, State.Error);
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Stopped, VirtualMachine.Event.OperationFailedToError, State.Error, Arrays.asList(new Impact[]{Impact.USAGE})));
|
||||
|
||||
s_fsm.addTransition(State.Stopped, VirtualMachine.Event.OperationFailed, State.Stopped);
|
||||
s_fsm.addTransition(State.Stopped, VirtualMachine.Event.ExpungeOperation, State.Expunging);
|
||||
s_fsm.addTransition(State.Stopped, VirtualMachine.Event.AgentReportShutdowned, State.Stopped);
|
||||
s_fsm.addTransition(State.Stopped, VirtualMachine.Event.StorageMigrationRequested, State.Migrating);
|
||||
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.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.Running, VirtualMachine.Event.AgentReportMigrated, State.Running);
|
||||
s_fsm.addTransition(State.Running, VirtualMachine.Event.OperationSucceeded, State.Running);
|
||||
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.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.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.Error, VirtualMachine.Event.DestroyRequested, State.Expunging);
|
||||
s_fsm.addTransition(State.Error, VirtualMachine.Event.ExpungeOperation, State.Expunging);
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Stopped, VirtualMachine.Event.OperationFailed, State.Stopped, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Stopped, VirtualMachine.Event.ExpungeOperation, State.Expunging, Arrays.asList(new Impact[]{Impact.USAGE})));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Stopped, VirtualMachine.Event.AgentReportShutdowned, State.Stopped, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Stopped, VirtualMachine.Event.StorageMigrationRequested, State.Migrating, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Starting, VirtualMachine.Event.OperationRetry, State.Starting, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Starting, VirtualMachine.Event.OperationSucceeded, State.Running, Arrays.asList(new Impact[]{Impact.USAGE})));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Starting, VirtualMachine.Event.OperationFailed, State.Stopped, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Starting, VirtualMachine.Event.AgentReportRunning, State.Running, Arrays.asList(new Impact[]{Impact.USAGE})));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Starting, VirtualMachine.Event.AgentReportStopped, State.Stopped, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Starting, VirtualMachine.Event.AgentReportShutdowned, State.Stopped, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Destroyed, VirtualMachine.Event.RecoveryRequested, State.Stopped, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Destroyed, VirtualMachine.Event.ExpungeOperation, State.Expunging, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Running, VirtualMachine.Event.MigrationRequested, State.Migrating, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Running, VirtualMachine.Event.AgentReportRunning, State.Running, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Running, VirtualMachine.Event.AgentReportStopped, State.Stopped, Arrays.asList(new Impact[]{Impact.USAGE})));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Running, VirtualMachine.Event.StopRequested, State.Stopping, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Running, VirtualMachine.Event.AgentReportShutdowned, State.Stopped, Arrays.asList(new Impact[]{Impact.USAGE})));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Running, VirtualMachine.Event.AgentReportMigrated, State.Running, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Running, VirtualMachine.Event.OperationSucceeded, State.Running, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Migrating, VirtualMachine.Event.MigrationRequested, State.Migrating, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Migrating, VirtualMachine.Event.OperationSucceeded, State.Running, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Migrating, VirtualMachine.Event.OperationFailed, State.Running, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Migrating, VirtualMachine.Event.AgentReportRunning, State.Running, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Migrating, VirtualMachine.Event.AgentReportStopped, State.Stopped, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Migrating, VirtualMachine.Event.AgentReportShutdowned, State.Stopped, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Stopping, VirtualMachine.Event.OperationSucceeded, State.Stopped, Arrays.asList(new Impact[]{Impact.USAGE})));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Stopping, VirtualMachine.Event.OperationFailed, State.Running, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Stopping, VirtualMachine.Event.AgentReportRunning, State.Running, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Stopping, VirtualMachine.Event.AgentReportStopped, State.Stopped, Arrays.asList(new Impact[]{Impact.USAGE})));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Stopping, VirtualMachine.Event.StopRequested, State.Stopping, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Stopping, VirtualMachine.Event.AgentReportShutdowned, State.Stopped, Arrays.asList(new Impact[]{Impact.USAGE})));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Expunging, VirtualMachine.Event.OperationFailed, State.Expunging,null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Expunging, VirtualMachine.Event.ExpungeOperation, State.Expunging,null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Error, VirtualMachine.Event.DestroyRequested, State.Expunging, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Error, VirtualMachine.Event.ExpungeOperation, State.Expunging, null));
|
||||
|
||||
s_fsm.addTransition(State.Starting, VirtualMachine.Event.FollowAgentPowerOnReport, State.Running);
|
||||
s_fsm.addTransition(State.Stopping, VirtualMachine.Event.FollowAgentPowerOnReport, State.Running);
|
||||
s_fsm.addTransition(State.Stopped, VirtualMachine.Event.FollowAgentPowerOnReport, State.Running);
|
||||
s_fsm.addTransition(State.Running, VirtualMachine.Event.FollowAgentPowerOnReport, State.Running);
|
||||
s_fsm.addTransition(State.Migrating, VirtualMachine.Event.FollowAgentPowerOnReport, State.Running);
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Starting, VirtualMachine.Event.FollowAgentPowerOnReport, State.Running, Arrays.asList(new Impact[]{Impact.USAGE})));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Stopping, VirtualMachine.Event.FollowAgentPowerOnReport, State.Running, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Stopped, VirtualMachine.Event.FollowAgentPowerOnReport, State.Running, Arrays.asList(new Impact[]{Impact.USAGE})));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Running, VirtualMachine.Event.FollowAgentPowerOnReport, State.Running, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Migrating, VirtualMachine.Event.FollowAgentPowerOnReport, State.Running, null));
|
||||
|
||||
s_fsm.addTransition(State.Starting, VirtualMachine.Event.FollowAgentPowerOffReport, State.Stopped);
|
||||
s_fsm.addTransition(State.Stopping, VirtualMachine.Event.FollowAgentPowerOffReport, State.Stopped);
|
||||
s_fsm.addTransition(State.Running, VirtualMachine.Event.FollowAgentPowerOffReport, State.Stopped);
|
||||
s_fsm.addTransition(State.Migrating, VirtualMachine.Event.FollowAgentPowerOffReport, State.Stopped);
|
||||
s_fsm.addTransition(State.Stopped, VirtualMachine.Event.FollowAgentPowerOffReport, State.Stopped);
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Starting, VirtualMachine.Event.FollowAgentPowerOffReport, State.Stopped, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Stopping, VirtualMachine.Event.FollowAgentPowerOffReport, State.Stopped, Arrays.asList(new Impact[]{Impact.USAGE})));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Running, VirtualMachine.Event.FollowAgentPowerOffReport, State.Stopped, Arrays.asList(new Impact[]{Impact.USAGE})));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Migrating, VirtualMachine.Event.FollowAgentPowerOffReport, State.Stopped, null));
|
||||
s_fsm.addTransition(new Transition<State, Event>(State.Stopped, VirtualMachine.Event.FollowAgentPowerOffReport, State.Stopped, null));
|
||||
}
|
||||
|
||||
public static boolean isVmStarted(State oldState, Event e, State newState) {
|
||||
|
||||
@ -24,6 +24,7 @@ import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.utils.fsm.StateMachine2;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
|
||||
@ -65,12 +66,15 @@ public class NetworkStateListener implements StateListener<State, Event, Network
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean postStateTransitionEvent(State oldState, Event event, State newState, Network vo, boolean status, Object opaque) {
|
||||
pubishOnEventBus(event.name(), "postStateTransitionEvent", vo, oldState, newState);
|
||||
return true;
|
||||
public boolean postStateTransitionEvent(StateMachine2.Transition<State, Event> transition, Network vo, boolean status, Object opaque) {
|
||||
State oldState = transition.getCurrentState();
|
||||
State newState = transition.getToState();
|
||||
Event event = transition.getEvent();
|
||||
pubishOnEventBus(event.name(), "postStateTransitionEvent", vo, oldState, newState);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void pubishOnEventBus(String event, String status, Network vo, State oldState, State newState) {
|
||||
private void pubishOnEventBus(String event, String status, Network vo, State oldState, State newState) {
|
||||
|
||||
String configKey = "publish.resource.state.events";
|
||||
String value = _configDao.getValue(configKey);
|
||||
|
||||
@ -29,6 +29,7 @@ import javax.naming.ConfigurationException;
|
||||
import com.cloud.utils.db.QueryBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.fsm.StateMachine2;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import org.apache.cloudstack.api.BaremetalProvisionDoneNotificationCmd;
|
||||
@ -81,37 +82,39 @@ public class BaremetalManagerImpl extends ManagerBase implements BaremetalManage
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean postStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vo, boolean status, Object opaque) {
|
||||
if (newState != State.Starting && newState != State.Error && newState != State.Expunging) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (vo.getHypervisorType() != HypervisorType.BareMetal) {
|
||||
return true;
|
||||
}
|
||||
|
||||
HostVO host = _hostDao.findById(vo.getHostId());
|
||||
if (host == null) {
|
||||
s_logger.debug("Skip oldState " + oldState + " to " + "newState " + newState + " transimtion");
|
||||
return true;
|
||||
}
|
||||
_hostDao.loadDetails(host);
|
||||
|
||||
if (newState == State.Starting) {
|
||||
host.setDetail("vmName", vo.getInstanceName());
|
||||
s_logger.debug("Add vmName " + host.getDetail("vmName") + " to host " + host.getId() + " details");
|
||||
} else {
|
||||
if (host.getDetail("vmName") != null && host.getDetail("vmName").equalsIgnoreCase(vo.getInstanceName())) {
|
||||
s_logger.debug("Remove vmName " + host.getDetail("vmName") + " from host " + host.getId() + " details");
|
||||
host.getDetails().remove("vmName");
|
||||
}
|
||||
}
|
||||
_hostDao.saveDetails(host);
|
||||
|
||||
public boolean postStateTransitionEvent(StateMachine2.Transition<State, Event> transition, VirtualMachine vo, boolean status, Object opaque) {
|
||||
State newState = transition.getToState();
|
||||
State oldState = transition.getCurrentState();
|
||||
if (newState != State.Starting && newState != State.Error && newState != State.Expunging) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (vo.getHypervisorType() != HypervisorType.BareMetal) {
|
||||
return true;
|
||||
}
|
||||
|
||||
HostVO host = _hostDao.findById(vo.getHostId());
|
||||
if (host == null) {
|
||||
s_logger.debug("Skip oldState " + oldState + " to " + "newState " + newState + " transimtion");
|
||||
return true;
|
||||
}
|
||||
_hostDao.loadDetails(host);
|
||||
|
||||
if (newState == State.Starting) {
|
||||
host.setDetail("vmName", vo.getInstanceName());
|
||||
s_logger.debug("Add vmName " + host.getDetail("vmName") + " to host " + host.getId() + " details");
|
||||
} else {
|
||||
if (host.getDetail("vmName") != null && host.getDetail("vmName").equalsIgnoreCase(vo.getInstanceName())) {
|
||||
s_logger.debug("Remove vmName " + host.getDetail("vmName") + " from host " + host.getId() + " details");
|
||||
host.getDetails().remove("vmName");
|
||||
}
|
||||
}
|
||||
_hostDao.saveDetails(host);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public List<Class<?>> getCommands() {
|
||||
List<Class<?>> cmds = new ArrayList<Class<?>>();
|
||||
cmds.add(AddBaremetalHostCmd.class);
|
||||
|
||||
@ -36,6 +36,7 @@ import com.cloud.network.vpc.dao.VpcDao;
|
||||
import com.cloud.network.vpc.VpcManager;
|
||||
import com.cloud.network.vpc.VpcVO;
|
||||
import com.cloud.network.vpc.dao.NetworkACLDao;
|
||||
import com.cloud.utils.fsm.StateMachine2;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import com.cloud.vm.Nic;
|
||||
@ -680,25 +681,26 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean postStateTransitionEvent(VirtualMachine.State oldState, VirtualMachine.Event event,
|
||||
VirtualMachine.State newState, VirtualMachine vm,
|
||||
boolean status, Object opaque) {
|
||||
if (!status) {
|
||||
return false;
|
||||
}
|
||||
public boolean postStateTransitionEvent(StateMachine2.Transition<VirtualMachine.State, VirtualMachine.Event> transition, VirtualMachine vm, boolean status, Object opaque) {
|
||||
if (!status) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (VirtualMachine.State.isVmStarted(oldState, event, newState)) {
|
||||
handleVmStateChange((VMInstanceVO)vm);
|
||||
} else if (VirtualMachine.State.isVmStopped(oldState, event, newState)) {
|
||||
handleVmStateChange((VMInstanceVO)vm);
|
||||
} else if (VirtualMachine.State.isVmMigrated(oldState, event, newState)) {
|
||||
handleVmStateChange((VMInstanceVO)vm);
|
||||
}
|
||||
VirtualMachine.State oldState = transition.getCurrentState();
|
||||
VirtualMachine.State newState = transition.getToState();
|
||||
VirtualMachine.Event event = transition.getEvent();
|
||||
if (VirtualMachine.State.isVmStarted(oldState, event, newState)) {
|
||||
handleVmStateChange((VMInstanceVO)vm);
|
||||
} else if (VirtualMachine.State.isVmStopped(oldState, event, newState)) {
|
||||
handleVmStateChange((VMInstanceVO)vm);
|
||||
} else if (VirtualMachine.State.isVmMigrated(oldState, event, newState)) {
|
||||
handleVmStateChange((VMInstanceVO)vm);
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void handleVmStateChange(VMInstanceVO vm) {
|
||||
private void handleVmStateChange(VMInstanceVO vm) {
|
||||
|
||||
// get the VPC's impacted with the VM start
|
||||
List<Long> vpcIds = _ovsNetworkToplogyGuru.getVpcIdsVmIsPartOf(vm.getId());
|
||||
|
||||
@ -27,6 +27,7 @@ import javax.ejb.Local;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.utils.fsm.StateMachine2;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
|
||||
@ -770,79 +771,82 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager,
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean postStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vm, boolean status, Object opaque) {
|
||||
if (!status) {
|
||||
return false;
|
||||
public boolean postStateTransitionEvent(StateMachine2.Transition<State, Event> transition, VirtualMachine vm, boolean status, Object opaque) {
|
||||
if (!status) {
|
||||
return false;
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
Pair<Long, Long> hosts = (Pair<Long, Long>)opaque;
|
||||
Long oldHostId = hosts.first();
|
||||
|
||||
State oldState = transition.getCurrentState();
|
||||
State newState = transition.getToState();
|
||||
Event event = transition.getEvent();
|
||||
s_logger.debug("VM state transitted from :" + oldState + " to " + newState + " with event: " + event + "vm's original host id: " + vm.getLastHostId() +
|
||||
" new host id: " + vm.getHostId() + " host id before state transition: " + oldHostId);
|
||||
|
||||
if (oldState == State.Starting) {
|
||||
if (newState != State.Running) {
|
||||
releaseVmCapacity(vm, false, false, oldHostId);
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
Pair<Long, Long> hosts = (Pair<Long, Long>)opaque;
|
||||
Long oldHostId = hosts.first();
|
||||
|
||||
s_logger.debug("VM state transitted from :" + oldState + " to " + newState + " with event: " + event + "vm's original host id: " + vm.getLastHostId() +
|
||||
" new host id: " + vm.getHostId() + " host id before state transition: " + oldHostId);
|
||||
|
||||
if (oldState == State.Starting) {
|
||||
if (newState != State.Running) {
|
||||
releaseVmCapacity(vm, false, false, oldHostId);
|
||||
}
|
||||
} else if (oldState == State.Running) {
|
||||
if (event == Event.AgentReportStopped) {
|
||||
releaseVmCapacity(vm, false, true, oldHostId);
|
||||
} else if (event == Event.AgentReportMigrated) {
|
||||
releaseVmCapacity(vm, false, false, oldHostId);
|
||||
}
|
||||
} else if (oldState == State.Migrating) {
|
||||
if (event == Event.AgentReportStopped) {
|
||||
} else if (oldState == State.Running) {
|
||||
if (event == Event.AgentReportStopped) {
|
||||
releaseVmCapacity(vm, false, true, oldHostId);
|
||||
} else if (event == Event.AgentReportMigrated) {
|
||||
releaseVmCapacity(vm, false, false, oldHostId);
|
||||
}
|
||||
} else if (oldState == State.Migrating) {
|
||||
if (event == Event.AgentReportStopped) {
|
||||
/* Release capacity from original host */
|
||||
releaseVmCapacity(vm, false, false, vm.getLastHostId());
|
||||
releaseVmCapacity(vm, false, false, oldHostId);
|
||||
} else if (event == Event.OperationFailed) {
|
||||
releaseVmCapacity(vm, false, false, vm.getLastHostId());
|
||||
releaseVmCapacity(vm, false, false, oldHostId);
|
||||
} else if (event == Event.OperationFailed) {
|
||||
/* Release from dest host */
|
||||
releaseVmCapacity(vm, false, false, oldHostId);
|
||||
} else if (event == Event.OperationSucceeded) {
|
||||
releaseVmCapacity(vm, false, false, vm.getLastHostId());
|
||||
}
|
||||
} else if (oldState == State.Stopping) {
|
||||
if (event == Event.OperationSucceeded) {
|
||||
releaseVmCapacity(vm, false, true, oldHostId);
|
||||
} else if (event == Event.AgentReportStopped) {
|
||||
releaseVmCapacity(vm, false, false, oldHostId);
|
||||
} else if (event == Event.AgentReportMigrated) {
|
||||
releaseVmCapacity(vm, false, false, oldHostId);
|
||||
}
|
||||
} else if (oldState == State.Stopped) {
|
||||
if (event == Event.DestroyRequested || event == Event.ExpungeOperation) {
|
||||
releaseVmCapacity(vm, true, false, vm.getLastHostId());
|
||||
} else if (event == Event.AgentReportMigrated) {
|
||||
releaseVmCapacity(vm, false, false, oldHostId);
|
||||
}
|
||||
releaseVmCapacity(vm, false, false, oldHostId);
|
||||
} else if (event == Event.OperationSucceeded) {
|
||||
releaseVmCapacity(vm, false, false, vm.getLastHostId());
|
||||
}
|
||||
|
||||
if ((newState == State.Starting || newState == State.Migrating || event == Event.AgentReportMigrated) && vm.getHostId() != null) {
|
||||
boolean fromLastHost = false;
|
||||
if (vm.getHostId().equals(vm.getLastHostId())) {
|
||||
s_logger.debug("VM starting again on the last host it was stopped on");
|
||||
fromLastHost = true;
|
||||
}
|
||||
allocateVmCapacity(vm, fromLastHost);
|
||||
} else if (oldState == State.Stopping) {
|
||||
if (event == Event.OperationSucceeded) {
|
||||
releaseVmCapacity(vm, false, true, oldHostId);
|
||||
} else if (event == Event.AgentReportStopped) {
|
||||
releaseVmCapacity(vm, false, false, oldHostId);
|
||||
} else if (event == Event.AgentReportMigrated) {
|
||||
releaseVmCapacity(vm, false, false, oldHostId);
|
||||
}
|
||||
|
||||
if (newState == State.Stopped) {
|
||||
if (vm.getType() == VirtualMachine.Type.User) {
|
||||
|
||||
UserVmVO userVM = _userVMDao.findById(vm.getId());
|
||||
_userVMDao.loadDetails(userVM);
|
||||
// free the message sent flag if it exists
|
||||
userVM.setDetail(MESSAGE_RESERVED_CAPACITY_FREED_FLAG, "false");
|
||||
_userVMDao.saveDetails(userVM);
|
||||
|
||||
}
|
||||
} else if (oldState == State.Stopped) {
|
||||
if (event == Event.DestroyRequested || event == Event.ExpungeOperation) {
|
||||
releaseVmCapacity(vm, true, false, vm.getLastHostId());
|
||||
} else if (event == Event.AgentReportMigrated) {
|
||||
releaseVmCapacity(vm, false, false, oldHostId);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
if ((newState == State.Starting || newState == State.Migrating || event == Event.AgentReportMigrated) && vm.getHostId() != null) {
|
||||
boolean fromLastHost = false;
|
||||
if (vm.getHostId().equals(vm.getLastHostId())) {
|
||||
s_logger.debug("VM starting again on the last host it was stopped on");
|
||||
fromLastHost = true;
|
||||
}
|
||||
allocateVmCapacity(vm, fromLastHost);
|
||||
}
|
||||
|
||||
if (newState == State.Stopped) {
|
||||
if (vm.getType() == VirtualMachine.Type.User) {
|
||||
|
||||
UserVmVO userVM = _userVMDao.findById(vm.getId());
|
||||
_userVMDao.loadDetails(userVM);
|
||||
// free the message sent flag if it exists
|
||||
userVM.setDetail(MESSAGE_RESERVED_CAPACITY_FREED_FLAG, "false");
|
||||
_userVMDao.saveDetails(userVM);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: Get rid of this case once we've determined that the capacity listeners above have all the changes
|
||||
// TODO: Get rid of this case once we've determined that the capacity listeners above have all the changes
|
||||
// create capacity entries if none exist for this server
|
||||
private void createCapacityEntry(StartupCommand startup, HostVO server) {
|
||||
SearchCriteria<CapacityVO> capacitySC = _capacityDao.createSearchCriteria();
|
||||
|
||||
@ -31,6 +31,7 @@ import javax.ejb.Local;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.utils.fsm.StateMachine2;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.affinity.AffinityGroupProcessor;
|
||||
@ -1443,16 +1444,18 @@ StateListener<State, VirtualMachine.Event, VirtualMachine> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean postStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vo, boolean status, Object opaque) {
|
||||
if (!status) {
|
||||
return false;
|
||||
}
|
||||
if ((oldState == State.Starting) && (newState != State.Starting)) {
|
||||
// cleanup all VM reservation entries
|
||||
SearchCriteria<VMReservationVO> sc = _reservationDao.createSearchCriteria();
|
||||
sc.addAnd("vmId", SearchCriteria.Op.EQ, vo.getId());
|
||||
_reservationDao.expunge(sc);
|
||||
}
|
||||
return true;
|
||||
public boolean postStateTransitionEvent(StateMachine2.Transition<State, Event> transition, VirtualMachine vo, boolean status, Object opaque) {
|
||||
if (!status) {
|
||||
return false;
|
||||
}
|
||||
State oldState = transition.getCurrentState();
|
||||
State newState = transition.getToState();
|
||||
if ((oldState == State.Starting) && (newState != State.Starting)) {
|
||||
// cleanup all VM reservation entries
|
||||
SearchCriteria<VMReservationVO> sc = _reservationDao.createSearchCriteria();
|
||||
sc.addAnd("vmId", SearchCriteria.Op.EQ, vo.getId());
|
||||
_reservationDao.expunge(sc);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -218,6 +218,7 @@ import com.cloud.utils.db.TransactionCallbackNoReturn;
|
||||
import com.cloud.utils.db.TransactionStatus;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.fsm.StateListener;
|
||||
import com.cloud.utils.fsm.StateMachine2;
|
||||
import com.cloud.utils.net.Ip;
|
||||
import com.cloud.utils.net.MacAddress;
|
||||
import com.cloud.utils.net.NetUtils;
|
||||
@ -4432,17 +4433,20 @@ VirtualMachineGuru, Listener, Configurable, StateListener<State, VirtualMachine.
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean postStateTransitionEvent(State oldState, VirtualMachine.Event event, State newState, VirtualMachine vo, boolean status, Object opaque) {
|
||||
if (oldState == State.Stopped && event == VirtualMachine.Event.FollowAgentPowerOnReport && newState == State.Running) {
|
||||
if (vo.getType() == VirtualMachine.Type.DomainRouter) {
|
||||
s_logger.info("Schedule a router reboot task as router " + vo.getId() + " is powered-on out-of-band. we need to reboot to refresh network rules");
|
||||
_executor.schedule(new RebootTask(vo.getId()), 1000, TimeUnit.MICROSECONDS);
|
||||
}
|
||||
public boolean postStateTransitionEvent(StateMachine2.Transition<State, VirtualMachine.Event> transition, VirtualMachine vo, boolean status, Object opaque) {
|
||||
State oldState = transition.getCurrentState();
|
||||
State newState = transition.getToState();
|
||||
VirtualMachine.Event event = transition.getEvent();
|
||||
if (oldState == State.Stopped && event == VirtualMachine.Event.FollowAgentPowerOnReport && newState == State.Running) {
|
||||
if (vo.getType() == VirtualMachine.Type.DomainRouter) {
|
||||
s_logger.info("Schedule a router reboot task as router " + vo.getId() + " is powered-on out-of-band. we need to reboot to refresh network rules");
|
||||
_executor.schedule(new RebootTask(vo.getId()), 1000, TimeUnit.MICROSECONDS);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected class RebootTask extends ManagedContextRunnable {
|
||||
protected class RebootTask extends ManagedContextRunnable {
|
||||
|
||||
long _routerId;
|
||||
|
||||
|
||||
@ -40,6 +40,7 @@ import javax.ejb.Local;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.utils.fsm.StateMachine2;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
@ -1279,32 +1280,35 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean postStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vm, boolean status, Object opaque) {
|
||||
if (!status) {
|
||||
return false;
|
||||
}
|
||||
public boolean postStateTransitionEvent(StateMachine2.Transition<State, Event> transition, VirtualMachine vm, boolean status, Object opaque) {
|
||||
if (!status) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (VirtualMachine.State.isVmStarted(oldState, event, newState)) {
|
||||
if (s_logger.isTraceEnabled()) {
|
||||
s_logger.trace("Security Group Mgr: handling start of vm id" + vm.getId());
|
||||
}
|
||||
handleVmStarted((VMInstanceVO)vm);
|
||||
} else if (VirtualMachine.State.isVmStopped(oldState, event, newState)) {
|
||||
if (s_logger.isTraceEnabled()) {
|
||||
s_logger.trace("Security Group Mgr: handling stop of vm id" + vm.getId());
|
||||
}
|
||||
handleVmStopped((VMInstanceVO)vm);
|
||||
} else if (VirtualMachine.State.isVmMigrated(oldState, event, newState)) {
|
||||
if (s_logger.isTraceEnabled()) {
|
||||
s_logger.trace("Security Group Mgr: handling migration of vm id" + vm.getId());
|
||||
}
|
||||
handleVmMigrated((VMInstanceVO)vm);
|
||||
State oldState = transition.getCurrentState();
|
||||
State newState = transition.getToState();
|
||||
Event event = transition.getEvent();
|
||||
if (VirtualMachine.State.isVmStarted(oldState, event, newState)) {
|
||||
if (s_logger.isTraceEnabled()) {
|
||||
s_logger.trace("Security Group Mgr: handling start of vm id" + vm.getId());
|
||||
}
|
||||
handleVmStarted((VMInstanceVO)vm);
|
||||
} else if (VirtualMachine.State.isVmStopped(oldState, event, newState)) {
|
||||
if (s_logger.isTraceEnabled()) {
|
||||
s_logger.trace("Security Group Mgr: handling stop of vm id" + vm.getId());
|
||||
}
|
||||
handleVmStopped((VMInstanceVO)vm);
|
||||
} else if (VirtualMachine.State.isVmMigrated(oldState, event, newState)) {
|
||||
if (s_logger.isTraceEnabled()) {
|
||||
s_logger.trace("Security Group Mgr: handling migration of vm id" + vm.getId());
|
||||
}
|
||||
handleVmMigrated((VMInstanceVO)vm);
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public boolean isVmSecurityGroupEnabled(Long vmId) {
|
||||
VirtualMachine vm = _vmDao.findByIdIncludingRemoved(vmId);
|
||||
List<NicProfile> nics = _networkMgr.getNicProfiles(vm);
|
||||
|
||||
@ -26,6 +26,7 @@ import javax.annotation.PostConstruct;
|
||||
import javax.ejb.Local;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.utils.fsm.StateMachine2;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.stereotype.Component;
|
||||
@ -72,12 +73,12 @@ public class SnapshotStateListener implements StateListener<State, Event, Snapsh
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean postStateTransitionEvent(State oldState, Event event, State newState, SnapshotVO vo, boolean status, Object opaque) {
|
||||
pubishOnEventBus(event.name(), "postStateTransitionEvent", vo, oldState, newState);
|
||||
return true;
|
||||
public boolean postStateTransitionEvent(StateMachine2.Transition<State, Event> transition, SnapshotVO vo, boolean status, Object opaque) {
|
||||
pubishOnEventBus(transition.getEvent().name(), "postStateTransitionEvent", vo, transition.getCurrentState(), transition.getToState());
|
||||
return true;
|
||||
}
|
||||
|
||||
private void pubishOnEventBus(String event, String status, Snapshot vo, State oldState, State newState) {
|
||||
private void pubishOnEventBus(String event, String status, Snapshot vo, State oldState, State newState) {
|
||||
|
||||
String configKey = Config.PublishResourceStateEvent.key();
|
||||
String value = s_configDao.getValue(configKey);
|
||||
|
||||
@ -22,6 +22,7 @@ import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.cloud.utils.fsm.StateMachine2;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
|
||||
@ -56,12 +57,12 @@ public class VolumeStateListener implements StateListener<State, Event, Volume>
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean postStateTransitionEvent(State oldState, Event event, State newState, Volume vo, boolean status, Object opaque) {
|
||||
pubishOnEventBus(event.name(), "postStateTransitionEvent", vo, oldState, newState);
|
||||
return true;
|
||||
public boolean postStateTransitionEvent(StateMachine2.Transition<State, Event> transition, Volume vo, boolean status, Object opaque) {
|
||||
pubishOnEventBus(transition.getEvent().name(), "postStateTransitionEvent", vo, transition.getCurrentState(), transition.getToState());
|
||||
return true;
|
||||
}
|
||||
|
||||
private void pubishOnEventBus(String event, String status, Volume vo, State oldState, State newState) {
|
||||
private void pubishOnEventBus(String event, String status, Volume vo, State oldState, State newState) {
|
||||
|
||||
String configKey = Config.PublishResourceStateEvent.key();
|
||||
String value = _configDao.getValue(configKey);
|
||||
|
||||
@ -25,6 +25,7 @@ import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.server.ManagementService;
|
||||
import com.cloud.utils.fsm.StateMachine2;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
@ -77,36 +78,40 @@ public class UserVmStateListener implements StateListener<State, VirtualMachine.
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean postStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vo, boolean status, Object opaque) {
|
||||
if (!status) {
|
||||
return false;
|
||||
}
|
||||
public boolean postStateTransitionEvent(StateMachine2.Transition<State, Event> transition, VirtualMachine vo, boolean status, Object opaque) {
|
||||
if (!status) {
|
||||
return false;
|
||||
}
|
||||
Event event = transition.getEvent();
|
||||
State oldState = transition.getCurrentState();
|
||||
State newState = transition.getToState();
|
||||
pubishOnEventBus(event.name(), "postStateTransitionEvent", vo, oldState, newState);
|
||||
|
||||
pubishOnEventBus(event.name(), "postStateTransitionEvent", vo, oldState, newState);
|
||||
|
||||
if (vo.getType() != VirtualMachine.Type.User) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (VirtualMachine.State.isVmCreated(oldState, event, newState)) {
|
||||
generateUsageEvent(vo.getServiceOfferingId(), vo, EventTypes.EVENT_VM_CREATE);
|
||||
} else if (VirtualMachine.State.isVmStarted(oldState, event, newState)) {
|
||||
generateUsageEvent(vo.getServiceOfferingId(), vo, EventTypes.EVENT_VM_START);
|
||||
} else if (VirtualMachine.State.isVmStopped(oldState, event, newState)) {
|
||||
generateUsageEvent(vo.getServiceOfferingId(), vo, EventTypes.EVENT_VM_STOP);
|
||||
List<NicVO> nics = _nicDao.listByVmId(vo.getId());
|
||||
for (NicVO nic : nics) {
|
||||
NetworkVO network = _networkDao.findById(nic.getNetworkId());
|
||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_REMOVE, vo.getAccountId(), vo.getDataCenterId(), vo.getId(),
|
||||
Long.toString(nic.getId()), network.getNetworkOfferingId(), null, 0L, vo.getClass().getName(), vo.getUuid(), vo.isDisplay());
|
||||
}
|
||||
} else if (VirtualMachine.State.isVmDestroyed(oldState, event, newState)) {
|
||||
generateUsageEvent(vo.getServiceOfferingId(), vo, EventTypes.EVENT_VM_DESTROY);
|
||||
}
|
||||
if (vo.getType() != VirtualMachine.Type.User) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(transition.isImpacted(StateMachine2.Transition.Impact.USAGE)) {
|
||||
if (oldState == State.Destroyed && newState == State.Stopped) {
|
||||
generateUsageEvent(vo.getServiceOfferingId(), vo, EventTypes.EVENT_VM_CREATE);
|
||||
} else if (newState == State.Running) {
|
||||
generateUsageEvent(vo.getServiceOfferingId(), vo, EventTypes.EVENT_VM_START);
|
||||
} else if (newState == State.Stopped) {
|
||||
generateUsageEvent(vo.getServiceOfferingId(), vo, EventTypes.EVENT_VM_STOP);
|
||||
List<NicVO> nics = _nicDao.listByVmId(vo.getId());
|
||||
for (NicVO nic : nics) {
|
||||
NetworkVO network = _networkDao.findById(nic.getNetworkId());
|
||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_REMOVE, vo.getAccountId(), vo.getDataCenterId(), vo.getId(),
|
||||
Long.toString(nic.getId()), network.getNetworkOfferingId(), null, 0L, vo.getClass().getName(), vo.getUuid(), vo.isDisplay());
|
||||
}
|
||||
} else if (newState == State.Destroyed || newState == State.Error || newState == State.Expunging) {
|
||||
generateUsageEvent(vo.getServiceOfferingId(), vo, EventTypes.EVENT_VM_DESTROY);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void generateUsageEvent(Long serviceOfferingId, VirtualMachine vm, String eventType){
|
||||
private void generateUsageEvent(Long serviceOfferingId, VirtualMachine vm, String eventType){
|
||||
boolean displayVm = true;
|
||||
if(vm.getType() == VirtualMachine.Type.User){
|
||||
UserVmVO uservm = _userVmDao.findById(vm.getId());
|
||||
|
||||
@ -26,6 +26,7 @@ import javax.ejb.Local;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.utils.fsm.StateMachine2;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
@ -439,20 +440,21 @@ public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGro
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean postStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vo, boolean status, Object opaque) {
|
||||
if (!status) {
|
||||
return false;
|
||||
}
|
||||
if ((newState == State.Expunging) || (newState == State.Error)) {
|
||||
// cleanup all affinity groups associations of the Expunged VM
|
||||
SearchCriteria<AffinityGroupVMMapVO> sc = _affinityGroupVMMapDao.createSearchCriteria();
|
||||
sc.addAnd("instanceId", SearchCriteria.Op.EQ, vo.getId());
|
||||
_affinityGroupVMMapDao.expunge(sc);
|
||||
}
|
||||
return true;
|
||||
public boolean postStateTransitionEvent(StateMachine2.Transition<State, Event> transition, VirtualMachine vo, boolean status, Object opaque) {
|
||||
if (!status) {
|
||||
return false;
|
||||
}
|
||||
State newState = transition.getToState();
|
||||
if ((newState == State.Expunging) || (newState == State.Error)) {
|
||||
// cleanup all affinity groups associations of the Expunged VM
|
||||
SearchCriteria<AffinityGroupVMMapVO> sc = _affinityGroupVMMapDao.createSearchCriteria();
|
||||
sc.addAnd("instanceId", SearchCriteria.Op.EQ, vo.getId());
|
||||
_affinityGroupVMMapDao.expunge(sc);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public UserVm updateVMAffinityGroups(Long vmId, List<Long> affinityGroupIds) {
|
||||
// Verify input parameters
|
||||
UserVmVO vmInstance = _userVmDao.findById(vmId);
|
||||
|
||||
@ -28,19 +28,16 @@ public interface StateListener<S, E, V> {
|
||||
* @param newState VM's new state
|
||||
* @param vo the VM instance
|
||||
* @param opaque host id
|
||||
* @param vmDao VM dao
|
||||
* @return
|
||||
*/
|
||||
public boolean preStateTransitionEvent(S oldState, E event, S newState, V vo, boolean status, Object opaque);
|
||||
|
||||
/**
|
||||
* 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, Object opaque);
|
||||
* Event is triggered after state machine transition finished
|
||||
* @param transition The Transition fo the Event
|
||||
* @param vo the VM instance
|
||||
* @param status the state transition is allowed or not
|
||||
* @return
|
||||
*/
|
||||
public boolean postStateTransitionEvent(StateMachine2.Transition<S, E> transition, V vo, boolean status, Object opaque);
|
||||
}
|
||||
|
||||
@ -46,25 +46,33 @@ public class StateMachine2<S, E, V extends StateObject<S>> {
|
||||
}
|
||||
|
||||
public void addTransition(S currentState, E event, S toState) {
|
||||
StateEntry entry = null;
|
||||
if (currentState == null) {
|
||||
entry = _initialStateEntry;
|
||||
} else {
|
||||
entry = _states.get(currentState);
|
||||
if (entry == null) {
|
||||
entry = new StateEntry(currentState);
|
||||
_states.put(currentState, entry);
|
||||
}
|
||||
}
|
||||
addTransition(new Transition<S, E>(currentState, event, toState, null));
|
||||
}
|
||||
|
||||
entry.addTransition(event, toState);
|
||||
|
||||
entry = _states.get(toState);
|
||||
public void addTransition(Transition<S, E> transition) {
|
||||
S currentState = transition.getCurrentState();
|
||||
E event = transition.getEvent();
|
||||
S toState = transition.getToState();
|
||||
StateEntry entry = null;
|
||||
if (currentState == null) {
|
||||
entry = _initialStateEntry;
|
||||
} else {
|
||||
entry = _states.get(currentState);
|
||||
if (entry == null) {
|
||||
entry = new StateEntry(toState);
|
||||
_states.put(toState, entry);
|
||||
entry = new StateEntry(currentState);
|
||||
_states.put(currentState, entry);
|
||||
}
|
||||
entry.addFromTransition(event, currentState);
|
||||
}
|
||||
|
||||
entry.addTransition(event, toState, transition);
|
||||
|
||||
entry = _states.get(toState);
|
||||
if (entry == null) {
|
||||
entry = new StateEntry(toState);
|
||||
_states.put(toState, entry);
|
||||
}
|
||||
entry.addFromTransition(event, currentState);
|
||||
}
|
||||
|
||||
public Set<E> getPossibleEvents(S s) {
|
||||
@ -73,19 +81,23 @@ public class StateMachine2<S, E, V extends StateObject<S>> {
|
||||
}
|
||||
|
||||
public S getNextState(S s, E e) throws NoTransitionException {
|
||||
StateEntry entry = null;
|
||||
if (s == null) {
|
||||
entry = _initialStateEntry;
|
||||
} else {
|
||||
entry = _states.get(s);
|
||||
assert entry != null : "Cannot retrieve transitions for state " + s;
|
||||
}
|
||||
return getTransition(s, e).getToState();
|
||||
}
|
||||
|
||||
S ns = entry.nextStates.get(e);
|
||||
if (ns == null) {
|
||||
throw new NoTransitionException("Unable to transition to a new state from " + s + " via " + e);
|
||||
}
|
||||
return ns;
|
||||
public Transition<S, E> getTransition(S s, E e) throws NoTransitionException {
|
||||
StateEntry entry = null;
|
||||
if (s == null) {
|
||||
entry = _initialStateEntry;
|
||||
} else {
|
||||
entry = _states.get(s);
|
||||
assert entry != null : "Cannot retrieve transitions for state " + s;
|
||||
}
|
||||
|
||||
Transition<S, E> transition = entry.nextStates.get(e);
|
||||
if (transition == null) {
|
||||
throw new NoTransitionException("Unable to transition to a new state from " + s + " via " + e);
|
||||
}
|
||||
return transition;
|
||||
}
|
||||
|
||||
public List<S> getFromStates(S s, E e) {
|
||||
@ -100,6 +112,7 @@ public class StateMachine2<S, E, V extends StateObject<S>> {
|
||||
public boolean transitTo(V vo, E e, Object opaque, StateDao<S, E, V> dao) throws NoTransitionException {
|
||||
S currentState = vo.getState();
|
||||
S nextState = getNextState(currentState, e);
|
||||
Transition<S, E> transition = getTransition(currentState, e);
|
||||
|
||||
boolean transitionStatus = true;
|
||||
if (nextState == null) {
|
||||
@ -116,7 +129,7 @@ public class StateMachine2<S, E, V extends StateObject<S>> {
|
||||
}
|
||||
|
||||
for (StateListener<S, E, V> listener : _listeners) {
|
||||
listener.postStateTransitionEvent(currentState, e, nextState, vo, transitionStatus, opaque);
|
||||
listener.postStateTransitionEvent(transition, vo, transitionStatus, opaque);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -138,21 +151,84 @@ public class StateMachine2<S, E, V extends StateObject<S>> {
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
public static class Transition<S, E> {
|
||||
|
||||
private S currentState;
|
||||
|
||||
private E event;
|
||||
|
||||
private S toState;
|
||||
|
||||
private List<Impact> impacts;
|
||||
|
||||
public static enum Impact {
|
||||
USAGE
|
||||
}
|
||||
|
||||
public Transition(S currentState, E event, S toState, List<Impact> impacts) {
|
||||
this.currentState = currentState;
|
||||
this.event = event;
|
||||
this.toState = toState;
|
||||
this.impacts = impacts;
|
||||
}
|
||||
|
||||
public S getCurrentState() {
|
||||
return currentState;
|
||||
}
|
||||
|
||||
public E getEvent() {
|
||||
return event;
|
||||
}
|
||||
|
||||
public S getToState() {
|
||||
return toState;
|
||||
}
|
||||
|
||||
public boolean isImpacted(Impact impact) {
|
||||
if (impacts == null || impacts.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
return impacts.contains(impact);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
Transition that = (Transition) o;
|
||||
|
||||
if (currentState != null ? !currentState.equals(that.currentState) : that.currentState != null) return false;
|
||||
if (event != null ? !event.equals(that.event) : that.event != null) return false;
|
||||
if (toState != null ? !toState.equals(that.toState) : that.toState != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = currentState != null ? currentState.hashCode() : 0;
|
||||
result = 31 * result + (event != null ? event.hashCode() : 0);
|
||||
result = 31 * result + (toState != null ? toState.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private class StateEntry {
|
||||
public S state;
|
||||
public HashMap<E, S> nextStates;
|
||||
public HashMap<E, Transition<S, E>> nextStates;
|
||||
public HashMap<E, List<S>> prevStates;
|
||||
|
||||
public StateEntry(S state) {
|
||||
this.state = state;
|
||||
nextStates = new HashMap<E, S>();
|
||||
prevStates = new HashMap<E, List<S>>();
|
||||
nextStates = new HashMap<E, Transition<S, E>>();
|
||||
}
|
||||
|
||||
public void addTransition(E e, S s) {
|
||||
public void addTransition(E e, S s, Transition<S, E> transition) {
|
||||
assert !nextStates.containsKey(e) : "State " + getStateStr() + " already contains a transition to state " + nextStates.get(e).toString() + " via event " +
|
||||
e.toString() + ". Please revisit the rule you're adding to state " + s.toString();
|
||||
nextStates.put(e, s);
|
||||
nextStates.put(e, transition);
|
||||
}
|
||||
|
||||
public void addFromTransition(E e, S s) {
|
||||
@ -172,7 +248,7 @@ public class StateMachine2<S, E, V extends StateObject<S>> {
|
||||
|
||||
public void buildString(StringBuilder str) {
|
||||
str.append("State: ").append(getStateStr()).append("\n");
|
||||
for (Map.Entry<E, S> nextState : nextStates.entrySet()) {
|
||||
for (Map.Entry<E, Transition<S, E>> nextState : nextStates.entrySet()) {
|
||||
str.append(" --> Event: ");
|
||||
Formatter format = new Formatter();
|
||||
str.append(format.format("%-30s", nextState.getKey().toString()));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user