package org.ovirt.engine.core.dao; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.Map; import javax.inject.Named; import javax.inject.Singleton; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.type.TypeReference; import org.ovirt.engine.core.common.businessentities.BootSequence; import org.ovirt.engine.core.common.businessentities.GraphicsInfo; import org.ovirt.engine.core.common.businessentities.GraphicsType; import org.ovirt.engine.core.common.businessentities.GuestAgentStatus; import org.ovirt.engine.core.common.businessentities.GuestContainer; import org.ovirt.engine.core.common.businessentities.SessionState; import org.ovirt.engine.core.common.businessentities.VMStatus; import org.ovirt.engine.core.common.businessentities.VmDynamic; import org.ovirt.engine.core.common.businessentities.VmExitReason; import org.ovirt.engine.core.common.businessentities.VmExitStatus; import org.ovirt.engine.core.common.businessentities.VmPauseStatus; import org.ovirt.engine.core.common.utils.Pair; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.dal.dbbroker.DbFacadeUtils; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.SingleColumnRowMapper; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; @Named @Singleton public class VmDynamicDaoImpl extends MassOperationsGenericDao<VmDynamic, Guid> implements VmDynamicDao { public VmDynamicDaoImpl() { super("VmDynamic"); setProcedureNameForGet("GetVmDynamicByVmGuid"); } @Override public List<VmDynamic> getAllRunningForVds(Guid id) { MapSqlParameterSource parameterSource = getCustomMapSqlParameterSource() .addValue("vds_id", id); RowMapper<VmDynamic> mapper = createEntityRowMapper(); return getCallsHandler().executeReadList("GetVmsDynamicRunningOnVds", mapper, parameterSource); } @Override public boolean isAnyVmRunOnVds(Guid vdsId) { MapSqlParameterSource parameterSource = getCustomMapSqlParameterSource() .addValue("vds_id", vdsId); return getCallsHandler().executeRead("IsAnyVmRunOnVds", SingleColumnRowMapper.newInstance(Boolean.class), parameterSource); } @Override public void updateStatus(Guid vmGuid, VMStatus status) { MapSqlParameterSource parameterSource = getCustomMapSqlParameterSource() .addValue("vm_guid", vmGuid) .addValue("status", status); getCallsHandler().executeModification("UpdateVmDynamicStatus", parameterSource); } @Override public void clearMigratingToVds(Guid id) { MapSqlParameterSource parameterSource = getCustomMapSqlParameterSource() .addValue("vm_guid", id); getCallsHandler().executeModification("ClearMigratingToVds", parameterSource); } @Override public boolean updateConsoleUserWithOptimisticLocking(VmDynamic vm) { MapSqlParameterSource parameterSource = getCustomMapSqlParameterSource() .addValue("vm_guid", vm.getId()) .addValue("console_user_id", vm.getConsoleUserId()) .addValue("guest_cur_user_name", vm.getGuestCurrentUserName()) .addValue("console_cur_user_name", vm.getConsoleCurrentUserName()); Map<String, Object> results = getCallsHandler().executeModification("UpdateConsoleUserWithOptimisticLocking", parameterSource); return (Boolean) results.get("updated"); } @Override public List<VmDynamic> getAll() { return getCallsHandler().executeReadList("GetAllFromVmDynamic", createEntityRowMapper(), getCustomMapSqlParameterSource()); } @Override public void updateGuestAgentStatus(Guid vmId, GuestAgentStatus guestAgentStatus) { getCallsHandler().executeModification("UpdateGuestAgentStatus", getCustomMapSqlParameterSource() .addValue("vm_guid", vmId) .addValue("guest_agent_status", guestAgentStatus.getValue())); } @Override public void updateVmsToUnknown(List<Guid> vmIds) { MapSqlParameterSource parameterSource = getCustomMapSqlParameterSource() .addValue("vm_ids", createArrayOfUUIDs(vmIds)) .addValue("status", VMStatus.Unknown); getCallsHandler().executeModification("SetToUnknown", parameterSource); } @Override public List<VmDynamic> getAllMigratingToHost(Guid vdsId) { return getCallsHandler().executeReadList("GetVmsMigratingToVds", createEntityRowMapper(), getCustomMapSqlParameterSource() .addValue("vds_id", vdsId)); } @Override public List<Pair<Guid, String>> getAllDevicesHashes() { MapSqlParameterSource parameterSource = getCustomMapSqlParameterSource(); return getCallsHandler().executeReadList("GetAllHashesFromVmDynamic", (rs, i) -> new Pair<>(new Guid(rs.getString("vm_guid")), rs.getString("hash")), parameterSource); } @Override public void updateDevicesHashes(List<Pair<Guid, String>> vmHashes) { getCallsHandler().executeStoredProcAsBatch("SetHashByVmGuid", vmHashes, pair -> getCustomMapSqlParameterSource() .addValue("vm_guid", pair.getFirst()) .addValue("hash", pair.getSecond())); } @Override protected MapSqlParameterSource createIdParameterMapper(Guid id) { return getCustomMapSqlParameterSource().addValue("vm_guid", id); } @Override protected MapSqlParameterSource createFullParametersMapper(VmDynamic vm) { GraphicsInfo spice = vm.getGraphicsInfos().get(GraphicsType.SPICE); GraphicsInfo vnc = vm.getGraphicsInfos().get(GraphicsType.VNC); return createIdParameterMapper(vm.getId()) .addValue("app_list", vm.getAppList()) .addValue("guest_cur_user_name", vm.getGuestCurrentUserName()) .addValue("console_cur_user_name", vm.getConsoleCurrentUserName()) .addValue("console_user_id", vm.getConsoleUserId()) .addValue("guest_os", vm.getGuestOs()) .addValue("migrating_to_vds", vm.getMigratingToVds()) .addValue("run_on_vds", vm.getRunOnVds()) .addValue("status", vm.getStatus()) .addValue("vm_host", vm.getVmHost()) .addValue("vm_ip", vm.getIp()) .addValue("vm_fqdn", vm.getFqdn()) .addValue("last_start_time", vm.getLastStartTime()) .addValue("last_stop_time", vm.getLastStopTime()) .addValue("acpi_enable", vm.getAcpiEnable()) .addValue("session", vm.getSession()) .addValue("boot_sequence", vm.getBootSequence()) .addValue("utc_diff", vm.getUtcDiff()) .addValue("client_ip", vm.getClientIp()) .addValue("guest_requested_memory", vm.getGuestRequestedMemory()) .addValue("exit_status", vm.getExitStatus().getValue()) .addValue("pause_status", vm.getPauseStatus().getValue()) .addValue("exit_message", vm.getExitMessage()) .addValue("guest_agent_nics_hash", vm.getGuestAgentNicsHash()) .addValue("last_watchdog_event", vm.getLastWatchdogEvent()) .addValue("last_watchdog_action", vm.getLastWatchdogAction()) .addValue("is_run_once", vm.isRunOnce()) .addValue("cpu_name", vm.getCpuName()) .addValue("guest_agent_status", vm.getGuestAgentStatus().getValue()) .addValue("current_cd", vm.getCurrentCd()) .addValue("reason", vm.getStopReason()) .addValue("exit_reason", vm.getExitReason().getValue()) .addValue("guest_cpu_count", vm.getGuestCpuCount()) .addValue("emulated_machine", vm.getEmulatedMachine()) .addValue("spice_port", spice != null ? spice.getPort() : null) .addValue("spice_tls_port", spice != null ? spice.getTlsPort() : null) .addValue("spice_ip", spice != null ? spice.getIp() : null) .addValue("vnc_port", vnc != null ? vnc.getPort() : null) .addValue("vnc_ip", vnc != null ? vnc.getIp() : null) .addValue("guest_timezone_name", vm.getGuestOsTimezoneName()) .addValue("guest_timezone_offset", vm.getGuestOsTimezoneOffset()) .addValue("guestos_arch", vm.getGuestOsArch().getValue()) .addValue("guestos_codename", vm.getGuestOsCodename()) .addValue("guestos_distribution", vm.getGuestOsDistribution()) .addValue("guestos_kernel_version", vm.getGuestOsKernelVersion()) .addValue("guestos_type", vm.getGuestOsType().name()) .addValue("guestos_version", vm.getGuestOsVersion()) .addValue("guest_containers", toGuestContainersString(vm)); } private static ObjectMapper JSON_MAPPER = new ObjectMapper(); private static String toGuestContainersString(VmDynamic vm) { try { return JSON_MAPPER.writeValueAsString(vm.getGuestContainers()); } catch(Exception e) { return "[]"; } } @SuppressWarnings("unchecked") private static List<GuestContainer> fromContainersString(String s) { try { return (List<GuestContainer>) JSON_MAPPER.readValue(s, new TypeReference<List<GuestContainer>>() {}); } catch(Exception e) { return new ArrayList<>(); } } @Override protected RowMapper<VmDynamic> createEntityRowMapper() { return vmDynamicRowMapper; } private static final RowMapper<VmDynamic> vmDynamicRowMapper = (rs, rowNum) -> { VmDynamic entity = new VmDynamic(); entity.setAppList(rs.getString("app_list")); entity.setGuestCurrentUserName(rs.getString("guest_cur_user_name")); entity.setConsoleCurrentUserName(rs.getString("console_cur_user_name")); entity.setConsoleUserId(getGuid(rs, "console_user_id")); entity.setGuestOs(rs.getString("guest_os")); entity.setMigratingToVds(getGuid(rs, "migrating_to_vds")); entity.setRunOnVds(getGuid(rs, "run_on_vds")); entity.setStatus(VMStatus.forValue(rs.getInt("status"))); entity.setId(getGuidDefaultEmpty(rs, "vm_guid")); entity.setVmHost(rs.getString("vm_host")); entity.setIp(rs.getString("vm_ip")); entity.setFqdn(rs.getString("vm_fqdn")); entity.setLastStartTime(DbFacadeUtils.fromDate(rs.getTimestamp("last_start_time"))); entity.setLastStopTime(DbFacadeUtils.fromDate(rs.getTimestamp("last_stop_time"))); entity.setAcpiEnable((Boolean) rs.getObject("acpi_enable")); entity.setSession(SessionState.forValue(rs.getInt("session"))); entity.setBootSequence(BootSequence.forValue(rs.getInt("boot_sequence"))); entity.setUtcDiff((Integer) rs.getObject("utc_diff")); entity.setClientIp(rs.getString("client_ip")); entity.setGuestRequestedMemory((Integer) rs.getObject("guest_requested_memory")); VmExitStatus exitStatus = VmExitStatus.forValue(rs.getInt("exit_status")); VmPauseStatus pauseStatus = VmPauseStatus.forValue(rs.getInt("pause_status")); entity.setExitMessage(rs.getString("exit_message")); entity.setExitStatus(exitStatus); entity.setPauseStatus(pauseStatus); entity.setGuestAgentNicsHash(rs.getInt("guest_agent_nics_hash")); entity.setLastWatchdogEvent(getLong(rs, "last_watchdog_event")); entity.setLastWatchdogAction(rs.getString("last_watchdog_action")); entity.setRunOnce(rs.getBoolean("is_run_once")); entity.setCpuName(rs.getString("cpu_name")); entity.setGuestAgentStatus(GuestAgentStatus.forValue(rs.getInt("guest_agent_status"))); entity.setCurrentCd(rs.getString("current_cd")); entity.setStopReason(rs.getString("reason")); VmExitReason exitReason = VmExitReason.forValue(rs.getInt("exit_reason")); entity.setExitReason(exitReason); entity.setGuestCpuCount(rs.getInt("guest_cpu_count")); entity.setEmulatedMachine(rs.getString("emulated_machine")); setGraphicsToEntity(rs, entity); entity.setGuestOsTimezoneOffset(rs.getInt("guest_timezone_offset")); entity.setGuestOsTimezoneName(rs.getString("guest_timezone_name")); entity.setGuestOsArch(rs.getInt("guestos_arch")); entity.setGuestOsCodename(rs.getString("guestos_codename")); entity.setGuestOsDistribution(rs.getString("guestos_distribution")); entity.setGuestOsKernelVersion(rs.getString("guestos_kernel_version")); entity.setGuestOsType(rs.getString("guestos_type")); entity.setGuestOsVersion(rs.getString("guestos_version")); entity.setGuestContainers(fromContainersString(rs.getString("guest_containers"))); return entity; }; private static void setGraphicsToEntity(ResultSet rs, VmDynamic entity) throws SQLException { GraphicsInfo graphicsInfo = new GraphicsInfo(); graphicsInfo.setIp(rs.getString("spice_ip")); graphicsInfo.setPort((Integer) rs.getObject("spice_port")); graphicsInfo.setTlsPort((Integer) rs.getObject("spice_tls_port")); if (graphicsInfo.getPort() != null || graphicsInfo.getTlsPort() != null) { entity.getGraphicsInfos().put(GraphicsType.SPICE, graphicsInfo); } graphicsInfo = new GraphicsInfo(); graphicsInfo.setIp(rs.getString("vnc_ip")); graphicsInfo.setPort((Integer) rs.getObject("vnc_port")); if (graphicsInfo.getPort() != null) { entity.getGraphicsInfos().put(GraphicsType.VNC, graphicsInfo); } } protected static RowMapper<VmDynamic> getRowMapper() { return vmDynamicRowMapper; } }