java/sql-dk/src/info/globalcode/sql/dk/configuration/Loader.java
author František Kučera <franta-hg@frantovo.cz>
Tue, 26 Feb 2019 18:19:49 +0100
branchv_0
changeset 236 a3ec71fa8e17
parent 196 76da38d49e81
permissions -rw-r--r--
Avoid reusing/rewriting the DB connection properties. There was weird random errors while testing connection to multiple DB in parallel when one of them was meta connection to same DB connection. Two kinds of exception: 1) missing password 2) „Passing DB password as CLI parameter is insecure!“
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16
5b8fcd35d4d6 license: GNU GPLv3+
František Kučera <franta-hg@frantovo.cz>
parents: 15
diff changeset
     1
/**
5b8fcd35d4d6 license: GNU GPLv3+
František Kučera <franta-hg@frantovo.cz>
parents: 15
diff changeset
     2
 * SQL-DK
189
f4d879cbcee1 separate configuration loading into the Loader class
František Kučera <franta-hg@frantovo.cz>
parents: 179
diff changeset
     3
 * Copyright © 2015 František Kučera (frantovo.cz)
16
5b8fcd35d4d6 license: GNU GPLv3+
František Kučera <franta-hg@frantovo.cz>
parents: 15
diff changeset
     4
 *
5b8fcd35d4d6 license: GNU GPLv3+
František Kučera <franta-hg@frantovo.cz>
parents: 15
diff changeset
     5
 * This program is free software: you can redistribute it and/or modify
5b8fcd35d4d6 license: GNU GPLv3+
František Kučera <franta-hg@frantovo.cz>
parents: 15
diff changeset
     6
 * it under the terms of the GNU General Public License as published by
5b8fcd35d4d6 license: GNU GPLv3+
František Kučera <franta-hg@frantovo.cz>
parents: 15
diff changeset
     7
 * the Free Software Foundation, either version 3 of the License, or
5b8fcd35d4d6 license: GNU GPLv3+
František Kučera <franta-hg@frantovo.cz>
parents: 15
diff changeset
     8
 * (at your option) any later version.
5b8fcd35d4d6 license: GNU GPLv3+
František Kučera <franta-hg@frantovo.cz>
parents: 15
diff changeset
     9
 *
5b8fcd35d4d6 license: GNU GPLv3+
František Kučera <franta-hg@frantovo.cz>
parents: 15
diff changeset
    10
 * This program is distributed in the hope that it will be useful,
5b8fcd35d4d6 license: GNU GPLv3+
František Kučera <franta-hg@frantovo.cz>
parents: 15
diff changeset
    11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
5b8fcd35d4d6 license: GNU GPLv3+
František Kučera <franta-hg@frantovo.cz>
parents: 15
diff changeset
    12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5b8fcd35d4d6 license: GNU GPLv3+
František Kučera <franta-hg@frantovo.cz>
parents: 15
diff changeset
    13
 * GNU General Public License for more details.
5b8fcd35d4d6 license: GNU GPLv3+
František Kučera <franta-hg@frantovo.cz>
parents: 15
diff changeset
    14
 *
5b8fcd35d4d6 license: GNU GPLv3+
František Kučera <franta-hg@frantovo.cz>
parents: 15
diff changeset
    15
 * You should have received a copy of the GNU General Public License
5b8fcd35d4d6 license: GNU GPLv3+
František Kučera <franta-hg@frantovo.cz>
parents: 15
diff changeset
    16
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
5b8fcd35d4d6 license: GNU GPLv3+
František Kučera <franta-hg@frantovo.cz>
parents: 15
diff changeset
    17
 */
189
f4d879cbcee1 separate configuration loading into the Loader class
František Kučera <franta-hg@frantovo.cz>
parents: 179
diff changeset
    18
package info.globalcode.sql.dk.configuration;
1
f32dac78d13a WOW some classes LOL; TODO: refactor
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    19
189
f4d879cbcee1 separate configuration loading into the Loader class
František Kučera <franta-hg@frantovo.cz>
parents: 179
diff changeset
    20
