package org.ovirt.engine.core.bll.storage.disk.cinder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import javax.inject.Inject;
import org.ovirt.engine.core.bll.ConcurrentChildCommandsExecutionCallback;
import org.ovirt.engine.core.bll.InternalCommandAttribute;
import org.ovirt.engine.core.bll.NonTransactiveCommandAttribute;
import org.ovirt.engine.core.bll.VmCommand;
import org.ovirt.engine.core.bll.context.CommandContext;
import org.ovirt.engine.core.bll.storage.disk.image.DisksFilter;
import org.ovirt.engine.core.bll.tasks.CommandCoordinatorUtil;
import org.ovirt.engine.core.bll.tasks.interfaces.CommandCallback;
import org.ovirt.engine.core.common.action.RemoveAllVmCinderDisksParameters;
import org.ovirt.engine.core.common.action.RemoveCinderDiskParameters;
import org.ovirt.engine.core.common.action.VdcActionParametersBase.EndProcedure;
import org.ovirt.engine.core.common.action.VdcActionType;
import org.ovirt.engine.core.common.action.VdcReturnValueBase;
import org.ovirt.engine.core.common.businessentities.storage.CinderDisk;
import org.ovirt.engine.core.common.businessentities.storage.DiskImage;
import org.ovirt.engine.core.dao.DiskDao;
@InternalCommandAttribute
@NonTransactiveCommandAttribute
public class RemoveAllVmCinderDisksCommand<T extends RemoveAllVmCinderDisksParameters> extends VmCommand<T> {
@Inject
private DiskDao diskDao;
public RemoveAllVmCinderDisksCommand(T parameters, CommandContext cmdContext) {
super(parameters, cmdContext);
}
@Override
protected void executeVmCommand() {
Collection<CinderDisk> failedRemoving = new LinkedList<>();
for (final CinderDisk cinderDisk : getCinderDisksToBeRemoved()) {
if (Boolean.TRUE.equals(cinderDisk.getActive())) {
VdcReturnValueBase vdcReturnValue = removeCinderDisk(cinderDisk);
if (vdcReturnValue == null || !vdcReturnValue.getSucceeded()) {
failedRemoving.add(cinderDisk);
logRemoveCinderDiskError(cinderDisk, vdcReturnValue);
}
}
}
setActionReturnValue(failedRemoving);
persistCommand(getParameters().getParentCommand(), true);
setSucceeded(true);
}
private void logRemoveCinderDiskError(CinderDisk cinderDisk, VdcReturnValueBase vdcReturnValue) {
log.error("Can't remove cinder disk id '{}' for VM id '{}' from domain id '{}' due to: {}.",
cinderDisk.getImageId(),
getParameters().getVmId(),
cinderDisk.getStorageIds().get(0),
vdcReturnValue != null ? vdcReturnValue.getFault().getMessage() : "");
}
private VdcReturnValueBase removeCinderDisk(CinderDisk cinderDisk) {
Future<VdcReturnValueBase> future = CommandCoordinatorUtil.executeAsyncCommand(
VdcActionType.RemoveCinderDisk,
buildChildCommandParameters(cinderDisk),
cloneContextAndDetachFromParent());
try {
return future.get();
} catch (InterruptedException | ExecutionException e) {
log.error("Error removing Cinder disk", e);
}
return null;
}
private RemoveCinderDiskParameters buildChildCommandParameters(CinderDisk cinderDisk) {
RemoveCinderDiskParameters removeDiskParams = new RemoveCinderDiskParameters(cinderDisk.getId());
removeDiskParams.setParentCommand(getActionType());
removeDiskParams.setParentParameters(getParameters());
removeDiskParams.setShouldBeLogged(false);
removeDiskParams.setEndProcedure(EndProcedure.COMMAND_MANAGED);
return removeDiskParams;
}
private List<CinderDisk> getCinderDisksToBeRemoved() {
List<CinderDisk> imageDisks = getParameters().cinderDisks;
List<CinderDisk> cinderDisks = new ArrayList<>();
if (imageDisks == null) {
cinderDisks = DisksFilter.filterCinderDisks(diskDao.getAllForVm(getVmId()));
} else {
for (DiskImage diskImage : imageDisks) {
cinderDisks.add((CinderDisk) diskImage);
}
}
return cinderDisks;
}
@Override
protected void endSuccessfully() {
// handled by parent command
setSucceeded(true);
}
@Override
protected void endWithFailure() {
// handled by parent command
setSucceeded(true);
}
@Override
public CommandCallback getCallback() {
return new ConcurrentChildCommandsExecutionCallback();
}
}