package org.ovirt.engine.api.restapi.resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import javax.ws.rs.core.Response;
import org.ovirt.engine.api.model.ConfigurationType;
import org.ovirt.engine.api.model.Disk;
import org.ovirt.engine.api.model.DiskAttachment;
import org.ovirt.engine.api.model.DiskAttachments;
import org.ovirt.engine.api.model.Disks;
import org.ovirt.engine.api.model.Snapshot;
import org.ovirt.engine.api.model.Snapshots;
import org.ovirt.engine.api.model.Vm;
import org.ovirt.engine.api.resource.SnapshotResource;
import org.ovirt.engine.api.resource.SnapshotsResource;
import org.ovirt.engine.api.restapi.types.DiskMapper;
import org.ovirt.engine.api.restapi.types.SnapshotMapper;
import org.ovirt.engine.core.common.action.CreateAllSnapshotsFromVmParameters;
import org.ovirt.engine.core.common.action.VdcActionType;
import org.ovirt.engine.core.common.businessentities.storage.DiskImage;
import org.ovirt.engine.core.common.queries.IdQueryParameters;
import org.ovirt.engine.core.common.queries.VdcQueryReturnValue;
import org.ovirt.engine.core.common.queries.VdcQueryType;
import org.ovirt.engine.core.compat.Guid;
public class BackendSnapshotsResource
extends AbstractBackendCollectionResource<Snapshot, org.ovirt.engine.core.common.businessentities.Snapshot>
implements SnapshotsResource {
protected Guid parentId;
public BackendSnapshotsResource(Guid parentId) {
super(Snapshot.class, org.ovirt.engine.core.common.businessentities.Snapshot.class);
this.parentId = parentId;
}
@Override
public Snapshots list() {
return mapCollection(getBackendCollection(VdcQueryType.GetAllVmSnapshotsByVmId,
new IdQueryParameters(parentId)));
}
@Override
public Response add(Snapshot snapshot) {
return doAdd(snapshot, expectBlocking());
}
protected Response doAdd(Snapshot snapshot, boolean block) {
validateParameters(snapshot, "description");
CreateAllSnapshotsFromVmParameters snapshotParams =
new CreateAllSnapshotsFromVmParameters(parentId, snapshot.getDescription());
if (snapshot.isSetPersistMemorystate()) {
snapshotParams.setSaveMemory(snapshot.isPersistMemorystate());
}
if (snapshot.isSetDiskAttachments()) {
snapshotParams.setDisks(mapDisks(snapshot.getDiskAttachments()));
}
return performCreate(VdcActionType.CreateAllSnapshotsFromVm,
snapshotParams,
new SnapshotIdResolver(),
block);
}
private List<DiskImage> mapDisks(DiskAttachments diskAttachments) {
List<DiskImage> diskImages = null;
if (diskAttachments.isSetDiskAttachments()) {
diskImages =
diskAttachments.getDiskAttachments().stream()
.map(DiskAttachment::getDisk)
.filter(Objects::nonNull)
.map(d -> (DiskImage) DiskMapper.map(d, null))
.collect(Collectors.toList());
}
return diskImages;
}
public ArrayList<DiskImage> mapDisks(Disks disks) {
ArrayList<DiskImage> diskImages = null;
if (disks != null && disks.isSetDisks()) {
diskImages = new ArrayList<>();
for (Disk disk : disks.getDisks()) {
if (disk != null) {
DiskImage diskImage = (DiskImage) DiskMapper.map(disk, null);
diskImages.add(diskImage);
}
}
}
return diskImages;
}
@Override
public SnapshotResource getSnapshotResource(String id) {
return inject(new BackendSnapshotResource(id, parentId, this));
}
protected Snapshots mapCollection(List<org.ovirt.engine.core.common.businessentities.Snapshot> entities) {
Snapshots snapshots = new Snapshots();
for (org.ovirt.engine.core.common.businessentities.Snapshot entity : entities) {
Snapshot snapshot = map(entity, null);
snapshot = populate(snapshot, entity);
snapshot = addLinks(snapshot);
snapshot = addVmConfiguration(entity, snapshot);
snapshots.getSnapshots().add(snapshot);
}
return snapshots;
}
protected Snapshot addVmConfiguration(org.ovirt.engine.core.common.businessentities.Snapshot entity, Snapshot snapshot) {
if (entity.isVmConfigurationAvailable()) {
snapshot.setVm(new Vm());
getMapper(org.ovirt.engine.core.common.businessentities.VM.class, Vm.class).map(getVmPreview(snapshot), snapshot.getVm());
}
else {
snapshot.setVm(null);
snapshot.getLinks().clear();
}
return snapshot;
}
protected org.ovirt.engine.core.common.businessentities.VM getVmPreview(Snapshot snapshot) {
org.ovirt.engine.core.common.businessentities.VM vm = getEntity(org.ovirt.engine.core.common.businessentities.VM.class, VdcQueryType.GetVmConfigurationBySnapshot, new IdQueryParameters(asGuid(snapshot.getId())), null);
return vm;
}
protected org.ovirt.engine.core.common.businessentities.Snapshot getSnapshotById(Guid id) {
//TODO: move to 'GetSnapshotBySnapshotId' once Backend supplies it.
for (org.ovirt.engine.core.common.businessentities.Snapshot snapshot : getBackendCollection(VdcQueryType.GetAllVmSnapshotsByVmId,
new IdQueryParameters(parentId))) {
if (snapshot.getId().equals(id)) {
return snapshot;
}
}
return null;
}
@Override
protected Snapshot addParents(Snapshot snapshot) {
snapshot.setVm(new Vm());
snapshot.getVm().setId(parentId.toString());
return snapshot;
}
protected class SnapshotIdResolver extends EntityIdResolver<Guid> {
SnapshotIdResolver() {}
@Override
public org.ovirt.engine.core.common.businessentities.Snapshot lookupEntity(
Guid id) throws BackendFailureException {
return getSnapshotById(id);
}
}
@Override
protected Snapshot doPopulate(Snapshot model, org.ovirt.engine.core.common.businessentities.Snapshot entity) {
return populateSnapshotConfiguration(model);
}
private Snapshot populateSnapshotConfiguration (Snapshot model) {
VdcQueryReturnValue queryReturnValue =
runQuery(VdcQueryType.GetSnapshotBySnapshotId,
new IdQueryParameters(Guid.createGuidFromString(model.getId())));
if (queryReturnValue.getSucceeded() && queryReturnValue.getReturnValue() != null) {
org.ovirt.engine.core.common.businessentities.Snapshot snapshot = queryReturnValue.getReturnValue();
if (snapshot.getVmConfiguration() != null) {
return SnapshotMapper.map(snapshot.getVmConfiguration(),
ConfigurationType.OVF,
model);
}
}
return model;
}
}