Displaying differences for changeset
 
display as  

src/java/m/rse/cfactor/utils/PGTools.java

@@ -14,6 +14,7 @@
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import javax.sql.DataSource;
@@ -30,17 +31,50 @@
  */
 public class PGTools {
 
-    private static DataSource datasource;
-    private static DataSource ssurgoDatasource;
-    private static String connectionString;
-    private static String ssurgoConnectionString;
+    private static ConcurrentHashMap<String, DataSource> dataSources = new ConcurrentHashMap<>();
+    private static ConcurrentHashMap<String, String> connectionStrings = new ConcurrentHashMap<>(); 
 
     static final Logger logger = Logger.getLogger(PGTools.class.getName());
 
-    public static synchronized Connection getConnection() throws SQLException {
+    public static synchronized Connection getConnection() throws csip.ServiceException  {
     return getConnection(PGTools.class.toString(), logger);
     }
+    
+    public static synchronized Connection getConnection(String className, Logger logger) throws csip.ServiceException {
+    Connection ret_val = null;
+    boolean debugging = Boolean.parseBoolean(Config.getString("debugging", "false"));
 
+    if (null != className) {
+        
+        //Don't need to synchronize() around these calls because they are already in a synchronized member
+        if (!connectionStrings.containsKey(className)) {
+        connectionStrings.put(className, Config.getString((debugging ? className.toLowerCase() + ".debug.db" : className.toLowerCase() + ".db")));
+        }
+
+        if (connectionStrings.get(className) == null || connectionStrings.get(className).isEmpty()) {
+        if (logger != null) {
+            logger.log(Level.SEVERE, "Connection string not provided.  Please configure wqm.db configuration parameter.");
+        }
+        throw new csip.ServiceException("Unable to connect to RSE database.  Please check the " + (debugging ? className.toLowerCase() + ".debug.db" : className.toLowerCase() + ".db") + " configuration parameter");
+        }
+
+        try {
+        if (!dataSources.containsKey(className))  {
+            createDataSource(className, Config.getString(className + ".db.driver", "org.postgresql.Driver"), logger);
+        }
+
+        ret_val = dataSources.get(className).getConnection();
+        } catch (SQLException ex) {
+        if (logger != null) {
+            logger.log(Level.SEVERE, null, ex);
+        }
+        throw new csip.ServiceException("Failed to connect to RSE database.  Please check the " + className + " configuration parameter");
+        }
+    }
+    return ret_val;
+    }
+
+/*    
     public static synchronized Connection getConnection(String className, Logger logger) throws SQLException {
     Connection ret_val = null;
     String confString = Config.getString(className + ".db", "");
@@ -64,8 +98,8 @@
             PoolProperties p = new PoolProperties();
             p.setUrl(ssurgoConnectionString);
             p.setDefaultAutoCommit(false);
-            p.setUsername("postgres");
-            p.setPassword("admin");
+            //p.setUsername("postgres");
+            //p.setPassword("admin");
             p.setDriverClassName("org.postgresql.Driver");
             p.setJmxEnabled(false);
             p.setTestOnBorrow(true);
@@ -138,6 +172,33 @@
 
     return ret_val;
     }
+*/
+    
+    //Doesn't 'need' to be synchronized because it should only be called by getConnection() which is synchronized, 
+    //  but just in case someone tries calling it elsewhere within this class at a later date...leave it synchronized.
+    private static synchronized void createDataSource(String className, String DriverClassName, Logger logger) throws SQLException {
+    PoolProperties p = new PoolProperties();
+    p.setUrl(connectionStrings.get(className));
+    p.setDriverClassName(DriverClassName);
+    p.setDefaultAutoCommit(false);    
+    p.setJmxEnabled(false);
+    p.setTestOnBorrow(true);
+    p.setValidationQuery("SELECT 1");
+    p.setTestOnReturn(false);
+    p.setValidationInterval(30000);
+    p.setTimeBetweenEvictionRunsMillis(30000);
+    p.setMaxWait(10000);
+    p.setRemoveAbandonedTimeout(10);
+    p.setRemoveAbandoned(true);
+    p.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"
+        + "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer;"
+        + "org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer");
+
+    dataSources.put(className, new org.apache.tomcat.jdbc.pool.DataSource(p));
+    if (logger != null) {
+        logger.log(Level.INFO, "\nCreated datasource {0}", dataSources.get(className).toString());
+    }
+    }
     
     
 //Probably won't ever need this function if we continue to use try-with blocks.
@@ -146,7 +207,7 @@
 //structure is set to allow abandoned connections to be closed by the underlying apache tomcat system
 //Thus, connections that for some strange reason have not been closed after 15 minutes would be automatically closed.
 //The 15 minutes is configurable via the setRemoveAbandonedTimeout() member function of the poolProperties.
-    
+/*    
     public static void shutdownDataSource() { 
     if (datasource != null && datasource instanceof DataSourceProxy) {
         DataSourceProxy proxy = (DataSourceProxy) datasource;
@@ -161,7 +222,7 @@
         System.out.println("Closed SSURGO datasource.");
     }
     }
-
+*/
     public static class PolygonLatLon {
 
     private ArrayList<PGTools.PolygonLatLon.PointLatLon> points;