package org.zstack.compute.vm;
import org.springframework.beans.factory.annotation.Autowired;
import org.zstack.core.componentloader.PluginRegistry;
import org.zstack.core.errorcode.ErrorFacade;
import org.zstack.header.Component;
import org.zstack.header.errorcode.ErrorCode;
import org.zstack.header.vm.*;
import org.zstack.header.volume.VolumeInventory;
import org.zstack.utils.CollectionUtils;
import org.zstack.utils.Utils;
import org.zstack.utils.function.ForEachFunction;
import org.zstack.utils.logging.CLogger;
import static org.zstack.core.Platform.operr;
import java.util.List;
public class VmInstanceExtensionPointEmitter implements Component {
private static final CLogger logger = Utils.getLogger(VmInstanceExtensionPointEmitter.class);
@Autowired
private PluginRegistry pluginRgty;
@Autowired
private ErrorFacade errf;
private List<VmInstanceStartNewCreatedVmExtensionPoint> startNewCreatedVmExtensions;
private List<VmInstanceStopExtensionPoint> stopVmExtensions;
private List<VmInstanceRebootExtensionPoint> rebootVmExtensions;
private List<VmInstanceDestroyExtensionPoint> destroyVmExtensions;
private List<VmInstanceStartExtensionPoint> startVmExtensions;
private List<VmInstanceMigrateExtensionPoint> migrateVmExtensions;
private List<VmAttachVolumeExtensionPoint> attachVolumeExtensions;
private List<VmDetachVolumeExtensionPoint> detachVolumeExtensions;
public ErrorCode preStartNewCreatedVm(VmInstanceInventory inv) {
for (VmInstanceStartNewCreatedVmExtensionPoint ext : startNewCreatedVmExtensions) {
try {
String err = ext.preStartNewCreatedVm(inv);
if (err != null) {
return operr("VmInstanceStartNewCreatedVmExtensionPoint[%s] refuses to create vm[uuid:%s] because %s",
ext.getClass().getName(), inv.getUuid(), err);
}
} catch (Exception e) {
logger.warn(String.format("Unhandled exception while calling %s", ext.getClass().getName()), e);
}
}
return null;
}
public void beforeStartNewCreatedVm(final VmInstanceInventory inv) {
CollectionUtils.safeForEach(startNewCreatedVmExtensions, new ForEachFunction<VmInstanceStartNewCreatedVmExtensionPoint>() {
@Override
public void run(VmInstanceStartNewCreatedVmExtensionPoint arg) {
arg.beforeStartNewCreatedVm(inv);
}
});
}
public void afterStartNewCreatedVm(final VmInstanceInventory inv) {
CollectionUtils.forEach(startNewCreatedVmExtensions, new ForEachFunction<VmInstanceStartNewCreatedVmExtensionPoint>() {
@Override
public void run(VmInstanceStartNewCreatedVmExtensionPoint arg) {
arg.afterStartNewCreatedVm(inv);
}
});
}
public void failedToStartNewCreatedVm(final VmInstanceInventory inv, final ErrorCode reason) {
CollectionUtils.forEach(startNewCreatedVmExtensions, new ForEachFunction<VmInstanceStartNewCreatedVmExtensionPoint>() {
@Override
public void run(VmInstanceStartNewCreatedVmExtensionPoint arg) {
arg.failedToStartNewCreatedVm(inv, reason);
}
});
}
public ErrorCode preStopVm(VmInstanceInventory inv) {
for (VmInstanceStopExtensionPoint ext : stopVmExtensions) {
try {
String err = ext.preStopVm(inv);
if (err != null) {
return operr("VmInstanceStopVmExtensionPoint[%s] refuses to stop vm[uuid:%s] because %s",
ext.getClass().getName(), inv.getUuid(), err);
}
} catch (Exception e) {
logger.warn(String.format("Unhandled exception while calling %s", ext.getClass().getName()), e);
}
}
return null;
}
public void beforeStopVm(final VmInstanceInventory inv) {
CollectionUtils.forEach(stopVmExtensions, new ForEachFunction<VmInstanceStopExtensionPoint>() {
@Override
public void run(VmInstanceStopExtensionPoint arg) {
arg.beforeStopVm(inv);
}
});
}
public void afterStopVm(final VmInstanceInventory inv) {
CollectionUtils.forEach(stopVmExtensions, new ForEachFunction<VmInstanceStopExtensionPoint>() {
@Override
public void run(VmInstanceStopExtensionPoint arg) {
arg.afterStopVm(inv);
}
});
}
public void failedToStopVm(final VmInstanceInventory inv, final ErrorCode reason) {
CollectionUtils.forEach(stopVmExtensions, new ForEachFunction<VmInstanceStopExtensionPoint>() {
@Override
public void run(VmInstanceStopExtensionPoint arg) {
arg.failedToStopVm(inv, reason);
}
});
}
public ErrorCode preRebootVm(final VmInstanceInventory inv) {
for (VmInstanceRebootExtensionPoint ext : rebootVmExtensions) {
try {
String err = ext.preRebootVm(inv);
if (err != null) {
return operr("VmInstanceRebootExtensionPoint[%s] refuses to reboot vm[uuid:%s] because %s", ext.getClass().getName(),
inv.getUuid(), err);
}
} catch (Exception e) {
logger.warn(String.format("Unhandled exception while calling %s", ext.getClass().getName()), e);
}
}
return null;
}
public void beforeRebootVm(final VmInstanceInventory inv) {
CollectionUtils.safeForEach(rebootVmExtensions, new ForEachFunction<VmInstanceRebootExtensionPoint>() {
@Override
public void run(VmInstanceRebootExtensionPoint arg) {
arg.beforeRebootVm(inv);
}
});
}
public void afterRebootVm(final VmInstanceInventory inv) {
CollectionUtils.safeForEach(rebootVmExtensions, new ForEachFunction<VmInstanceRebootExtensionPoint>() {
@Override
public void run(VmInstanceRebootExtensionPoint arg) {
arg.afterRebootVm(inv);
}
});
}
public void failedToRebootVm(final VmInstanceInventory inv, final ErrorCode reason) {
CollectionUtils.safeForEach(rebootVmExtensions, new ForEachFunction<VmInstanceRebootExtensionPoint>() {
@Override
public void run(VmInstanceRebootExtensionPoint arg) {
arg.failedToRebootVm(inv, reason);
}
});
}
public ErrorCode preDestroyVm(VmInstanceInventory inv) {
for (VmInstanceDestroyExtensionPoint ext : destroyVmExtensions) {
try {
String err = ext.preDestroyVm(inv);
if (err != null) {
return operr("VmInstanceDestroyVmExtensionPoint[%s] refuses to destroy vm[uuid:%s] because %s", ext.getClass().getName(), inv.getUuid(), err);
}
} catch (Exception e) {
logger.warn(String.format("Unhandled exception while calling %s", ext.getClass().getName()), e);
}
}
return null;
}
public void beforeDestroyVm(final VmInstanceInventory inv) {
CollectionUtils.safeForEach(destroyVmExtensions, new ForEachFunction<VmInstanceDestroyExtensionPoint>() {
@Override
public void run(VmInstanceDestroyExtensionPoint arg) {
arg.beforeDestroyVm(inv);
}
});
}
public void afterDestroyVm(final VmInstanceInventory inv) {
CollectionUtils.safeForEach(destroyVmExtensions, new ForEachFunction<VmInstanceDestroyExtensionPoint>() {
@Override
public void run(VmInstanceDestroyExtensionPoint arg) {
arg.afterDestroyVm(inv);
}
});
}
public void failedToDestroyVm(final VmInstanceInventory inv, final ErrorCode reason) {
CollectionUtils.safeForEach(destroyVmExtensions, new ForEachFunction<VmInstanceDestroyExtensionPoint>() {
@Override
public void run(VmInstanceDestroyExtensionPoint arg) {
arg.failedToDestroyVm(inv, reason);
}
});
}
public ErrorCode preStartVm(VmInstanceInventory inv) {
for (VmInstanceStartExtensionPoint ext : startVmExtensions) {
try {
String err = ext.preStartVm(inv);
if (err != null) {
return operr("VmInstanceStartExtensionPoint[%s] refuses to start vm[uuid:%s] because %s", ext.getClass().getName(),
inv.getUuid(), err);
}
} catch (Exception e) {
logger.warn(String.format("Unhandled exception while calling %s", ext.getClass().getName()), e);
}
}
return null;
}
public void beforeStartVm(final VmInstanceInventory inv) {
CollectionUtils.safeForEach(startVmExtensions, new ForEachFunction<VmInstanceStartExtensionPoint>() {
@Override
public void run(VmInstanceStartExtensionPoint arg) {
arg.beforeStartVm(inv);
}
});
}
public void afterStartVm(final VmInstanceInventory inv) {
CollectionUtils.safeForEach(startVmExtensions, new ForEachFunction<VmInstanceStartExtensionPoint>() {
@Override
public void run(VmInstanceStartExtensionPoint arg) {
arg.afterStartVm(inv);
}
});
}
public void failedToStartVm(final VmInstanceInventory inv, final ErrorCode reason) {
CollectionUtils.safeForEach(startVmExtensions, new ForEachFunction<VmInstanceStartExtensionPoint>() {
@Override
public void run(VmInstanceStartExtensionPoint arg) {
arg.failedToStartVm(inv, reason);
}
});
}
public void afterMigrateVm(final VmInstanceInventory inv, final String srcHostUuid) {
CollectionUtils.safeForEach(migrateVmExtensions, new ForEachFunction<VmInstanceMigrateExtensionPoint>() {
@Override
public void run(VmInstanceMigrateExtensionPoint arg) {
arg.afterMigrateVm(inv, srcHostUuid);
}
});
}
public void failedToMigrateVm(final VmInstanceInventory inv, final String dstHostUuid, final ErrorCode reason) {
CollectionUtils.safeForEach(migrateVmExtensions, new ForEachFunction<VmInstanceMigrateExtensionPoint>() {
@Override
public void run(final VmInstanceMigrateExtensionPoint arg) {
arg.failedToMigrateVm(inv, dstHostUuid, reason);
}
});
}
public void preAttachVolume(VmInstanceInventory vm, VolumeInventory volume) {
for (VmAttachVolumeExtensionPoint ext : attachVolumeExtensions) {
ext.preAttachVolume(vm, volume);
}
}
public void beforeAttachVolume(final VmInstanceInventory vm, final VolumeInventory volume) {
CollectionUtils.safeForEach(attachVolumeExtensions, new ForEachFunction<VmAttachVolumeExtensionPoint>() {
@Override
public void run(VmAttachVolumeExtensionPoint arg) {
arg.beforeAttachVolume(vm, volume);
}
});
}
public void afterAttachVolume(final VmInstanceInventory vm, final VolumeInventory volume) {
CollectionUtils.safeForEach(attachVolumeExtensions, new ForEachFunction<VmAttachVolumeExtensionPoint>() {
@Override
public void run(VmAttachVolumeExtensionPoint arg) {
arg.afterAttachVolume(vm, volume);
}
});
}
public void failedToAttachVolume(final VmInstanceInventory vm, final VolumeInventory volume, final ErrorCode errorCode) {
CollectionUtils.safeForEach(attachVolumeExtensions, new ForEachFunction<VmAttachVolumeExtensionPoint>() {
@Override
public void run(VmAttachVolumeExtensionPoint arg) {
arg.failedToAttachVolume(vm, volume, errorCode);
}
});
}
public void preDetachVolume(final VmInstanceInventory vm, final VolumeInventory volume) {
for (VmDetachVolumeExtensionPoint ext : detachVolumeExtensions) {
ext.preDetachVolume(vm, volume);
}
}
public void beforeDetachVolume(final VmInstanceInventory vm, final VolumeInventory volume) {
CollectionUtils.safeForEach(detachVolumeExtensions, new ForEachFunction<VmDetachVolumeExtensionPoint>() {
@Override
public void run(VmDetachVolumeExtensionPoint arg) {
arg.beforeDetachVolume(vm, volume);
}
});
}
public void afterDetachVolume(final VmInstanceInventory vm, final VolumeInventory volume) {
CollectionUtils.safeForEach(detachVolumeExtensions, new ForEachFunction<VmDetachVolumeExtensionPoint>() {
@Override
public void run(VmDetachVolumeExtensionPoint arg) {
arg.afterDetachVolume(vm, volume);
}
});
}
public void failedToDetachVolume(final VmInstanceInventory vm, final VolumeInventory volume, final ErrorCode errorCode) {
CollectionUtils.safeForEach(detachVolumeExtensions, new ForEachFunction<VmDetachVolumeExtensionPoint>() {
@Override
public void run(VmDetachVolumeExtensionPoint arg) {
arg.failedToDetachVolume(vm, volume, errorCode);
}
});
}
private void populateExtensions() {
startNewCreatedVmExtensions = pluginRgty.getExtensionList(VmInstanceStartNewCreatedVmExtensionPoint.class);
stopVmExtensions = pluginRgty.getExtensionList(VmInstanceStopExtensionPoint.class);
rebootVmExtensions = pluginRgty.getExtensionList(VmInstanceRebootExtensionPoint.class);
destroyVmExtensions = pluginRgty.getExtensionList(VmInstanceDestroyExtensionPoint.class);
startVmExtensions = pluginRgty.getExtensionList(VmInstanceStartExtensionPoint.class);
migrateVmExtensions = pluginRgty.getExtensionList(VmInstanceMigrateExtensionPoint.class);
attachVolumeExtensions = pluginRgty.getExtensionList(VmAttachVolumeExtensionPoint.class);
detachVolumeExtensions = pluginRgty.getExtensionList(VmDetachVolumeExtensionPoint.class);
}
@Override
public boolean start() {
populateExtensions();
return true;
}
@Override
public boolean stop() {
return true;
}
}