package org.ovirt.engine.core.bll.storage.disk.image;
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.NonTransactiveCommandAttribute;
import org.ovirt.engine.core.bll.context.CommandContext;
import org.ovirt.engine.core.bll.storage.EntityPollingCommand;
import org.ovirt.engine.core.bll.storage.StorageJobCommand;
import org.ovirt.engine.core.bll.storage.utils.VdsCommandsHelper;
import org.ovirt.engine.core.common.VdcObjectType;
import org.ovirt.engine.core.common.action.CopyDataCommandParameters;
import org.ovirt.engine.core.common.action.FenceVolumeJobCommandParameters;
import org.ovirt.engine.core.common.action.VdcActionParametersBase.EndProcedure;
import org.ovirt.engine.core.common.action.VdcActionType;
import org.ovirt.engine.core.common.businessentities.HostJobInfo.HostJobStatus;
import org.ovirt.engine.core.common.businessentities.VdsmImageLocationInfo;
import org.ovirt.engine.core.common.businessentities.storage.DiskImage;
import org.ovirt.engine.core.common.job.StepEnum;
import org.ovirt.engine.core.common.job.StepSubjectEntity;
import org.ovirt.engine.core.common.vdscommands.CopyVolumeDataVDSCommandParameters;
import org.ovirt.engine.core.common.vdscommands.VDSCommandType;
@NonTransactiveCommandAttribute
@InternalCommandAttribute
public class CopyDataCommand<T extends CopyDataCommandParameters> extends
StorageJobCommand<T> implements EntityPollingCommand {
@Inject
private VdsmImagePoller poller;
public CopyDataCommand(T parameters, CommandContext cmdContext) {
super(parameters, cmdContext);
}
@Override
protected void executeCommand() {
completeGenerationInfo();
VdsCommandsHelper.runVdsCommandWithFailover(VDSCommandType.CopyVolumeData,
new CopyVolumeDataVDSCommandParameters(getParameters().getStorageJobId(),
getParameters().getSrcInfo(),
getParameters().getDstInfo(),
getParameters().isCollapse()),
getParameters().getStoragePoolId(), this);
setSucceeded(true);
}
private void completeGenerationInfo() {
if (!isDstVdsmImage()) {
return;
}
VdsmImageLocationInfo info = (VdsmImageLocationInfo) getParameters().getDstInfo();
DiskImage image = ImagesHandler.getVolumeInfoFromVdsm(getParameters().getStoragePoolId(),
info.getStorageDomainId(), info.getImageGroupId(), info.getImageId());
info.setGeneration(image.getImage().getGeneration());
persistCommandIfNeeded();
}
@Override
public StepEnum getCommandStep() {
return StepEnum.COPY_VOLUME;
}
@Override
public boolean shouldUpdateStepProgress() {
return true;
}
@Override
public List<StepSubjectEntity> getCommandStepSubjectEntities() {
if (getParameters().getJobWeight() != null && getParameters().getDstInfo() instanceof VdsmImageLocationInfo) {
return Collections.singletonList(new StepSubjectEntity(VdcObjectType.Disk,
((VdsmImageLocationInfo) getParameters().getDstInfo()).getImageGroupId(),
getParameters().getJobWeight()));
}
return super.getCommandStepSubjectEntities();
}
@Override
public void attemptToFenceJob() {
if (isDstVdsmImage()) {
log.info("Command {} id: '{}': attempting to fence job {}",
getActionType(),
getCommandId(),
getJobId());
VdsmImageLocationInfo info = (VdsmImageLocationInfo) getParameters().getDstInfo();
FenceVolumeJobCommandParameters p = new FenceVolumeJobCommandParameters(info);
p.setParentCommand(getActionType());
p.setParentParameters(getParameters());
p.setStoragePoolId(getParameters().getStoragePoolId());
p.setEndProcedure(EndProcedure.COMMAND_MANAGED);
runInternalActionWithTasksContext(VdcActionType.FenceVolumeJob, p);
}
}
private boolean isDstVdsmImage() {
return getParameters().getDstInfo() instanceof VdsmImageLocationInfo;
}
@Override
public HostJobStatus poll() {
if (isDstVdsmImage()) {
VdsmImageLocationInfo info = (VdsmImageLocationInfo) getParameters().getDstInfo();
return poller.pollImage(getParameters().getStoragePoolId(), info.getStorageDomainId(),
info.getImageGroupId(), info.getImageId(), info.getGeneration(), getCommandId(), getActionType());
}
return null;
}
}