package org.zstack.compute.vm;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.zstack.core.cloudbus.CloudBus;
import org.zstack.core.cloudbus.CloudBusCallBack;
import org.zstack.core.db.DatabaseFacade;
import org.zstack.header.core.workflow.FlowTrigger;
import org.zstack.header.core.workflow.NoRollbackFlow;
import org.zstack.header.host.HostConstant;
import org.zstack.header.host.HostErrors;
import org.zstack.header.message.MessageReply;
import org.zstack.header.vm.DestroyVmOnHypervisorMsg;
import org.zstack.header.vm.VmInstanceConstant;
import org.zstack.header.vm.VmInstanceSpec;
import org.zstack.header.vm.VmInstanceState;
import org.zstack.utils.Utils;
import org.zstack.utils.logging.CLogger;
import java.util.Map;
@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE)
public class VmDestroyOnHypervisorFlow extends NoRollbackFlow {
private static final CLogger logger = Utils.getLogger(VmDestroyOnHypervisorFlow.class);
@Autowired
protected DatabaseFacade dbf;
@Autowired
protected CloudBus bus;
@Override
public void run(final FlowTrigger chain, Map data) {
final VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString());
final String hostUuid = spec.getVmInventory().getHostUuid() == null ? spec.getVmInventory().getLastHostUuid() : spec.getVmInventory().getHostUuid();
if (spec.getVmInventory().getClusterUuid() == null || hostUuid == null) {
// the vm failed to start because no host available at that time
// no need to send DestroyVmOnHypervisorMsg
chain.next();
return;
}
if (VmInstanceState.Stopped.toString().equals(spec.getVmInventory().getState())) {
chain.next();
return;
}
DestroyVmOnHypervisorMsg msg = new DestroyVmOnHypervisorMsg();
msg.setVmInventory(spec.getVmInventory());
bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, hostUuid);
bus.send(msg, new CloudBusCallBack(chain) {
@Override
public void run(MessageReply reply) {
if (reply.isSuccess()) {
chain.next();
return;
}
if (!reply.getError().isError(HostErrors.OPERATION_FAILURE_GC_ELIGIBLE)) {
chain.fail(reply.getError());
return;
}
DeleteVmGC gc = new DeleteVmGC();
gc.NAME = String.format("gc-vm-%s-on-host-%s", spec.getVmInventory().getUuid(), hostUuid);
gc.hostUuid = hostUuid;
gc.inventory = spec.getVmInventory();
gc.submit();
chain.next();
}
});
}
}