package org.ovirt.engine.core.bll.storage.disk.image;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.inject.Inject;
import org.ovirt.engine.core.bll.CommandBase;
import org.ovirt.engine.core.bll.InternalCommandAttribute;
import org.ovirt.engine.core.bll.NonTransactiveCommandAttribute;
import org.ovirt.engine.core.bll.SerialChildCommandsExecutionCallback;
import org.ovirt.engine.core.bll.SerialChildExecutingCommand;
import org.ovirt.engine.core.bll.context.CommandContext;
import org.ovirt.engine.core.bll.tasks.interfaces.CommandCallback;
import org.ovirt.engine.core.bll.utils.CommandsWeightsUtils;
import org.ovirt.engine.core.bll.utils.PermissionSubject;
import org.ovirt.engine.core.common.action.CloneImageGroupVolumesStructureCommandParameters;
import org.ovirt.engine.core.common.action.CreateVolumeContainerCommandParameters;
import org.ovirt.engine.core.common.action.VdcActionParametersBase.EndProcedure;
import org.ovirt.engine.core.common.action.VdcActionType;
import org.ovirt.engine.core.common.businessentities.storage.DiskImage;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.dao.DiskImageDao;
import org.ovirt.engine.core.dao.ImageDao;
@InternalCommandAttribute
@NonTransactiveCommandAttribute
public class CloneImageGroupVolumesStructureCommand<T extends CloneImageGroupVolumesStructureCommandParameters> extends CommandBase<T> implements SerialChildExecutingCommand {
@Inject
private CommandsWeightsUtils commandsWeightsUtils;
@Inject
private DiskImageDao diskImageDao;
@Inject
private ImageDao imageDao;
public CloneImageGroupVolumesStructureCommand(T parameters, CommandContext cmdContext) {
super(parameters, cmdContext);
setStoragePoolId(getParameters().getStoragePoolId());
}
@Override
protected void executeCommand() {
List<DiskImage> images = diskImageDao.getAllSnapshotsForImageGroup(getParameters().getImageGroupID());
ImagesHandler.sortImageList(images);
getParameters().setImageIds(ImagesHandler.getDiskImageIds(images));
prepareWeights();
persistCommand(getParameters().getParentCommand(), getCallback() != null);
setSucceeded(true);
}
private void prepareWeights() {
if (getParameters().getJobWeight() == null) {
return;
}
Double imageWeight = 1d / getParameters().getImageIds().size();
Map<String, Double> weightDivision =
getParameters().getImageIds().stream().collect(Collectors.toMap(Guid::toString, z -> imageWeight));
getParameters()
.setOperationsJobWeight(commandsWeightsUtils.adjust(weightDivision, getParameters().getJobWeight()));
}
@Override
public List<PermissionSubject> getPermissionCheckSubjects() {
return Collections.emptyList();
}
@Override
public CommandCallback getCallback() {
return new SerialChildCommandsExecutionCallback();
}
@Override
public boolean performNextOperation(int completedChildren) {
if (completedChildren == getParameters().getImageIds().size()) {
return false;
}
Guid imageId = getParameters().getImageIds().get(completedChildren);
log.info("Starting child command {} of {}, image '{}'",
completedChildren + 1,
getParameters().getImageIds().size(),
imageId);
createImage(diskImageDao.getSnapshotById(imageId));
return true;
}
private Guid determineSourceImageGroup(DiskImage image) {
if (Guid.Empty.equals(image.getParentId())) {
return Guid.Empty;
}
return image.getImageTemplateId().equals(image.getParentId()) ?
imageDao.get(image.getImageTemplateId()).getDiskId()
: getParameters().getImageGroupID();
}
private void createImage(DiskImage image) {
CreateVolumeContainerCommandParameters parameters = new CreateVolumeContainerCommandParameters(
getParameters().getStoragePoolId(),
getParameters().getDestDomain(),
determineSourceImageGroup(image),
image.getParentId(),
getParameters().getImageGroupID(),
image.getImageId(),
image.getVolumeFormat(),
getParameters().getDescription(),
image.getSize(),
ImagesHandler.determineImageInitialSize(image.getImage(),
image.getVolumeFormat(),
getParameters().getStoragePoolId(),
getParameters().getSrcDomain(),
getParameters().getDestDomain(),
getParameters().getImageGroupID()));
parameters.setEndProcedure(EndProcedure.COMMAND_MANAGED);
parameters.setParentCommand(getActionType());
parameters.setParentParameters(getParameters());
parameters.setJobWeight(getParameters().getOperationsJobWeight().get(image.getImageId().toString()));
runInternalActionWithTasksContext(VdcActionType.CreateVolumeContainer, parameters);
}
@Override
public void handleFailure() {
}
}