package org.ovirt.engine.core.bll.storage.ovfstore;
import static org.ovirt.engine.core.bll.storage.disk.image.DisksFilter.ONLY_ACTIVE;
import static org.ovirt.engine.core.bll.storage.disk.image.DisksFilter.ONLY_SNAPABLE;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.apache.commons.lang.StringUtils;
import org.ovirt.engine.core.bll.VmHandler;
import org.ovirt.engine.core.bll.VmTemplateHandler;
import org.ovirt.engine.core.bll.storage.disk.image.DisksFilter;
import org.ovirt.engine.core.bll.storage.disk.image.ImagesHandler;
import org.ovirt.engine.core.bll.utils.ClusterUtils;
import org.ovirt.engine.core.bll.validator.storage.DiskImagesValidator;
import org.ovirt.engine.core.common.businessentities.VM;
import org.ovirt.engine.core.common.businessentities.VMStatus;
import org.ovirt.engine.core.common.businessentities.VmTemplate;
import org.ovirt.engine.core.common.businessentities.network.VmNetworkInterface;
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.VmStaticDao;
import org.ovirt.engine.core.dao.VmTemplateDao;
import org.ovirt.engine.core.dao.network.VmNetworkInterfaceDao;
import org.ovirt.engine.core.utils.ovf.OvfManager;
import org.ovirt.engine.core.utils.ovf.OvfReaderException;
/**
* OvfHelper is a helper class that encapsulates the bll logic that needs
* to be done on the ovf read data before using it in the bll project.
*/
@Singleton
public class OvfHelper {
@Inject
private VmNetworkInterfaceDao vmNetworkInterfaceDao;
@Inject
private VmTemplateDao vmTemplateDao;
@Inject
private VmStaticDao vmStaticDao;
@Inject
private DiskImageDao diskImageDao;
@Inject
private VmHandler vmHandler;
@Inject
private OvfManager ovfManager;
/**
* parses a given ovf to a vm, intialized with images and interfaces.
* @return
* VM that represents the given ovf data
*/
public VM readVmFromOvf(String ovf) throws OvfReaderException {
VM vm = new VM();
ArrayList<DiskImage> diskImages = new ArrayList<>();
ArrayList<VmNetworkInterface> interfaces = new ArrayList<>();
ovfManager.importVm(ovf, vm, diskImages, interfaces);
// add images
vm.setImages(diskImages);
// add interfaces
vm.setInterfaces(interfaces);
// add disk map
Map<Guid, List<DiskImage>> images = ImagesHandler
.getImagesLeaf(diskImages);
for (Map.Entry<Guid, List<DiskImage>> entry : images.entrySet()) {
List<DiskImage> list = entry.getValue();
vm.getDiskMap().put(entry.getKey(), list.get(list.size() - 1));
}
return vm;
}
/**
* parses a given ovf to a VmTemplate, initialized with images and interfaces.
* @return
* VmTemplate that represents the given ovf data
*/
public VmTemplate readVmTemplateFromOvf(String ovf) throws OvfReaderException {
ArrayList<DiskImage> diskImages = new ArrayList<>();
ArrayList<VmNetworkInterface> interfaces = new ArrayList<>();
VmTemplate template = new VmTemplate();
ovfManager.importTemplate(ovf, template, diskImages, interfaces);
template.setInterfaces(interfaces);
// add disk map
for (DiskImage disk : diskImages) {
template.getDiskTemplateMap().put(disk.getId(), disk);
}
return template;
}
public String generateOvfConfigurationForVm(VM vm) {
if (VMStatus.ImageLocked != vm.getStatus()) {
vmHandler.updateDisksFromDb(vm);
DiskImagesValidator validator = new DiskImagesValidator(vm.getDiskList());
if (validator.diskImagesNotLocked().isValid()) {
loadVmData(vm);
Long currentDbGeneration = vmStaticDao.getDbGeneration(vm.getId());
// currentDbGeneration can be null in case that the vm was deleted during the run of OvfDataUpdater.
if (currentDbGeneration != null && vm.getStaticData().getDbGeneration() == currentDbGeneration) {
return buildMetadataDictionaryForVm(vm);
}
}
}
return null;
}
/**
* Adds the given vm metadata to the given map
*/
private String buildMetadataDictionaryForVm(VM vm) {
List<DiskImage> allVmImages = new ArrayList<>();
List<DiskImage> filteredDisks = DisksFilter.filterImageDisks(vm.getDiskList(), ONLY_SNAPABLE, ONLY_ACTIVE);
for (DiskImage diskImage : filteredDisks) {
List<DiskImage> images = diskImageDao.getAllSnapshotsForLeaf(diskImage.getImageId());
images.forEach(d -> d.setDiskVmElements(Collections.singletonList(diskImage.getDiskVmElementForVm(vm.getId()))));
allVmImages.addAll(images);
}
return ovfManager.exportVm(vm, allVmImages, ClusterUtils.getCompatibilityVersion(vm));
}
private void loadVmData(VM vm) {
if (vm.getInterfaces().isEmpty()) {
vm.setInterfaces(vmNetworkInterfaceDao.getAllForVm(vm.getId()));
}
if (StringUtils.isEmpty(vm.getVmtName())) {
if (!Guid.Empty.equals(vm.getVmtGuid())) {
VmTemplate template = vmTemplateDao.get(vm.getVmtGuid());
vm.setVmtName(template.getName());
} else {
vm.setVmtName(VmTemplateHandler.BLANK_VM_TEMPLATE_NAME);
}
}
}
public boolean isOvfTemplate(String ovfstring) throws OvfReaderException {
return ovfManager.isOvfTemplate(ovfstring);
}
}