package org.zstack.compute.vm; import org.springframework.beans.factory.annotation.Autowired; import org.zstack.core.componentloader.PluginExtension; import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.thread.AsyncThread; import org.zstack.header.Component; import org.zstack.header.host.HypervisorType; import org.zstack.header.vm.VmInstanceInventory; import org.zstack.header.vm.VmInstanceState; import org.zstack.header.vm.VmInstanceStateChangeNotifyPoint; import org.zstack.utils.CollectionUtils; import org.zstack.utils.Utils; import org.zstack.utils.function.ForEachFunction; import org.zstack.utils.logging.CLogger; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class VmInstanceNotifyPointEmitter implements Component { private static final CLogger logger = Utils.getLogger(VmInstanceNotifyPointEmitter.class); @Autowired private PluginRegistry pluginRgty; private Map<HypervisorType, List<VmInstanceStateChangeNotifyPoint>> stateChangePoints = new HashMap<HypervisorType, List<VmInstanceStateChangeNotifyPoint>>(); private void populateNotifyPoints() { for (VmInstanceStateChangeNotifyPoint ext : pluginRgty.getExtensionList(VmInstanceStateChangeNotifyPoint.class)) { List<VmInstanceStateChangeNotifyPoint> exts = stateChangePoints.get(ext.getSupportedHypervisorTypeForVmInstanceStateChangeNotifyPoint()); if (exts == null) { exts = new ArrayList<VmInstanceStateChangeNotifyPoint>(1); stateChangePoints.put(ext.getSupportedHypervisorTypeForVmInstanceStateChangeNotifyPoint(), exts); } exts.add(ext); } } @AsyncThread public void notifyVmStateChange(final VmInstanceInventory vm, final VmInstanceState pre, final VmInstanceState curr) { // when state changing from Created to Starting, there is no hyperviosrType yet as vm has not decided which host to go if (vm.getHypervisorType() == null) { return; } List<VmInstanceStateChangeNotifyPoint> exts = stateChangePoints.get(HypervisorType.valueOf(vm.getHypervisorType())); if (exts == null) { return; } CollectionUtils.safeForEach(exts, new ForEachFunction<VmInstanceStateChangeNotifyPoint>() { @Override public void run(VmInstanceStateChangeNotifyPoint arg) { arg.notifyVmInstanceStateChange(vm, pre, curr); } }); } @Override public boolean start() { populateNotifyPoints(); return true; } @Override public boolean stop() { return true; } }