package org.ovirt.engine.core.bll;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.ovirt.engine.core.common.AuditLogType;
import org.ovirt.engine.core.common.action.AddImagesFromImportParameters;
import org.ovirt.engine.core.common.action.AddVmTemplateFromImportParameters;
import org.ovirt.engine.core.common.action.VdcActionType;
import org.ovirt.engine.core.common.businessentities.DiskImage;
import org.ovirt.engine.core.common.businessentities.VmTemplate;
import org.ovirt.engine.core.common.businessentities.VmTemplateStatus;
import org.ovirt.engine.core.common.queries.GetVmTemplateParameters;
import org.ovirt.engine.core.common.queries.TemplateCandidateInfo;
import org.ovirt.engine.core.common.queries.VdcQueryType;
import org.ovirt.engine.core.common.vdscommands.GetImageInfoVDSCommandParameters;
import org.ovirt.engine.core.common.vdscommands.VDSCommandType;
import org.ovirt.engine.core.common.vdscommands.VDSReturnValue;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.compat.LogCompat;
import org.ovirt.engine.core.compat.LogFactoryCompat;
import org.ovirt.engine.core.compat.StringHelper;
import org.ovirt.engine.core.dal.VdcBllMessages;
import org.ovirt.engine.core.dal.dbbroker.DbFacade;
public class AddVmTemplateFromImportCommand<T extends AddVmTemplateFromImportParameters> extends
AddVmTemplateCommand<T> {
protected TemplateCandidateInfo _candidateInfo;
public AddVmTemplateFromImportCommand(T parameters) {
super(parameters);
}
@Override
protected boolean canDoAction() {
boolean canDoAction = true;
if (!GetAndCheckCandidateInfo() || !CheckCandidateImagesGUIDsLegal()) {
canDoAction = false;
}
else if (isVmTemlateWithSameNameExist(_candidateInfo.getVmTemplateData().getname())) {
log.errorFormat(
"VmTemplateHandler::AddVmTemplateFromImportCommand::CanDoAction: Cannot import candidate {0}, a template with the same name already exists in VDC",
_candidateInfo.getVmTemplateData().getname());
addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_TEMPLATE_NAME_ALREADY_EXISTS);
canDoAction = false;
}
if (!canDoAction && getReturnValue().getCanDoActionMessages().size() > 0) {
addCanDoActionMessage(VdcBllMessages.VAR__ACTION__IMPORT);
addCanDoActionMessage(VdcBllMessages.VAR__TYPE__VM_TEMPLATE);
}
return canDoAction;
}
private boolean GetAndCheckCandidateInfo() {
// Get candidate and check that it is OK:
Object tempVar = Backend.getInstance()
.runInternalQuery(VdcQueryType.GetCandidateInfo, getParameters().getCandidateInfoParams())
.getReturnValue();
_candidateInfo = (TemplateCandidateInfo) ((tempVar instanceof TemplateCandidateInfo) ? tempVar : null);
if (_candidateInfo == null) {
log.errorFormat(
"VmTemplateHandler::AddVmTemplateFromImportCommand::GetAndCheckCandidateInfo: Cannot import candidate {0}, candidate info returned as null from IRS",
getParameters().getCandidateInfoParams().getCandidateIdOrName());
addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_PROBLEM_WITH_CANDIDATE_INFO);
return false;
}
// Set the candidate info's name to new name, if exists. Also set
// AuditLogableBase's VmTemplateName:
setVmTemplateName(!StringHelper.isNullOrEmpty(getParameters().getVmTemplateNewName()) ? getParameters()
.getVmTemplateNewName() : _candidateInfo.getVmTemplateData().getname());
_candidateInfo.getVmTemplateData().setname(getVmTemplateName());
// Check that there isn't already a template with the same GUID in the
// VDC:
Object tempVar2 = Backend
.getInstance()
.runInternalQuery(VdcQueryType.GetVmTemplate,
new GetVmTemplateParameters(_candidateInfo.getVmTemplateData().getId())).getReturnValue();
VmTemplate sameGuidTemplate = (VmTemplate) ((tempVar2 instanceof VmTemplate) ? tempVar2 : null);
if (sameGuidTemplate != null) {
log.errorFormat(
"VmTemplateHandler::AddVmTemplateFromImportCommand::GetAndCheckCandidateInfo: Cannot import candidate {0}, there is already a template with its GUID ({1}) in VDC.",
_candidateInfo.getCandidateDisplayName(),
_candidateInfo.getVmTemplateData().getId());
addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_TEMPLATE_GUID_ALREADY_EXISTS);
return false;
}
return true;
}
private boolean CheckCandidateImagesGUIDsLegal() {
Map<String, List<DiskImage>> imagesToImport = _candidateInfo.getImagesData();
if (imagesToImport != null && imagesToImport.size() > 0) {
for (List<DiskImage> driveImagesToImport : imagesToImport.values()) {
if (driveImagesToImport != null && driveImagesToImport.size() > 0) {
for (DiskImage image : driveImagesToImport) {
// check that each image's GUID doesn't exist in the
// VDC:
Guid imageGUID = image.getId();
Guid storagePoolId = image.getstorage_pool_id() != null ? image.getstorage_pool_id().getValue()
: Guid.Empty;
Guid storageDomainId = image.getstorage_id() != null ? image.getstorage_id().getValue()
: Guid.Empty;
Guid imageGroupId = image.getimage_group_id() != null ? image.getimage_group_id().getValue()
: Guid.Empty;
VDSReturnValue retValue = Backend
.getInstance()
.getResourceManager()
.RunVdsCommand(
VDSCommandType.DoesImageExist,
new GetImageInfoVDSCommandParameters(storagePoolId, storageDomainId,
imageGroupId, imageGUID));
if (retValue == null || retValue.getReturnValue() == null
|| !(retValue.getReturnValue() instanceof Boolean)
|| (Boolean) (retValue.getReturnValue())) {
log.errorFormat(
"VmTemplateHandler::AddVmTemplateFromImportCommand::CheckCandidateImagesGUIDsLegal: Cannot import candidate, Image {0} already exists in IRS",
imageGUID);
addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_IMAGE_ALREADY_EXISTS);
return false;
}
}
}
}
}
return true;
}
@Override
protected void AddVmTemplateToDb() {
_candidateInfo.getVmTemplateData().setstatus(VmTemplateStatus.Locked);
DbFacade.getInstance().getVmTemplateDAO().save(_candidateInfo.getVmTemplateData());
setActionReturnValue(_candidateInfo.getVmTemplateData().getId());
}
@Override
protected void AddVmTemplateImages() {
Guid candidateID = _candidateInfo.getVmTemplateData().getId();
// LINQ 29456
// Dictionary<string, Guid> baseImageIDs =
// _candidateInfo.ImagesData.ToDictionary<KeyValuePair<string,
// List<DiskImage>>, string, Guid>
// (a => a.Key,
// a => a.Value[0].image_guid);
HashMap<String, Guid> baseImageIds = new HashMap<String, Guid>();
for (String key : _candidateInfo.getImagesData().keySet()) {
baseImageIds.put(key, _candidateInfo.getImagesData().get(key).get(0).getId());
}
Backend.getInstance().runInternalAction(
VdcActionType.AddTemplateImagesFromImport,
new AddImagesFromImportParameters(candidateID.toString(), candidateID, baseImageIds, getParameters()
.getCandidateInfoParams().getPath(), getParameters().getCandidateInfoParams()
.getCandidateSource(), getParameters().getForce(), _candidateInfo.getImagesData()));
}
@Override
protected void executeCommand() {
// TODO: einav - consider new ovf structure including vm interfaces
setActionReturnValue(Guid.Empty);
AddCustomValue("ImportedVmTemplateName", _candidateInfo.getVmTemplateData().getname());
AddVmTemplateToDb();
AddVmTemplateImages();
setSucceeded(true);
}
@Override
public AuditLogType getAuditLogTypeValue() {
return getSucceeded() ? AuditLogType.TEMPLATE_IMPORT : AuditLogType.TEMPLATE_IMPORT_FAILED;
}
private static LogCompat log = LogFactoryCompat.getLog(AddVmTemplateFromImportCommand.class);
}