diff --git a/src/org/jgroups/protocols/JDBC_PING.java b/src/org/jgroups/protocols/JDBC_PING.java
index b11cf75a30..ec1e4c2f53 100644
--- a/src/org/jgroups/protocols/JDBC_PING.java
+++ b/src/org/jgroups/protocols/JDBC_PING.java
@@ -10,6 +10,7 @@
import javax.sql.DataSource;
import java.sql.*;
import java.util.List;
+import java.util.function.Function;
/**
*
Discovery protocol using a JDBC connection to a shared database.
@@ -83,6 +84,10 @@ public class JDBC_PING extends FILE_PING {
"properties must be empty.")
protected String datasource_jndi_name;
+ @Property(description="The fully qualified name of a class which implements a Function. " +
+ "If not null, this has precedence over datasource_jndi_name.")
+ protected String datasource_injecter_class;
+
/* --------------------------------------------- Fields ------------------------------------------------------ */
protected DataSource dataSource;
@@ -92,20 +97,52 @@ public class JDBC_PING extends FILE_PING {
; // do *not* create root file system (don't remove !)
}
- public JDBC_PING setDataSource(DataSource dataSource) {
- this.dataSource = dataSource; return this;
- }
+ public JDBC_PING setDataSource(DataSource ds) {this.dataSource=ds; return this;}
+ public DataSource getDataSource() {return dataSource;}
+ public String getConnectionUrl() {return connection_url;}
+ public JDBC_PING setConnectionUrl(String c) {this.connection_url=c; return this;}
+ public String getConnectionUsername() {return connection_username;}
+ public JDBC_PING setConnectionUsername(String c) {this.connection_username=c; return this;}
+ public String getConnectionPassword() {return connection_password;}
+ public JDBC_PING setConnectionPassword(String c) {this.connection_password=c; return this;}
+ public String getConnectionDriver() {return connection_driver;}
+ public JDBC_PING setConnectionDriver(String c) {this.connection_driver=c; return this;}
+ public String getInitializeSql() {return initialize_sql;}
+ public JDBC_PING setInitializeSql(String i) {this.initialize_sql=i; return this;}
+ public String getInsertSingleSql() {return insert_single_sql;}
+ public JDBC_PING setInsertSingleSql(String i) {this.insert_single_sql=i; return this;}
+ public String getDeleteSingleSql() {return delete_single_sql;}
+ public JDBC_PING setDeleteSingleSql(String d) {this.delete_single_sql=d; return this;}
+ public String getClearSql() {return clear_sql;}
+ public JDBC_PING setClearSql(String c) {this.clear_sql=c; return this;}
+ public String getSelectAllPingdataSql() {return select_all_pingdata_sql;}
+ public JDBC_PING setSelectAllPingdataSql(String s) {this.select_all_pingdata_sql=s; return this;}
+ public String getContainsSql() {return contains_sql;}
+ public JDBC_PING setContainsSql(String c) {this.contains_sql=c; return this;}
+ public String getDatasourceJndiName() {return datasource_jndi_name;}
+ public JDBC_PING setDatasourceJndiName(String d) {this.datasource_jndi_name=d; return this;}
+ public String getDatasourceInjecterClass() {return datasource_injecter_class;}
+ public JDBC_PING setDatasourceInjecterClass(String d) {this.datasource_injecter_class=d; return this;}
+
@Override
public void init() throws Exception {
super.init();
verifyConfigurationParameters();
// If dataSource is already set, skip loading driver or JNDI lookup
- if (dataSource == null) {
- if (stringIsEmpty(datasource_jndi_name)) {
- loadDriver();
- } else {
- dataSource = getDataSourceFromJNDI(datasource_jndi_name.trim());
+ if(dataSource == null) {
+ if(datasource_injecter_class != null) {
+ dataSource=injectDataSource(datasource_injecter_class);
+ if(dataSource == null) {
+ String m=String.format("datasource_injecter_class %s created null datasource", datasource_injecter_class);
+ throw new IllegalArgumentException(m);
+ }
+ }
+ else {
+ if(datasource_jndi_name != null)
+ dataSource=getDataSourceFromJNDI(datasource_jndi_name.trim());
+ else
+ loadDriver();
}
}
attemptSchemaInitialization();
@@ -243,8 +280,8 @@ protected void readAll(Connection connection, List members, String clus
protected void attemptSchemaInitialization() {
- if(stringIsEmpty(initialize_sql)) {
- log.debug("Table creation step skipped: initialize_sql property is missing");
+ if(initialize_sql == null) {
+ log.debug("Table creation step skipped: initialize_sql attribute is missing");
return;
}
Connection connection=getConnection();
@@ -267,17 +304,24 @@ protected void attemptSchemaInitialization() {
}
protected void loadDriver() {
- if (stringIsEmpty(connection_driver))
- return;
- log.debug("Registering JDBC Driver named '%s'", connection_driver);
+ assertNonNull("connection_driver", connection_driver);
+ log.debug("Registering JDBC driver %s", connection_driver);
try {
Util.loadClass(connection_driver, this.getClass().getClassLoader());
- } catch (ClassNotFoundException e) {
- throw new IllegalArgumentException("JDBC Driver required for JDBC_PING "
- + " protocol could not be loaded: '" + connection_driver + "'");
}
+ catch (ClassNotFoundException e) {
+ throw new IllegalArgumentException(String.format("JDBC driver could not be loaded: '%s'", connection_driver));
+ }
+ }
+
+ protected DataSource injectDataSource(String ds_class) throws Exception {
+ Class> cl=Util.loadClass(ds_class, Thread.currentThread().getContextClassLoader());
+ Object obj=cl.getConstructor().newInstance();
+ Function fun=(Function)obj;
+ return fun.apply(this);
}
+ // todo: check if connections should be cached (connection pool?)
protected Connection getConnection() {
if (dataSource == null) {
Connection connection;
@@ -407,43 +451,22 @@ protected DataSource getDataSourceFromJNDI(String name) {
}
protected void verifyConfigurationParameters() {
- // Skip if datasource is already provided via integration code (e.g. WildFly)
- if (dataSource == null) {
- if (stringIsEmpty(this.connection_url) ||
- stringIsEmpty(this.connection_driver) ||
- stringIsEmpty(this.connection_username)) {
- if (stringIsEmpty(this.datasource_jndi_name)) {
- throw new IllegalArgumentException("Either the 4 configuration properties starting with 'connection_' or the datasource_jndi_name must be set");
- }
- }
- if (stringNotEmpty(this.connection_url) ||
- stringNotEmpty(this.connection_driver) ||
- stringNotEmpty(this.connection_username)) {
- if (stringNotEmpty(this.datasource_jndi_name)) {
- throw new IllegalArgumentException("When using the 'datasource_jndi_name' configuration property, all properties starting with 'connection_' must not be set");
- }
- }
- }
- if (stringIsEmpty(this.insert_single_sql)) {
- throw new IllegalArgumentException("The insert_single_sql configuration property is mandatory");
- }
- if (stringIsEmpty(this.delete_single_sql)) {
- throw new IllegalArgumentException("The delete_single_sql configuration property is mandatory");
- }
- if (stringIsEmpty(this.select_all_pingdata_sql)) {
- throw new IllegalArgumentException("The select_all_pingdata_sql configuration property is mandatory");
- }
- }
-
- private static boolean stringIsEmpty(final String value) {
- return value == null || value.trim().isEmpty();
+ // initialize_sql is skipped as the table could be created external to JDBC_PING
+ assertNonNull("insert_single_sql", insert_single_sql,
+ "clear_sql", clear_sql,
+ "delete_single_sql", delete_single_sql,
+ "select_all_pingdata_sql", select_all_pingdata_sql,
+ "contains_sql", contains_sql);
}
- private static boolean stringNotEmpty(final String value) {
- return !stringIsEmpty(value);
+ protected static void assertNonNull(String... strings) {
+ for(int i=0; i < strings.length; i+=2) {
+ String attr=strings[i], val=strings[i+1];
+ if(val == null)
+ throw new IllegalArgumentException(String.format("%s must not be null", attr));
+ }
}
-
public static void main(String[] args) throws ClassNotFoundException {
String driver="org.hsqldb.jdbcDriver";
String user="SA";