package org.ovirt.engine.core.bll.storage.disk.cinder;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import javax.inject.Inject;
import org.ovirt.engine.core.bll.InternalCommandAttribute;
import org.ovirt.engine.core.bll.context.CommandContext;
import org.ovirt.engine.core.bll.storage.disk.image.BaseImagesCommand;
import org.ovirt.engine.core.bll.tasks.interfaces.CommandCallback;
import org.ovirt.engine.core.common.VdcObjectType;
import org.ovirt.engine.core.common.action.ImagesContainterParametersBase;
import org.ovirt.engine.core.common.businessentities.SubjectEntity;
import org.ovirt.engine.core.common.businessentities.storage.DiskImage;
import org.ovirt.engine.core.common.businessentities.storage.ImageStatus;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.dao.DiskImageDao;
import org.ovirt.engine.core.dao.ImageDao;
import org.ovirt.engine.core.di.Injector;
import org.ovirt.engine.core.utils.transaction.NoOpTransactionCompletionListener;
import org.ovirt.engine.core.utils.transaction.TransactionSupport;
@InternalCommandAttribute
public class RemoveCinderSnapshotDiskCommand<T extends ImagesContainterParametersBase> extends BaseImagesCommand<T> {
@Inject
private ImageDao imageDao;
@Inject
private DiskImageDao diskImageDao;
public RemoveCinderSnapshotDiskCommand(T parameters, CommandContext cmdContext) {
super(parameters, cmdContext);
}
@Override
protected void executeCommand() {
registerRollbackHandler(new CustomTransactionCompletionListener());
deleteSnapshot();
persistCommand(getParameters().getParentCommand(), true);
getReturnValue().setActionReturnValue(getImageId());
setSucceeded(true);
}
private void deleteSnapshot() {
getCinderBroker().deleteSnapshot(getImageId());
}
@Override
public Guid getStorageDomainId() {
return getDiskImage().getStorageIds().get(0);
}
@Override
protected void endSuccessfully() {
if (getDestinationDiskImage() != null) {
DiskImage curr = getDestinationDiskImage();
// Set the parent snapshot to be dependent on the current snapshot descendant id.
List<DiskImage> orderedCinderSnapshots = diskImageDao.getAllSnapshotsForParent(curr.getImageId());
if (!orderedCinderSnapshots.isEmpty()) {
DiskImage volumeBasedOnsnapshot = orderedCinderSnapshots.get(0);
volumeBasedOnsnapshot.setParentId(curr.getParentId());
imageDao.update(volumeBasedOnsnapshot.getImage());
}
imageDao.remove(curr.getImageId());
}
setSucceeded(true);
}
@Override
public CommandCallback getCallback() {
return Injector.injectMembers(new RemoveCinderSnapshotCommandCallback());
}
private class CustomTransactionCompletionListener extends NoOpTransactionCompletionListener {
@Override
public void onRollback() {
TransactionSupport.executeInNewTransaction(() -> {
if (!getParameters().isLeaveLocked()) {
DiskImage diskImage = getImage();
if (diskImage != null) {
imageDao.updateStatus(diskImage.getImage().getId(), ImageStatus.OK);
}
unLockImage();
}
return null;
});
}
}
@Override
protected Collection<SubjectEntity> getSubjectEntities() {
return Collections.singleton(new SubjectEntity(VdcObjectType.Storage, getStorageDomainId()));
}
}