package org.zstack.compute.vm; import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.db.Q; import org.zstack.core.gc.EventBasedGarbageCollector; import org.zstack.core.gc.GC; import org.zstack.core.gc.GCCompletion; import org.zstack.header.host.*; import org.zstack.header.message.MessageReply; import org.zstack.header.vm.*; import static org.zstack.core.Platform.operr; /** * Created by xing5 on 2017/3/3. */ public class DeleteVmGC extends EventBasedGarbageCollector { @GC public String hostUuid; @GC public VmInstanceInventory inventory; @Override protected void setup() { onEvent(HostCanonicalEvents.HOST_DELETED_PATH, (tokens, data) -> { HostCanonicalEvents.HostDeletedData d = (HostCanonicalEvents.HostDeletedData) data; return hostUuid.equals(d.getHostUuid()); }); onEvent(HostCanonicalEvents.HOST_STATUS_CHANGED_PATH, (tokens, data) -> { HostCanonicalEvents.HostStatusChangedData d = (HostCanonicalEvents.HostStatusChangedData) data; return d.getHostUuid().equals(hostUuid) && d.getNewStatus().equals(HostStatus.Connected.toString()); }); } @Override protected void triggerNow(GCCompletion completion) { HostStatus status = Q.New(HostVO.class).select(HostVO_.status) .eq(HostVO_.uuid, hostUuid).findValue(); if (status == null) { // the host has been deleted completion.cancel(); return; } if (status != HostStatus.Connected) { completion.fail(operr("the host[uuid:%s] is not connected", hostUuid)); return; } VmInstanceState vmstate = Q.New(VmInstanceVO.class).select(VmInstanceVO_.state) .eq(VmInstanceVO_.uuid, inventory.getUuid()).findValue(); if (vmstate != null && vmstate != VmInstanceState.Destroyed) { // the vm has been recovered completion.cancel(); return; } VmDirectlyDestroyOnHypervisorMsg msg = new VmDirectlyDestroyOnHypervisorMsg(); msg.setHostUuid(hostUuid); msg.setVmUuid(inventory.getUuid()); bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, hostUuid); bus.send(msg, new CloudBusCallBack(completion) { @Override public void run(MessageReply reply) { if (reply.isSuccess()) { completion.success(); } else { completion.fail(reply.getError()); } } }); } }