import info.globalcode.sql.dk.*;
192
a32bfcbdee51 jdbc-dk-driver: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 189
diff changeset
    21
import static info.globalcode.sql.dk.DatabaseConnection.JDBC_PROPERTY_USER;
a32bfcbdee51 jdbc-dk-driver: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 189
diff changeset
    22
import static info.globalcode.sql.dk.DatabaseConnection.JDBC_PROPERTY_PASSWORD;
a32bfcbdee51 jdbc-dk-driver: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 189
diff changeset
    23
import java.sql.Connection;
194
629c9c7eab01 JDBC driver class can be specified in the database configuration as an optional parameter (useful especially while embedding jdbc-dk-driver into other application that does not support automatic driver discovery)
František Kučera <franta-hg@frantovo.cz>
parents: 193
diff changeset
    24
import java.sql.Driver;
192
a32bfcbdee51 jdbc-dk-driver: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 189
diff changeset
    25
import java.sql.DriverManager;
a32bfcbdee51 jdbc-dk-driver: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 189
diff changeset
    26
import java.sql.SQLException;
a32bfcbdee51 jdbc-dk-driver: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 189
diff changeset
    27
import java.util.logging.Level;
a32bfcbdee51 jdbc-dk-driver: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 189
diff changeset
    28
import java.util.logging.Logger;
33
04db6ccd6c48 configuration loading from XML
František Kučera <franta-hg@frantovo.cz>
parents: 26
diff changeset
    29
import javax.xml.bind.JAXBContext;
04db6ccd6c48 configuration loading from XML
František Kučera <franta-hg@frantovo.cz>
parents: 26
diff changeset
    30
import javax.xml.bind.Unmarshaller;
13
599aad77e986 fix: try/catch
František Kučera <franta-hg@frantovo.cz>
parents: 5
diff changeset
    31
1
f32dac78d13a WOW some classes LOL; TODO: refactor
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    32
/**
189
f4d879cbcee1 separate configuration loading into the Loader class
František Kučera <franta-hg@frantovo.cz>
parents: 179
diff changeset
    33
 * Configuration loader – deserializes Configuration from the XML file.
1
f32dac78d13a WOW some classes LOL; TODO: refactor
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    34
 *
f32dac78d13a WOW some classes LOL; TODO: refactor
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    35
 * @author Ing. František Kučera (frantovo.cz)
f32dac78d13a WOW some classes LOL; TODO: refactor
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    36
 */
189
f4d879cbcee1 separate configuration loading into the Loader class
František Kučera <franta-hg@frantovo.cz>
parents: 179
diff changeset
    37
