package org.ovirt.engine.core.dao;
import java.io.IOException;
import java.util.List;
import javax.inject.Named;
import javax.inject.Singleton;
import org.codehaus.jackson.annotate.JsonAutoDetect;
import org.codehaus.jackson.map.ObjectMapper;
import org.ovirt.engine.core.common.businessentities.VDS;
import org.ovirt.engine.core.common.businessentities.VDSStatus;
import org.ovirt.engine.core.common.businessentities.VDSType;
import org.ovirt.engine.core.common.businessentities.VdsStatic;
import org.ovirt.engine.core.common.utils.pm.FenceProxySourceTypeHelper;
import org.ovirt.engine.core.compat.Guid;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.SingleColumnRowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcCall;
/**
* {@code VdsDaoImpl} provides an implementation of {@link VdsDao}.
*/
@Named
@Singleton
public class VdsStaticDaoImpl extends BaseDao implements VdsStaticDao {
@Override
public VdsStatic get(Guid id) {
return getCallsHandler().executeRead("GetVdsStaticByVdsId",
vdsStaticRowMapper,
getCustomMapSqlParameterSource()
.addValue("vds_id", id));
}
@Override
public VdsStatic getByHostName(String host) {
return getCallsHandler().executeRead("GetVdsStaticByHostName",
vdsStaticRowMapper,
getCustomMapSqlParameterSource()
.addValue("host_name", host));
}
@Override
public List<VdsStatic> getAllWithIpAddress(String address) {
return getCallsHandler().executeReadList("GetVdsStaticByIp",
vdsStaticRowMapper,
getCustomMapSqlParameterSource()
.addValue("ip", address));
}
@Override
public List<VdsStatic> getAllForCluster(Guid cluster) {
return getCallsHandler().executeReadList("GetVdsStaticByClusterId",
vdsStaticRowMapper,
getCustomMapSqlParameterSource()
.addValue("cluster_id", cluster));
}
@Override
public void save(VdsStatic vds) {
Guid id = vds.getId();
if (Guid.isNullOrEmpty(id)) {
id = Guid.newGuid();
vds.setId(id);
}
new SimpleJdbcCall(getJdbcTemplate()).withProcedureName("InsertVdsStatic")
.execute(getInsertOrUpdateParams(vds));
}
/**
* Note: Id doesn't update {@code last_stored_kernel_cmdline} column.
* @see #updateLastStoredKernelCmdline(Guid, String)
*/
@Override
public void update(VdsStatic vds) {
getCallsHandler().executeModification("UpdateVdsStatic", getInsertOrUpdateParams(vds));
}
private MapSqlParameterSource getInsertOrUpdateParams(final VdsStatic vds) {
return getCustomMapSqlParameterSource()
.addValue("host_name", vds.getHostName())
.addValue("free_text_comment", vds.getComment())
.addValue("vds_unique_id", vds.getUniqueID())
.addValue("port", vds.getPort())
.addValue("cluster_id", vds.getClusterId())
.addValue("vds_id", vds.getId())
.addValue("vds_name", vds.getName())
.addValue("server_SSL_enabled", vds.isServerSslEnabled())
.addValue("vds_type", vds.getVdsType())
.addValue("vds_strength", vds.getVdsStrength())
.addValue("pm_enabled", vds.isPmEnabled())
.addValue("pm_proxy_preferences", FenceProxySourceTypeHelper.saveAsString(vds.getFenceProxySources()))
.addValue("pm_detect_kdump", vds.isPmKdumpDetection())
.addValue("otp_validity", vds.getOtpValidity())
.addValue("vds_spm_priority", vds.getVdsSpmPriority())
.addValue("console_address", vds.getConsoleAddress())
.addValue("sshKeyFingerprint", vds.getSshKeyFingerprint())
.addValue("ssh_port", vds.getSshPort())
.addValue("ssh_username", vds.getSshUsername())
.addValue("disable_auto_pm", vds.isDisablePowerManagementPolicy())
.addValue("host_provider_id", vds.getHostProviderId())
.addValue("openstack_network_provider_id", vds.getOpenstackNetworkProviderId())
.addValue("kernel_cmdline", KernelCmdlineColumn.fromVdsStatic(vds).toJson())
.addValue("last_stored_kernel_cmdline", vds.getLastStoredKernelCmdline());
}
@Override
public void remove(Guid id) {
MapSqlParameterSource parameterSource = getCustomMapSqlParameterSource()
.addValue("vds_id", id);
getCallsHandler().executeModification("DeleteVdsStatic", parameterSource);
}
@Override
public List<VdsStatic> getAll() {
throw new UnsupportedOperationException();
}
private static final RowMapper<VdsStatic> vdsStaticRowMapper = (rs, rowNum) -> {
VdsStatic entity = new VdsStatic();
entity.setHostName(rs.getString("host_name"));
entity.setComment(rs.getString("free_text_comment"));
entity.setUniqueID(rs.getString("vds_unique_id"));
entity.setPort(rs.getInt("port"));
entity.setClusterId(getGuidDefaultEmpty(rs, "cluster_id"));
entity.setId(getGuidDefaultEmpty(rs, "vds_id"));
entity.setSshPort(rs.getInt("ssh_port"));
entity.setSshUsername(rs.getString("ssh_username"));
entity.setClusterId(Guid.createGuidFromStringDefaultEmpty(rs.getString("cluster_id")));
entity.setId(Guid.createGuidFromStringDefaultEmpty(rs.getString("vds_id")));
entity.setName(rs.getString("vds_name"));
entity.setServerSslEnabled(rs.getBoolean("server_SSL_enabled"));
entity.setVdsType(VDSType.forValue(rs.getInt("vds_type")));
entity.setVdsStrength(rs.getInt("vds_strength"));
entity.setPmEnabled(rs.getBoolean("pm_enabled"));
entity.setFenceProxySources(FenceProxySourceTypeHelper.parseFromString(rs.getString("pm_proxy_preferences")));
entity.setPmKdumpDetection(rs.getBoolean("pm_detect_kdump"));
entity.setOtpValidity(rs.getLong("otp_validity"));
entity.setSshKeyFingerprint(rs.getString("sshKeyFingerprint"));
entity.setConsoleAddress(rs.getString("console_address"));
entity.setDisablePowerManagementPolicy(rs.getBoolean("disable_auto_pm"));
entity.setHostProviderId(getGuid(rs, "host_provider_id"));
entity.setOpenstackNetworkProviderId(getGuid(rs, "openstack_network_provider_id"));
KernelCmdlineColumn.fromJson(rs.getString("kernel_cmdline")).toVdsStatic(entity);
entity.setLastStoredKernelCmdline(rs.getString("last_stored_kernel_cmdline"));
return entity;
};
@Override
public VdsStatic getByVdsName(String vdsName) {
return getCallsHandler().executeRead("GetVdsStaticByVdsName",
vdsStaticRowMapper,
getCustomMapSqlParameterSource()
.addValue("host_name", vdsName));
}
@Override
public List<String> getAllHostNamesPinnedToVm(Guid vm) {
return getCallsHandler().executeReadList("GetNamesOfHostsDedicatedToVm",
SingleColumnRowMapper.newInstance(String.class),
getCustomMapSqlParameterSource().addValue("vm_guid", vm));
}
@Override
public void updateLastStoredKernelCmdline(Guid vdsStaticId, String lastStoredKernelCmdline) {
getCallsHandler().executeModification(
"UpdateVdsStaticLastStoredKernelCmdline",
getCustomMapSqlParameterSource()
.addValue("vds_id", vdsStaticId)
.addValue("last_stored_kernel_cmdline", lastStoredKernelCmdline));
}
@Override
public boolean checkIfExistsHostThatMissesNetworkInCluster(Guid clusterId, String networkName, VDSStatus hostStatus) {
final MapSqlParameterSource customMapSqlParameterSource = getCustomMapSqlParameterSource()
.addValue("cluster_id", clusterId)
.addValue("network_name", networkName)
.addValue("host_status", hostStatus);
return getCallsHandler().executeRead(
"CheckIfExistsHostThatMissesNetworkInCluster",
SingleColumnRowMapper.newInstance(Boolean.class),
customMapSqlParameterSource);
}
/**
* Model of JSON structured column "kernel_cmdline"
*/
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
static class KernelCmdlineColumn {
private String current;
private boolean parsable;
private boolean iommu;
private boolean kvmNested;
private boolean unsafeInterrupts;
private boolean pciRealloc;
public String toJson() {
try {
return new ObjectMapper().writeValueAsString(this);
} catch (IOException ex) {
throw new RuntimeException(
"Error during JSON serialization of " + KernelCmdlineColumn.class.getCanonicalName(), ex);
}
}
public static KernelCmdlineColumn fromJson(String json) {
final String nonSafeJson = json == null ? "{}" : json;
try {
return new ObjectMapper().readValue(nonSafeJson, KernelCmdlineColumn.class);
} catch (IOException ex) {
throw new RuntimeException(
"Error during JSON deserialization of " + KernelCmdlineColumn.class.getCanonicalName(), ex);
}
}
public void toVdsStatic(VdsStatic vdsStatic) {
vdsStatic.setCurrentKernelCmdline(current);
vdsStatic.setKernelCmdlineParsable(parsable);
vdsStatic.setKernelCmdlineIommu(iommu);
vdsStatic.setKernelCmdlineKvmNested(kvmNested);
vdsStatic.setKernelCmdlineUnsafeInterrupts(unsafeInterrupts);
vdsStatic.setKernelCmdlinePciRealloc(pciRealloc);
}
public void toVds(VDS vds) {
vds.setCurrentKernelCmdline(current);
vds.setKernelCmdlineParsable(parsable);
vds.setKernelCmdlineIommu(iommu);
vds.setKernelCmdlineKvmNested(kvmNested);
vds.setKernelCmdlineUnsafeInterrupts(unsafeInterrupts);
vds.setKernelCmdlinePciRealloc(pciRealloc);
}
public static KernelCmdlineColumn fromVdsStatic(VdsStatic vdsStatic) {
final KernelCmdlineColumn kernelCmdlineColumn = new KernelCmdlineColumn();
kernelCmdlineColumn.current = vdsStatic.getCurrentKernelCmdline();
kernelCmdlineColumn.parsable = vdsStatic.isKernelCmdlineParsable();
kernelCmdlineColumn.iommu = vdsStatic.isKernelCmdlineIommu();
kernelCmdlineColumn.kvmNested = vdsStatic.isKernelCmdlineKvmNested();
kernelCmdlineColumn.unsafeInterrupts = vdsStatic.isKernelCmdlineUnsafeInterrupts();
kernelCmdlineColumn.pciRealloc = vdsStatic.isKernelCmdlinePciRealloc();
return kernelCmdlineColumn;
}
}
}