package org.ovirt.engine.api.restapi.resource;
import java.util.List;
import javax.ws.rs.core.Response;
import org.ovirt.engine.api.model.BaseResource;
import org.ovirt.engine.api.model.Disk;
import org.ovirt.engine.api.model.Disks;
import org.ovirt.engine.api.model.StorageType;
import org.ovirt.engine.api.resource.DiskResource;
import org.ovirt.engine.api.resource.DisksResource;
import org.ovirt.engine.api.restapi.logging.Messages;
import org.ovirt.engine.api.restapi.resource.utils.DiskResourceUtils;
import org.ovirt.engine.api.restapi.types.DiskMapper;
import org.ovirt.engine.api.restapi.util.LinkHelper;
import org.ovirt.engine.core.common.action.AddDiskParameters;
import org.ovirt.engine.core.common.action.VdcActionType;
import org.ovirt.engine.core.common.interfaces.SearchType;
import org.ovirt.engine.core.common.queries.IdQueryParameters;
import org.ovirt.engine.core.common.queries.VdcQueryParametersBase;
import org.ovirt.engine.core.common.queries.VdcQueryType;
import org.ovirt.engine.core.compat.Guid;
public class BackendDisksResource
extends AbstractBackendCollectionResource<Disk, org.ovirt.engine.core.common.businessentities.storage.Disk>
implements DisksResource {
public BackendDisksResource() {
super(Disk.class, org.ovirt.engine.core.common.businessentities.storage.Disk.class);
}
@Override
public Response add(Disk disk) {
validateDiskForCreation(disk);
AddDiskParameters params = new AddDiskParameters();
Guid storageDomainId = getStorageDomainId(disk);
params.setStorageDomainId(storageDomainId);
if (storageDomainId != null) {
updateStorageTypeForDisk(disk, storageDomainId);
}
params.setDiskInfo(getMapper(Disk.class, org.ovirt.engine.core.common.businessentities.storage.Disk.class).map(disk, null));
if (disk.isSetLunStorage() && disk.getLunStorage().isSetHost()) {
params.setVdsId(getHostId(disk.getLunStorage().getHost()));
}
return performCreate(VdcActionType.AddDisk, params,
new QueryIdResolver<Guid>(VdcQueryType.GetDiskByDiskId, IdQueryParameters.class));
}
private void updateStorageTypeForDisk(Disk disk, Guid storageDomainId) {
org.ovirt.engine.core.common.businessentities.StorageDomain storageDomain = getStorageDomainById(storageDomainId);
if (storageDomain != null) {
disk.setStorageType(DiskMapper.map(storageDomain.getStorageDomainType()));
}
}
private Guid getStorageDomainId(Disk disk) {
if (disk.isSetStorageDomains() && disk.getStorageDomains().isSetStorageDomains()
&& disk.getStorageDomains().getStorageDomains().get(0).isSetId()) {
return asGuid(disk.getStorageDomains().getStorageDomains().get(0).getId());
} else if (disk.isSetStorageDomains() && disk.getStorageDomains().getStorageDomains().get(0).isSetName()) {
String storageName = disk.getStorageDomains().getStorageDomains().get(0).getName();
Guid storageDomainId = getStorageDomainIdByName(storageName);
if (storageDomainId == null) {
notFound(storageName);
} else {
return storageDomainId;
}
}
return null;
}
private org.ovirt.engine.core.common.businessentities.StorageDomain getStorageDomainById(Guid id) {
return getEntity(org.ovirt.engine.core.common.businessentities.StorageDomain.class, VdcQueryType.GetStorageDomainById, new IdQueryParameters(id), id.toString());
}
protected void validateDiskForCreation(Disk disk) {
if (DiskResourceUtils.isLunDisk(disk)) {
validateParameters(disk.getLunStorage(), 2, "type"); // when creating a LUN disk, user must specify type.
StorageType storageType = disk.getLunStorage().getType();
if (storageType != null && storageType == StorageType.ISCSI) {
validateParameters(disk.getLunStorage().getLogicalUnits().getLogicalUnits().get(0), 3, "address",
"target", "port", "id");
}
} else if (disk.isSetLunStorage() && (!disk.getLunStorage().isSetLogicalUnits() || !disk.getLunStorage().getLogicalUnits().isSetLogicalUnits())) {
// TODO: Implement nested entity existence validation infra for validateParameters()
throw new WebFaultException(null,
localize(Messages.INCOMPLETE_PARAMS_REASON),
localize(Messages.INCOMPLETE_PARAMS_DETAIL_TEMPLATE, "LogicalUnit", "", "add"),
Response.Status.BAD_REQUEST);
} else {
validateParameters(disk, 2, "provisionedSize|size", "format"); // Non lun disks require size and format
}
}
private Guid getStorageDomainIdByName(String storageDomainName) {
List<org.ovirt.engine.core.common.businessentities.StorageDomain> storageDomains =
getBackendCollection(org.ovirt.engine.core.common.businessentities.StorageDomain.class,
VdcQueryType.GetAllStorageDomains,
new VdcQueryParametersBase());
for (org.ovirt.engine.core.common.businessentities.StorageDomain storageDomain : storageDomains) {
if (storageDomain.getStorageName().equals(storageDomainName)) {
return storageDomain.getId();
}
}
return null;
}
@Override
public Disks list() {
if (isFiltered()) {
return mapCollection(getBackendCollection(VdcQueryType.GetAllDisks, new VdcQueryParametersBase()));
} else {
return mapCollection(getBackendCollection(SearchType.Disk));
}
}
@Override
public DiskResource getDiskResource(String id) {
return inject(new BackendDiskResource(id));
}
protected Disks mapCollection(List<org.ovirt.engine.core.common.businessentities.storage.Disk> entities) {
Disks collection = new Disks();
for (org.ovirt.engine.core.common.businessentities.storage.Disk disk : entities) {
collection.getDisks().add(addLinks(populate(map(disk), disk)));
}
return collection;
}
@Override
protected Disk addLinks(Disk model, Class<? extends BaseResource> suggestedParent, String... subCollectionMembersToExclude) {
// Currently the method that adds the links doesn't take into account that links need to be added also to
// elements of lists, so whe need to add them explicitly:
Disk disk = super.addLinks(model, suggestedParent, subCollectionMembersToExclude);
if (disk.isSetStorageDomains()) {
disk.getStorageDomains().getStorageDomains().forEach(
storageDomain -> LinkHelper.addLinks(storageDomain, null, false)
);
}
return disk;
}
}