public class Loader {
20
e225bdcd260e refactor, configuration
František Kučera <franta-hg@frantovo.cz>
parents: 17
diff changeset
    38
192
a32bfcbdee51 jdbc-dk-driver: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 189
diff changeset
    39
	private static final Logger log = Logger.getLogger(Loader.class.getName());
a32bfcbdee51 jdbc-dk-driver: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 189
diff changeset
    40
189
f4d879cbcee1 separate configuration loading into the Loader class
František Kučera <franta-hg@frantovo.cz>
parents: 179
diff changeset
    41
	public Configuration loadConfiguration() throws ConfigurationException {
33
04db6ccd6c48 configuration loading from XML
František Kučera <franta-hg@frantovo.cz>
parents: 26
diff changeset
    42
		try {
193
5a18a6adf7f9 configuration loading: use JAXB index and set classloader (useful while embedding into Netbeans and other applications)
František Kučera <franta-hg@frantovo.cz>
parents: 192
diff changeset
    43
			JAXBContext jaxb = JAXBContext.newInstance(Configuration.class.getPackage().getName(), Configuration.class.getClassLoader());
33
04db6ccd6c48 configuration loading from XML
František Kučera <franta-hg@frantovo.cz>
parents: 26
diff changeset
    44
			Unmarshaller u = jaxb.createUnmarshaller();
04db6ccd6c48 configuration loading from XML
František Kučera <franta-hg@frantovo.cz>
parents: 26
diff changeset
    45
			return (Configuration) u.unmarshal(Constants.CONFIG_FILE);
04db6ccd6c48 configuration loading from XML
František Kučera <franta-hg@frantovo.cz>
parents: 26
diff changeset
    46
		} catch (Exception e) {
04db6ccd6c48 configuration loading from XML
František Kučera <franta-hg@frantovo.cz>
parents: 26
diff changeset
    47
			throw new ConfigurationException("Unable to load configuration from " + Constants.CONFIG_FILE, e);
04db6ccd6c48 configuration loading from XML
František Kučera <franta-hg@frantovo.cz>
parents: 26
diff changeset
    48
		}
20
e225bdcd260e refactor, configuration
František Kučera <franta-hg@frantovo.cz>
parents: 17
diff changeset
    49
	}
80
c4635ab3a7af bash completion: generate helper files with databases and formatters from configuration
František Kučera <franta-hg@frantovo.cz>
parents: 75
diff changeset
    50
192
a32bfcbdee51 jdbc-dk-driver: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 189
diff changeset
    51
	/**
a32bfcbdee51 jdbc-dk-driver: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 189
diff changeset
    52
	 * JDBC connection should not be used directly in SQL-DK.
a32bfcbdee51 jdbc-dk-driver: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 189
diff changeset
    53
	 *
a32bfcbdee51 jdbc-dk-driver: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 189
diff changeset
    54
	 * @see DatabaseDefinition#connect(info.globalcode.sql.dk.configuration.Properties)
a32bfcbdee51 jdbc-dk-driver: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 189
diff changeset
    55
	 * @param properties
a32bfcbdee51 jdbc-dk-driver: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 189
diff changeset
    56
	 * @param databaseDefinition
a32bfcbdee51 jdbc-dk-driver: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 189
diff changeset
    57
	 * @return
a32bfcbdee51 jdbc-dk-driver: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 189
diff changeset
    58
	 * @throws java.sql.SQLException
a32bfcbdee51 jdbc-dk-driver: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 189
diff changeset
    59
	 */
a32bfcbdee51 jdbc-dk-driver: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 189
diff changeset
    60
	public static Connection jdbcConnect(DatabaseDefinition databaseDefinition, Properties properties) throws SQLException {
236
a3ec71fa8e17 Avoid reusing/rewriting the DB connection properties.
František Kučera <franta-hg@frantovo.cz>
parents: 196
diff changeset
    61
		synchronized (properties) {
a3ec71fa8e17 Avoid reusing/rewriting the DB connection properties.
František Kučera <franta-hg@frantovo.cz>
parents: 196
diff changeset
    62
			/**
a3ec71fa8e17 Avoid reusing/rewriting the DB connection properties.
František Kučera <franta-hg@frantovo.cz>
parents: 196
diff changeset
    63
			 * Avoid rewriting the properties. Usually, the connection is created only once, but
a3ec71fa8e17 Avoid reusing/rewriting the DB connection properties.
František Kučera <franta-hg@frantovo.cz>
parents: 196
diff changeset
    64
			 * with --test-connection and with SQL-DK JDBC driver, it might be reused.
a3ec71fa8e17 Avoid reusing/rewriting the DB connection properties.
František Kučera <franta-hg@frantovo.cz>
parents: 196
diff changeset
    65
			 */
a3ec71fa8e17 Avoid reusing/rewriting the DB connection properties.
František Kučera <franta-hg@frantovo.cz>
parents: 196
diff changeset
    66
			properties = properties.clone();
a3ec71fa8e17 Avoid reusing/rewriting the DB connection properties.
František Kučera <franta-hg@frantovo.cz>
parents: 196
diff changeset
    67
		}
192
a32bfcbdee51 jdbc-dk-driver: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 189
diff changeset
    68
		if (properties.hasProperty(JDBC_PROPERTY_PASSWORD)) {
a32bfcbdee51 jdbc-dk-driver: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 189
diff changeset
    69
			log.log(Level.WARNING, "Passing DB password as CLI parameter is insecure!");
a32bfcbdee51 jdbc-dk-driver: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 189
diff changeset
    70
		}
a32bfcbdee51 jdbc-dk-driver: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 189
diff changeset
    71
		Properties credentials = new Properties();
a32bfcbdee51 jdbc-dk-driver: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 189
diff changeset
    72
		credentials.add(new Property(JDBC_PROPERTY_USER, databaseDefinition.getUserName()));
a32bfcbdee51 jdbc-dk-driver: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 189
diff changeset
    73
		credentials.add(new Property(JDBC_PROPERTY_PASSWORD, databaseDefinition.getPassword()));
a32bfcbdee51 jdbc-dk-driver: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 189
diff changeset
    74
		credentials.setDefaults(databaseDefinition.getProperties());
a32bfcbdee51 jdbc-dk-driver: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 189
diff changeset
    75
		properties.setDefaults(credentials);
a32bfcbdee51 jdbc-dk-driver: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 189
diff changeset
    76
		java.util.Properties javaProperties = properties.getJavaProperties();
194
629c9c7eab01 JDBC driver class can be specified in the database configuration as an optional parameter (useful especially while embedding jdbc-dk-driver into other application that does not support automatic driver discovery)
František Kučera <franta-hg@frantovo.cz>
parents: 193
diff changeset
    77
629c9c7eab01 JDBC driver class can be specified in the database configuration as an optional parameter (useful especially while embedding jdbc-dk-driver into other application that does not support automatic driver discovery)
František Kučera <franta-hg@frantovo.cz>
parents: 193
diff changeset
    78
		String driverClassName = databaseDefinition.getDriver();
629c9c7eab01 JDBC driver class can be specified in the database configuration as an optional parameter (useful especially while embedding jdbc-dk-driver into other application that does not support automatic driver discovery)
František Kučera <franta-hg@frantovo.cz>
parents: 193
diff changeset
    79
		final String url = databaseDefinition.getUrl();
629c9c7eab01 JDBC driver class can be specified in the database configuration as an optional parameter (useful especially while embedding jdbc-dk-driver into other application that does not support automatic driver discovery)
František Kučera <franta-hg@frantovo.cz>
parents: 193
diff changeset
    80
		if (driverClassName == null) {
629c9c7eab01 JDBC driver class can be specified in the database configuration as an optional parameter (useful especially while embedding jdbc-dk-driver into other application that does not support automatic driver discovery)
František Kučera <franta-hg@frantovo.cz>
parents: 193
diff changeset
    81
			log.log(Level.FINE, "Using DriverManager to create connection for „{0}“", url);
629c9c7eab01 JDBC driver class can be specified in the database configuration as an optional parameter (useful especially while embedding jdbc-dk-driver into other application that does not support automatic driver discovery)
František Kučera <franta-hg@frantovo.cz>
parents: 193
diff changeset
    82
			return DriverManager.getConnection(url, javaProperties);
629c9c7eab01 JDBC driver class can be specified in the database configuration as an optional parameter (useful especially while embedding jdbc-dk-driver into other application that does not support automatic driver discovery)
František Kučera <franta-hg@frantovo.cz>
parents: 193
diff changeset
    83
		} else {
629c9c7eab01 JDBC driver class can be specified in the database configuration as an optional parameter (useful especially while embedding jdbc-dk-driver into other application that does not support automatic driver discovery)
František Kučera <franta-hg@frantovo.cz>
parents: 193
diff changeset
    84
			log.log(Level.FINE, "Using custom Driver „{0}“ to create connection for „{1}“", new Object[]{driverClassName, url});
629c9c7eab01 JDBC driver class can be specified in the database configuration as an optional parameter (useful especially while embedding jdbc-dk-driver into other application that does not support automatic driver discovery)
František Kučera <franta-hg@frantovo.cz>
parents: 193
diff changeset
    85
			try {
629c9c7eab01 JDBC driver class can be specified in the database configuration as an optional parameter (useful especially while embedding jdbc-dk-driver into other application that does not support automatic driver discovery)
František Kučera <franta-hg@frantovo.cz>
parents: 193
diff changeset
    86
				Class<Driver> driverClass = (Class<Driver>) Class.forName(driverClassName);
629c9c7eab01 JDBC driver class can be specified in the database configuration as an optional parameter (useful especially while embedding jdbc-dk-driver into other application that does not support automatic driver discovery)
František Kučera <franta-hg@frantovo.cz>
parents: 193
diff changeset
    87
				Driver driver = driverClass.newInstance();
196
76da38d49e81 parallel connection testing: avoid deadlocks – preload drivers + better exception handling and logging
František Kučera <franta-hg@frantovo.cz>
parents: 194
diff changeset
    88
				Connection connection = driver.connect(url, javaProperties);
76da38d49e81 parallel connection testing: avoid deadlocks – preload drivers + better exception handling and logging
František Kučera <franta-hg@frantovo.cz>
parents: 194
diff changeset
    89
				if (connection == null) {
76da38d49e81 parallel connection testing: avoid deadlocks – preload drivers + better exception handling and logging
František Kučera <franta-hg@frantovo.cz>
parents: 194
diff changeset
    90
					log.log(Level.SEVERE, "Driver „{0}“ returend null → it does not accept the URL: „{1}“", new Object[]{driverClassName, url});
76da38d49e81 parallel connection testing: avoid deadlocks – preload drivers + better exception handling and logging
František Kučera <franta-hg@frantovo.cz>
parents: 194
diff changeset
    91
					throw new SQLException("Unable to connect: driver returned null.");
76da38d49e81 parallel connection testing: avoid deadlocks – preload drivers + better exception handling and logging
František Kučera <franta-hg@frantovo.cz>
parents: 194
diff changeset
    92
				} else {
76da38d49e81 parallel connection testing: avoid deadlocks – preload drivers + better exception handling and logging
František Kučera <franta-hg@frantovo.cz>
parents: 194
diff changeset
    93
					return connection;
76da38d49e81 parallel connection testing: avoid deadlocks – preload drivers + better exception handling and logging
František Kučera <franta-hg@frantovo.cz>
parents: 194
diff changeset
    94
				}
194
629c9c7eab01 JDBC driver class can be specified in the database configuration as an optional parameter (useful especially while embedding jdbc-dk-driver into other application that does not support automatic driver discovery)
František Kučera <franta-hg@frantovo.cz>
parents: 193
diff changeset
    95
			} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | SQLException e) {
629c9c7eab01 JDBC driver class can be specified in the database configuration as an optional parameter (useful especially while embedding jdbc-dk-driver into other application that does not support automatic driver discovery)
František Kučera <franta-hg@frantovo.cz>
parents: 193
diff changeset
    96
				throw new SQLException("Unable to connect usig specific driver: " + driverClassName, e);
629c9c7eab01 JDBC driver class can be specified in the database configuration as an optional parameter (useful especially while embedding jdbc-dk-driver into other application that does not support automatic driver discovery)
František Kučera <franta-hg@frantovo.cz>
parents: 193
diff changeset
    97
			}
629c9c7eab01 JDBC driver class can be specified in the database configuration as an optional parameter (useful especially while embedding jdbc-dk-driver into other application that does not support automatic driver discovery)
František Kučera <franta-hg@frantovo.cz>
parents: 193
diff changeset
    98
		}
192
a32bfcbdee51 jdbc-dk-driver: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 189
diff changeset
    99
	}
a32bfcbdee51 jdbc-dk-driver: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 189
diff changeset
   100
1
f32dac78d13a WOW some classes LOL; TODO: refactor
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   101
}