Merge pull request #803 from stefanneuhaus/fix-postgres-usage_missing-resource-exception_merge-property

Fix MissingResourceException "MERGE_PROPERTY" for Postgres
This commit is contained in:
Jeremy Long
2017-07-14 06:37:25 -04:00
committed by GitHub
4 changed files with 37 additions and 26 deletions

View File

@@ -117,7 +117,7 @@ public final class ConnectionFactory {
} }
} catch (DriverLoadException ex) { } catch (DriverLoadException ex) {
LOGGER.debug("Unable to load database driver", ex); LOGGER.debug("Unable to load database driver", ex);
throw new DatabaseException("Unable to load database driver"); throw new DatabaseException("Unable to load database driver", ex);
} }
} }
userName = Settings.getString(Settings.KEYS.DB_USER, "dcuser"); userName = Settings.getString(Settings.KEYS.DB_USER, "dcuser");
@@ -130,7 +130,7 @@ public final class ConnectionFactory {
} catch (IOException ex) { } catch (IOException ex) {
LOGGER.debug( LOGGER.debug(
"Unable to retrieve the database connection string", ex); "Unable to retrieve the database connection string", ex);
throw new DatabaseException("Unable to retrieve the database connection string"); throw new DatabaseException("Unable to retrieve the database connection string", ex);
} }
boolean shouldCreateSchema = false; boolean shouldCreateSchema = false;
try { try {
@@ -140,7 +140,7 @@ public final class ConnectionFactory {
} }
} catch (IOException ioex) { } catch (IOException ioex) {
LOGGER.debug("Unable to verify database exists", ioex); LOGGER.debug("Unable to verify database exists", ioex);
throw new DatabaseException("Unable to verify database exists"); throw new DatabaseException("Unable to verify database exists", ioex);
} }
LOGGER.debug("Loading database connection"); LOGGER.debug("Loading database connection");
LOGGER.debug("Connection String: {}", connectionString); LOGGER.debug("Connection String: {}", connectionString);
@@ -157,11 +157,11 @@ public final class ConnectionFactory {
LOGGER.debug("Unable to start the database in server mode; reverting to single user mode"); LOGGER.debug("Unable to start the database in server mode; reverting to single user mode");
} catch (SQLException sqlex) { } catch (SQLException sqlex) {
LOGGER.debug("Unable to connect to the database", ex); LOGGER.debug("Unable to connect to the database", ex);
throw new DatabaseException("Unable to connect to the database"); throw new DatabaseException("Unable to connect to the database", ex);
} }
} else { } else {
LOGGER.debug("Unable to connect to the database", ex); LOGGER.debug("Unable to connect to the database", ex);
throw new DatabaseException("Unable to connect to the database"); throw new DatabaseException("Unable to connect to the database", ex);
} }
} }
@@ -170,7 +170,7 @@ public final class ConnectionFactory {
createTables(conn); createTables(conn);
} catch (DatabaseException dex) { } catch (DatabaseException dex) {
LOGGER.debug("", dex); LOGGER.debug("", dex);
throw new DatabaseException("Unable to create the database structure"); throw new DatabaseException("Unable to create the database structure", dex);
} }
} }
try { try {
@@ -228,7 +228,7 @@ public final class ConnectionFactory {
conn = DriverManager.getConnection(connectionString, userName, password); conn = DriverManager.getConnection(connectionString, userName, password);
} catch (SQLException ex) { } catch (SQLException ex) {
LOGGER.debug("", ex); LOGGER.debug("", ex);
throw new DatabaseException("Unable to connect to the database"); throw new DatabaseException("Unable to connect to the database", ex);
} }
return conn; return conn;
} }
@@ -317,7 +317,7 @@ public final class ConnectionFactory {
try { try {
databaseProductName = conn.getMetaData().getDatabaseProductName(); databaseProductName = conn.getMetaData().getDatabaseProductName();
} catch (SQLException ex) { } catch (SQLException ex) {
throw new DatabaseException("Unable to get the database product name"); throw new DatabaseException("Unable to get the database product name", ex);
} }
if ("h2".equalsIgnoreCase(databaseProductName)) { if ("h2".equalsIgnoreCase(databaseProductName)) {
LOGGER.debug("Updating database structure"); LOGGER.debug("Updating database structure");
@@ -412,7 +412,7 @@ public final class ConnectionFactory {
} }
} catch (SQLException ex) { } catch (SQLException ex) {
LOGGER.debug("", ex); LOGGER.debug("", ex);
throw new DatabaseException("Unable to check the database schema version"); throw new DatabaseException("Unable to check the database schema version", ex);
} finally { } finally {
DBUtils.closeResultSet(rs); DBUtils.closeResultSet(rs);
DBUtils.closeStatement(ps); DBUtils.closeStatement(ps);

View File

@@ -231,7 +231,7 @@ public final class CveDB implements AutoCloseable {
*/ */
private static String determineDatabaseProductName(Connection conn) { private static String determineDatabaseProductName(Connection conn) {
try { try {
final String databaseProductName = conn.getMetaData().getDatabaseProductName(); final String databaseProductName = conn.getMetaData().getDatabaseProductName().toLowerCase();
LOGGER.debug("Database product: {}", databaseProductName); LOGGER.debug("Database product: {}", databaseProductName);
return databaseProductName; return databaseProductName;
} catch (SQLException se) { } catch (SQLException se) {
@@ -258,14 +258,19 @@ public final class CveDB implements AutoCloseable {
* database connection * database connection
*/ */
private synchronized void open() throws DatabaseException { private synchronized void open() throws DatabaseException {
if (!instance.isOpen()) { try {
instance.connection = ConnectionFactory.getConnection(); if (!instance.isOpen()) {
final String databaseProductName = determineDatabaseProductName(instance.connection); instance.connection = ConnectionFactory.getConnection();
instance.statementBundle = databaseProductName != null final String databaseProductName = determineDatabaseProductName(instance.connection);
? ResourceBundle.getBundle("data/dbStatements", new Locale(databaseProductName)) instance.statementBundle = databaseProductName != null
: ResourceBundle.getBundle("data/dbStatements"); ? ResourceBundle.getBundle("data/dbStatements", new Locale(databaseProductName))
instance.prepareStatements(); : ResourceBundle.getBundle("data/dbStatements");
instance.databaseProperties = new DatabaseProperties(instance); instance.prepareStatements();
instance.databaseProperties = new DatabaseProperties(instance);
}
} catch(DatabaseException e) {
releaseResources();
throw e;
} }
} }
@@ -290,14 +295,18 @@ public final class CveDB implements AutoCloseable {
LOGGER.error("There was an exception attempting to close the CveDB, see the log for more details."); LOGGER.error("There was an exception attempting to close the CveDB, see the log for more details.");
LOGGER.debug("", ex); LOGGER.debug("", ex);
} }
instance.statementBundle = null; releaseResources();
instance.preparedStatements.clear();
instance.databaseProperties = null;
instance.connection = null;
} }
} }
} }
private synchronized void releaseResources() {
instance.statementBundle = null;
instance.preparedStatements.clear();
instance.databaseProperties = null;
instance.connection = null;
}
/** /**
* Returns whether the database connection is open or closed. * Returns whether the database connection is open or closed.
* *
@@ -315,15 +324,15 @@ public final class CveDB implements AutoCloseable {
*/ */
private void prepareStatements() throws DatabaseException { private void prepareStatements() throws DatabaseException {
for (PreparedStatementCveDb key : values()) { for (PreparedStatementCveDb key : values()) {
final String statementString = statementBundle.getString(key.name());
final PreparedStatement preparedStatement; final PreparedStatement preparedStatement;
try { try {
final String statementString = statementBundle.getString(key.name());
if (key == INSERT_VULNERABILITY || key == INSERT_CPE) { if (key == INSERT_VULNERABILITY || key == INSERT_CPE) {
preparedStatement = connection.prepareStatement(statementString, new String[]{"id"}); preparedStatement = connection.prepareStatement(statementString, new String[]{"id"});
} else { } else {
preparedStatement = connection.prepareStatement(statementString); preparedStatement = connection.prepareStatement(statementString);
} }
} catch (SQLException exception) { } catch (SQLException | MissingResourceException exception) {
throw new DatabaseException(exception); throw new DatabaseException(exception);
} }
preparedStatements.put(key, preparedStatement); preparedStatements.put(key, preparedStatement);
@@ -492,7 +501,7 @@ public final class CveDB implements AutoCloseable {
mergeProperty.setString(1, key); mergeProperty.setString(1, key);
mergeProperty.setString(2, value); mergeProperty.setString(2, value);
mergeProperty.executeUpdate(); mergeProperty.executeUpdate();
} catch (MissingResourceException mre) { } catch (SQLException e) {
// No Merge statement, so doing an Update/Insert... // No Merge statement, so doing an Update/Insert...
final PreparedStatement updateProperty = getPreparedStatement(UPDATE_PROPERTY); final PreparedStatement updateProperty = getPreparedStatement(UPDATE_PROPERTY);
updateProperty.setString(1, value); updateProperty.setString(1, value);

View File

@@ -172,7 +172,9 @@ public class NvdCveUpdater implements CachedWebDataSource {
throw new UpdateException("Database Exception", ex); throw new UpdateException("Database Exception", ex);
} finally { } finally {
shutdownExecutorServices(); shutdownExecutorServices();
cveDb.close(); if(cveDb != null) {
cveDb.close();
}
if (lock != null) { if (lock != null) {
try { try {
lock.release(); lock.release();