//Dstl (c) Crown Copyright 2017
package uk.gov.dstl.baleen.resources;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Map;
import org.apache.uima.fit.descriptor.ConfigurationParameter;
import org.apache.uima.resource.ResourceInitializationException;
import org.apache.uima.resource.ResourceSpecifier;
import com.google.common.base.Strings;
import uk.gov.dstl.baleen.core.utils.ConfigUtils;
import uk.gov.dstl.baleen.exceptions.BaleenException;
import uk.gov.dstl.baleen.uima.BaleenResource;
/**
* <b>Shared resource for accessing PostgreSQL</b>
* <p>
* This resource removes the need for individual annotators to establish their
* own connections to PostgreSQL, instead providing a single JDBC Connection for
* Baleen that can be used. This provides benefits such as reduced
* configuration, reduced repeated code, and support for connection pooling.</p>
*
*
* @baleen.javadoc
*/
public class SharedPostgresResource extends BaleenResource {
/**
* The host to connect to PostgreSQL on
*
* @baleen.config localhost
*/
public static final String PARAM_HOST = "postgres.host";
@ConfigurationParameter(name = PARAM_HOST, defaultValue="localhost")
private String postgresqlHost;
/**
* The port to connect to PostgreSQL on
*
* @baleen.config 5432
*/
public static final String PARAM_PORT = "postgres.port";
@ConfigurationParameter(name = PARAM_PORT, defaultValue="5432")
private String postgresqlPortString;
//Parse the port config parameter into this variable to avoid issues with parameter types
private int postgresqlPort;
/**
* The PostgreSQL database to connect to
*
* @baleen.config baleen
*/
public static final String PARAM_DB = "postgres.db";
@ConfigurationParameter(name = PARAM_DB, defaultValue="baleen")
private String postgresqlDb;
/**
* The username to use for authentication.
* If left blank, then authentication will not be used.
*
* @baleen.config
*/
public static final String PARAM_USER = "postgres.user";
@ConfigurationParameter(name = PARAM_USER, defaultValue="")
private String postgresqlUser;
/**
* The password to use for authentication.
* If left blank, then authentication will not be used.
*
* @baleen.config
*/
public static final String PARAM_PASS = "postgres.pass";
@ConfigurationParameter(name = PARAM_PASS, defaultValue="")
private String postgresqlPass;
private Connection connection = null;
@Override
protected boolean doInitialize(ResourceSpecifier aSpecifier, Map<String, Object> aAdditionalParams) throws ResourceInitializationException {
postgresqlPort = ConfigUtils.stringToInteger(postgresqlPortString, 5432);
try{
Class.forName("org.postgresql.Driver");
}catch(ClassNotFoundException e){
getMonitor().error("Couldn't find PostgreSQL JDBC Driver", e);
throw new ResourceInitializationException(e);
}
try{
if(!Strings.isNullOrEmpty(postgresqlUser) && !Strings.isNullOrEmpty(postgresqlPass)){
connection = DriverManager.getConnection(getJdbcString(), postgresqlUser, postgresqlPass);
}else{
connection = DriverManager.getConnection(getJdbcString());
}
if(connection == null){
throw new BaleenException("Couldn't establish PostgreSQL connection");
}
}catch(SQLException | BaleenException e){
getMonitor().error("Couldn't establish PostgreSQL connection", e);
throw new ResourceInitializationException(e);
}
return true;
}
@Override
protected void doDestroy() {
if(connection != null){
try {
connection.close();
} catch (SQLException e) {
getMonitor().debug("Failed to close PostgreSQL Connection", e);
// Do nothing
}
connection = null;
}
}
/**
* Get the JDBC String for this connection
*/
public String getJdbcString(){
return "jdbc:postgresql://" + postgresqlHost + ":" + postgresqlPort + "/" + postgresqlDb;
}
/**
* Get the JDBC connection
*/
public Connection getConnection(){
return connection;
}
}