package org.ovirt.engine.core.dao;
import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import javax.inject.Named;
import javax.inject.Singleton;
import org.apache.commons.lang.StringUtils;
import org.ovirt.engine.core.common.VdcObjectType;
import org.ovirt.engine.core.common.action.VdcActionParametersBase;
import org.ovirt.engine.core.common.action.VdcActionType;
import org.ovirt.engine.core.common.action.VdcReturnValueBase;
import org.ovirt.engine.core.common.businessentities.CommandAssociatedEntity;
import org.ovirt.engine.core.common.businessentities.CommandEntity;
import org.ovirt.engine.core.common.utils.PersistedCommandContext;
import org.ovirt.engine.core.compat.CommandStatus;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.dal.dbbroker.CustomMapSqlParameterSource;
import org.ovirt.engine.core.dal.dbbroker.DbFacadeUtils;
import org.ovirt.engine.core.dal.dbbroker.MapSqlParameterMapper;
import org.ovirt.engine.core.utils.ReflectionUtils;
import org.ovirt.engine.core.utils.SerializationFactory;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
@Named
@Singleton
public class CommandEntityDaoImpl extends DefaultGenericDao<CommandEntity, Guid> implements CommandEntityDao {
private static final RowMapper<Guid> idRowMapper = (rs, rowNum) -> getGuidDefaultEmpty(rs, "id");
private static final RowMapper<CommandAssociatedEntity> coCoCmdEntityRowMapper = (rs, rowNum) -> {
CommandAssociatedEntity entity = new CommandAssociatedEntity(getGuid(rs, "command_id"),
VdcObjectType.valueOf(rs.getString("entity_type")),
getGuid(rs, "entity_id"));
entity.setEntityType(VdcObjectType.valueOf(rs.getString("entity_type")));
return entity;
};
private static RowMapper<CommandEntity> mapper = (resultSet, rowNum) -> {
CommandEntity result = new CommandEntity();
result.setEngineSessionSeqId(resultSet.getLong("engine_session_seq_id"));
result.setUserId(Guid.createGuidFromString(resultSet.getString("user_id")));
result.setId(Guid.createGuidFromString(resultSet.getString("command_id")));
result.setCommandContext(SerializationFactory.getDeserializer().deserialize(
resultSet.getString("command_context"), PersistedCommandContext.class));
result.setCreatedAt(DbFacadeUtils.fromDate(resultSet.getTimestamp("created_at")));
result.setCommandType(VdcActionType.forValue(resultSet.getInt("command_type")));
result.setParentCommandId(Guid.createGuidFromString(resultSet.getString("parent_command_id")));
result.setRootCommandId(Guid.createGuidFromString(resultSet.getString("root_command_id")));
result.setCommandParameters(deserializeParameters(resultSet.getString("command_parameters"), resultSet.getString("command_params_class")));
result.setReturnValue(deserializeReturnValue(resultSet.getString("return_value"), resultSet.getString("return_value_class")));
result.setCommandStatus(getCommandStatus(resultSet.getString("status")));
result.setExecuted(resultSet.getBoolean("executed"));
result.setCallbackEnabled(resultSet.getBoolean("callback_enabled"));
result.setCallbackNotified(resultSet.getBoolean("callback_notified"));
result.setData(SerializationFactory.getDeserializer().deserialize(resultSet.getString("data"), HashMap.class));
return result;
};
private MapSqlParameterMapper<CommandAssociatedEntity> cocoCmdEntityMapper = entity -> {
CustomMapSqlParameterSource paramSource = getCustomMapSqlParameterSource();
paramSource.addValue("command_id", entity.getCommandId()).
addValue("entity_id", entity.getEntityId()).
addValue("entity_type", entity.getEntityType().toString());
return paramSource;
};
private static CommandStatus getCommandStatus(String statusStr) {
CommandStatus status = CommandStatus.UNKNOWN;
if (!StringUtils.isEmpty(statusStr)) {
status = CommandStatus.valueOf(statusStr);
}
return status;
}
public CommandEntityDaoImpl() {
super("CommandEntity");
setProcedureNameForGetAll("GetAllFromCommandEntities");
}
@Override
protected MapSqlParameterSource createFullParametersMapper(CommandEntity entity) {
return getCustomMapSqlParameterSource().addValue("engine_session_seq_id", entity.getEngineSessionSeqId())
.addValue("user_id", Guid.isNullOrEmpty(entity.getUserId()) ? Guid.Empty : entity.getUserId())
.addValue("command_id", Guid.isNullOrEmpty(entity.getId()) ? Guid.Empty : entity.getId())
.addValue("command_type", entity.getCommandType().getValue())
.addValue("parent_command_id", entity.getParentCommandId())
.addValue("root_command_id", Guid.isNullOrEmpty(entity.getRootCommandId()) ? Guid.Empty : entity.getRootCommandId())
.addValue("command_context", SerializationFactory.getSerializer().serialize(entity.getCommandContext()))
.addValue("command_parameters", serializeParameters(entity.getCommandParameters()))
.addValue("command_params_class", entity.getCommandParameters() == null ? null : entity.getCommandParameters().getClass().getName())
.addValue("created_at", entity.getCreatedAt())
.addValue("status", entity.getCommandStatus().toString())
.addValue("executed", entity.isExecuted())
.addValue("callback_enabled", entity.isCallbackEnabled())
.addValue("return_value", serializeReturnValue(entity.getReturnValue()))
.addValue("return_value_class", entity.getReturnValue() == null ? null : entity.getReturnValue().getClass().getName())
.addValue("data", SerializationFactory.getSerializer().serialize(entity.getData()));
}
private String serializeReturnValue(VdcReturnValueBase retVal) {
return SerializationFactory.getSerializer().serialize(retVal);
}
private String serializeParameters(VdcActionParametersBase params) {
return SerializationFactory.getSerializer().serialize(params);
}
@SuppressWarnings("unchecked")
private static VdcReturnValueBase deserializeReturnValue(String payload, String className) {
if (className == null) {
return null;
}
Class<Serializable> retValueClass = (Class<Serializable>) ReflectionUtils.getClassFor(className);
return (VdcReturnValueBase) SerializationFactory.getDeserializer().deserialize(payload,
retValueClass);
}
@SuppressWarnings("unchecked")
private static VdcActionParametersBase deserializeParameters(String payload, String className) {
if (className == null) {
return null;
}
Class<Serializable> actionParamsClass = (Class<Serializable>) ReflectionUtils.getClassFor(className);
return (VdcActionParametersBase) SerializationFactory.getDeserializer().deserialize(payload,
actionParamsClass);
}
@Override
protected MapSqlParameterSource createIdParameterMapper(Guid id) {
return getCustomMapSqlParameterSource().addValue("command_id", id);
}
@Override
protected RowMapper<CommandEntity> createEntityRowMapper() {
return mapper;
}
@Override
public void saveOrUpdate(CommandEntity commandEntity) {
MapSqlParameterSource parameterSource = createFullParametersMapper(commandEntity);
getCallsHandler().executeModification("InsertOrUpdateCommandEntity", parameterSource);
}
@Override
public void updateStatus(Guid id, CommandStatus status) {
getCallsHandler().executeModification("UpdateCommandEntityStatus", createIdParameterMapper(id).addValue("status", status.toString()));
}
@Override
public void updateNotified(Guid id) {
getCallsHandler().executeModification("UpdateCommandEntityNotified", createIdParameterMapper(id).addValue("callback_notified", true));
}
@Override
public void updateExecuted(Guid id) {
getCallsHandler().executeModification("UpdateCommandEntityExecuted", createIdParameterMapper(id).addValue("executed", true));
}
@Override
public void removeAllBeforeDate(Date cutoff) {
MapSqlParameterSource parameterSource = getCustomMapSqlParameterSource()
.addValue("date", cutoff);
getCallsHandler().executeModification("DeleteCommandEntitiesOlderThanDate", parameterSource);
}
@Override
public List<CommandEntity> getCmdEntitiesByParentCmdId(Guid parentId) {
MapSqlParameterSource parameterSource = getCustomMapSqlParameterSource()
.addValue("root_command_id", parentId);
return getCallsHandler().executeReadList("GetCommandEntitiesByParentCmdId",
mapper,
parameterSource);
}
@Override
public List<Guid> getCommandIdsByEntity(Guid entityId) {
MapSqlParameterSource parameterSource = getCustomMapSqlParameterSource()
.addValue("entity_id", entityId);
return getCallsHandler().executeReadList("GetCommandIdsByEntityId",
idRowMapper,
parameterSource);
}
public void insertCommandAssociatedEntities(Collection<CommandAssociatedEntity> cmdAssociatedEntities) {
getCallsHandler().executeStoredProcAsBatch("InsertCommandAssociatedEntities",
cmdAssociatedEntities,
cocoCmdEntityMapper);
}
@Override
public List<CommandAssociatedEntity> getAllCommandAssociatedEntities(Guid cmdId) {
MapSqlParameterSource parameterSource = getCustomMapSqlParameterSource()
.addValue("command_id", cmdId);
return getCallsHandler().executeReadList("GetCommandAssociatedEntities",
coCoCmdEntityRowMapper,
parameterSource);
}
}