package org.ovirt.engine.core.bll.exportimport;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
import org.ovirt.engine.core.bll.VmHandler;
import org.ovirt.engine.core.bll.VmTemplateHandler;
import org.ovirt.engine.core.bll.context.CommandContext;
import org.ovirt.engine.core.bll.storage.disk.image.ImagesHandler;
import org.ovirt.engine.core.bll.storage.domain.StorageDomainCommandBase;
import org.ovirt.engine.core.bll.utils.PermissionSubject;
import org.ovirt.engine.core.bll.validator.storage.MultipleStorageDomainsValidator;
import org.ovirt.engine.core.common.VdcObjectType;
import org.ovirt.engine.core.common.action.MoveOrCopyImageGroupParameters;
import org.ovirt.engine.core.common.action.MoveOrCopyParameters;
import org.ovirt.engine.core.common.action.VdcActionParametersBase;
import org.ovirt.engine.core.common.action.VdcActionType;
import org.ovirt.engine.core.common.action.VdcReturnValueBase;
import org.ovirt.engine.core.common.asynctasks.EntityInfo;
import org.ovirt.engine.core.common.businessentities.StorageDomain;
import org.ovirt.engine.core.common.businessentities.storage.DiskImage;
import org.ovirt.engine.core.common.businessentities.storage.ImageOperation;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.dao.StorageDomainDao;
import org.ovirt.engine.core.dao.VmStaticDao;
import org.ovirt.engine.core.utils.transaction.TransactionMethod;
import org.ovirt.engine.core.utils.transaction.TransactionSupport;
@Deprecated
public abstract class MoveOrCopyTemplateCommand<T extends MoveOrCopyParameters> extends StorageDomainCommandBase<T> {
@Inject
protected VmHandler vmHandler;
@Inject
protected VmTemplateHandler vmTemplateHandler;
@Inject
private VmStaticDao vmStaticDao;
@Inject
private StorageDomainDao storageDomainDao;
protected Map<Guid, Guid> imageToDestinationDomainMap;
protected Map<Guid, DiskImage> imageFromSourceDomainMap;
private List<PermissionSubject> permissionCheckSubject;
private List<DiskImage> templateDisks;
/**
* Constructor for command creation when compensation is applied on startup
*/
public MoveOrCopyTemplateCommand(Guid commandId) {
super(commandId);
}
public MoveOrCopyTemplateCommand(T parameters, CommandContext commandContext) {
super(parameters, commandContext);
}
@Override
public void init() {
super.init();
setVmTemplateId(getParameters().getContainerId());
getParameters().setEntityInfo(new EntityInfo(VdcObjectType.VmTemplate, getVmTemplateId()));
imageToDestinationDomainMap = getParameters().getImageToDestinationDomainMap();
imageFromSourceDomainMap = new HashMap<>();
}
protected List<DiskImage> getTemplateDisks() {
if (templateDisks == null && getVmTemplate() != null) {
vmTemplateHandler.updateDisksFromDb(getVmTemplate());
templateDisks = getVmTemplate().getDiskList();
}
return templateDisks;
}
protected void moveOrCopyAllImageGroups() {
moveOrCopyAllImageGroups(getVmTemplateId(), getTemplateDisks());
}
protected void moveOrCopyAllImageGroups(final Guid containerID, final Iterable<DiskImage> disks) {
TransactionSupport.executeInNewTransaction(new TransactionMethod<Void>() {
@Override
public Void runInTransaction() {
for (DiskImage disk : disks) {
VdcReturnValueBase vdcRetValue = runInternalActionWithTasksContext(
VdcActionType.CopyImageGroup,
buildModeOrCopyImageGroupParameters(containerID, disk));
getReturnValue().getVdsmTaskIdList().addAll(vdcRetValue.getInternalVdsmTaskIdList());
}
return null;
}
private MoveOrCopyImageGroupParameters buildModeOrCopyImageGroupParameters(
final Guid containerID, DiskImage disk) {
MoveOrCopyImageGroupParameters params = new MoveOrCopyImageGroupParameters(
containerID, disk.getId(), disk.getImageId(),
getParameters().getStorageDomainId(), ImageOperation.Copy);
params.setParentCommand(getActionType());
params.setEntityInfo(getParameters().getEntityInfo());
params.setAddImageDomainMapping(true);
params.setSourceDomainId(imageFromSourceDomainMap.get(disk.getId()).getStorageIds().get(0));
params.setParentParameters(getParameters());
return params;
}
});
}
protected void endMoveOrCopyCommand() {
endActionOnAllImageGroups();
endVmTemplateRelatedOps();
setSucceeded(true);
}
protected final void endVmTemplateRelatedOps() {
if (getVmTemplate() != null) {
getVmDeviceUtils().setVmDevices(getVmTemplate());
vmHandler.updateVmInitFromDB(getVmTemplate(), true);
incrementDbGeneration();
vmTemplateHandler.unlockVmTemplate(getVmTemplateId());
}
else {
setCommandShouldBeLogged(false);
log.warn("MoveOrCopyTemplateCommand::EndMoveOrCopyCommand: VmTemplate is null, not performing full endAction");
}
}
protected void incrementDbGeneration() {
vmStaticDao.incrementDbGeneration(getVmTemplate().getId());
}
@Override
protected void endSuccessfully() {
endMoveOrCopyCommand();
}
@Override
protected void endWithFailure() {
endMoveOrCopyCommand();
}
protected void endActionOnAllImageGroups() {
for (VdcActionParametersBase p : getParameters().getImagesParameters()) {
getBackend().endAction(VdcActionType.CopyImageGroup,
p,
getContext().clone().withoutCompensationContext().withoutExecutionContext().withoutLock());
}
}
protected StorageDomain getStorageDomain(Guid domainId) {
return storageDomainDao.getForStoragePool(domainId, getStoragePool().getId());
}
protected boolean validateSpaceRequirements(Collection<DiskImage> diskImages) {
MultipleStorageDomainsValidator sdValidator = createMultipleStorageDomainsValidator(diskImages);
if (!validate(sdValidator.allDomainsExistAndActive())
|| !validate(sdValidator.allDomainsWithinThresholds())) {
return false;
}
if (getParameters().getCopyCollapse()) {
return validate(sdValidator.allDomainsHaveSpaceForClonedDisks(diskImages));
}
return validate(sdValidator.allDomainsHaveSpaceForDisksWithSnapshots(diskImages));
}
protected MultipleStorageDomainsValidator createMultipleStorageDomainsValidator(Collection<DiskImage> diskImages) {
return new MultipleStorageDomainsValidator(getStoragePoolId(),
ImagesHandler.getAllStorageIdsForImageIds(diskImages));
}
protected void ensureDomainMap(Collection<DiskImage> images, Guid defaultDomainId) {
if (imageToDestinationDomainMap == null) {
imageToDestinationDomainMap = new HashMap<>();
}
if (imageToDestinationDomainMap.isEmpty() && images != null && defaultDomainId != null) {
for (DiskImage image : images) {
if (getParameters().isImagesExistOnTargetStorageDomain()) {
imageToDestinationDomainMap.put(image.getId(), image.getStorageIds().get(0));
} else if (!Guid.Empty.equals(defaultDomainId)) {
imageToDestinationDomainMap.put(image.getId(), defaultDomainId);
}
}
}
}
@Override
public List<PermissionSubject> getPermissionCheckSubjects() {
if (permissionCheckSubject == null) {
if (imageToDestinationDomainMap == null || imageToDestinationDomainMap.isEmpty()) {
permissionCheckSubject = super.getPermissionCheckSubjects();
} else {
permissionCheckSubject = new ArrayList<>();
Set<PermissionSubject> permissionSet = new HashSet<>();
for (Guid storageId : imageToDestinationDomainMap.values()) {
permissionSet.add(new PermissionSubject(storageId,
VdcObjectType.Storage,
getActionType().getActionGroup()));
}
permissionCheckSubject.addAll(permissionSet);
}
}
return permissionCheckSubject;
}
}