package org.ovirt.engine.core.dal.dbbroker;
import java.io.IOException;
import java.util.Properties;
import javax.annotation.Resource;
import javax.enterprise.inject.Produces;
import javax.inject.Singleton;
import javax.sql.DataSource;
import org.ovirt.engine.core.utils.EngineLocalConfig;
import org.ovirt.engine.core.utils.ResourceUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.support.SQLExceptionTranslator;
/**
* A locator singleton for looking up (and initializing) DbFacade instance
*/
@Singleton
public class DbFacadeLocator {
private static final Logger log = LoggerFactory.getLogger(DbFacadeLocator.class);
// Default values for the configuration (these will be replaced with the
// values from the configuration file):
private static final int DEFAULT_CHECK_INTERVAL = 5000;
private static final int DEFAULT_CONNECTION_TIMEOUT = 30000;
// Time to wait between checks of the database connection and maximum time
// to wait for a connection:
private int checkInterval = DEFAULT_CHECK_INTERVAL;
private int connectionTimeout = DEFAULT_CONNECTION_TIMEOUT;
@Resource(mappedName = "java:/ENGINEDataSource")
@Produces
private DataSource dataSource;
@Produces
@Singleton
public JdbcTemplate produceJdbcTemplate(
DataSource dataSource,
DbEngineDialect dbEngineDialect,
SQLExceptionTranslator sqlExceptionTranslator) {
final JdbcTemplate jdbcTemplate = dbEngineDialect.createJdbcTemplate(dataSource);
jdbcTemplate.setExceptionTranslator(sqlExceptionTranslator);
return jdbcTemplate;
}
@Produces
@Singleton
public DbEngineDialect produceDbEngineDialect() {
return loadDbEngineDialect();
}
@Produces
@Singleton
public DbConnectionUtil produceDbConnectionUtil(JdbcTemplate jdbcTemplate) {
loadDbFacadeConfig();
return new DbConnectionUtil(jdbcTemplate, connectionTimeout, checkInterval);
}
DbFacadeLocator() {
}
/**
* Generate and sets the database engine dialect object according to configuration.
*
* @throws IllegalStateException If one of the expected properties is not present.
*/
public static DbEngineDialect loadDbEngineDialect() {
final String ENGINE_DB_ENGINE_PROPERTIES = "engine-db-engine.properties";
final String DIALECT = "DbEngineDialect";
final Properties props;
try {
props = ResourceUtils.loadProperties(DbFacadeLocator.class, ENGINE_DB_ENGINE_PROPERTIES);
}
catch (IOException exception) {
throw new IllegalStateException(
"Can't load properties from resource \"" +
ENGINE_DB_ENGINE_PROPERTIES + "\".", exception
);
}
String dialect = props.getProperty(DIALECT);
if (dialect == null) {
throw new IllegalStateException(
"Can't load property \"" + DIALECT + "\" from resource \"" +
ENGINE_DB_ENGINE_PROPERTIES + "\"."
);
}
try {
return (DbEngineDialect) Class.forName(dialect).newInstance();
}
catch (Exception exception) {
throw new IllegalStateException(
"Can't create instance of dialect class \"" + dialect + "\".",
exception
);
}
}
private void loadDbFacadeConfig() {
final EngineLocalConfig config = EngineLocalConfig.getInstance();
try {
connectionTimeout = config.getInteger("ENGINE_DB_CONNECTION_TIMEOUT");
checkInterval = config.getInteger("ENGINE_DB_CHECK_INTERVAL");
}
catch (Exception exception) {
log.warn("Can't load connection checking parameters of DB facade, "
+ "will continue using the default values. Error: {}",
exception.getMessage());
log.debug("Exception", exception);
}
}
}