Merge pull request #2894 from narfindustries/dbmanager-reload

EamDB implementations will now correctly shutdown and restart connections when settings have changed.
This commit is contained in:
Richard Cordovano 2017-06-26 17:45:46 -04:00 committed by GitHub
commit abb18d4b43
5 changed files with 87 additions and 5 deletions

View File

@ -47,8 +47,26 @@ public interface EamDb {
}
}
/**
* Shutdown the connection pool.
*
* This closes the connection pool including all idle database connections.
* It will not close active/in-use connections.
* Thus, it is vital that there are no in-use connections
* when you call this method.
*
* @throws EamDbException if there is a problem closing the connection pool.
*/
void shutdownConnections() throws EamDbException;
/**
* Update settings
*
* When using updateSettings,
* if any database settings have changed, you should call
* shutdownConnections() before using any API methods.
* That will ensure that any old connections are closed
* and all new connections will be made using the new settings.
*/
void updateSettings();

View File

@ -50,7 +50,19 @@ public class PostgresEamDb extends AbstractSqlEamDb {
private PostgresEamDb() {
dbSettings = new PostgresEamDbSettings();
updateSettings();
bulkArtifactsThreshold = dbSettings.getBulkThreshold();
}
@Override
public void shutdownConnections() throws EamDbException {
try {
synchronized(this) {
connectionPool.close();
connectionPool = null; // force it to be re-created on next connect()
}
} catch (SQLException ex) {
throw new EamDbException("Failed to close existing database connections.", ex); // NON-NLS
}
}
@Override

View File

@ -25,6 +25,7 @@ import java.sql.Statement;
import java.util.List;
import java.util.logging.Level;
import org.apache.commons.dbcp2.BasicDataSource;
import org.openide.util.Exceptions;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
@ -50,9 +51,23 @@ public class SqliteEamDb extends AbstractSqlEamDb {
private SqliteEamDb() {
dbSettings = new SqliteEamDbSettings();
updateSettings();
bulkArtifactsThreshold = dbSettings.getBulkThreshold();
}
@Override
public void shutdownConnections() throws EamDbException {
try {
synchronized(this) {
if (null != connectionPool) {
connectionPool.close();
connectionPool = null; // force it to be re-created on next connect()
}
}
} catch (SQLException ex) {
throw new EamDbException("Failed to close existing database connections.", ex); // NON-NLS
}
}
@Override
public void updateSettings() {
synchronized (this) {

View File

@ -18,7 +18,9 @@ import javax.swing.ImageIcon;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.netbeans.spi.options.OptionsPanelController;
@ -545,22 +547,58 @@ public class EamDbSettingsDialog extends JDialog {
}
}//GEN-LAST:event_bnCreateDbActionPerformed
@Messages({"EamDbSettingsDialog.okButton.errorTitle.text=Restart Required.",
"EamDbSettingsDialog.okButton.errorMsg.text=Please restart Autopsy to begin using the new database platform."})
private void bnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnOkActionPerformed
/**
* We have to shutdown the previous platform's connection pool first;
* assuming it wasn't DISABLED. This will close any existing idle
* connections.
*
* The next use of an EamDb API method will start a new connection pool
* using those new settings.
*/
try {
EamDb previousDbManager = EamDb.getInstance();
if (null != previousDbManager) {
// NOTE: do not set/save the seleted platform before calling this.
EamDb.getInstance().shutdownConnections();
}
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Failed to close database connections in previously selected platform.", ex); // NON-NLS
SwingUtilities.invokeLater(() -> {
JOptionPane.showMessageDialog(null,
Bundle.EamDbSettingsDialog_okButton_errorMsg_text(),
Bundle.EamDbSettingsDialog_okButton_errorTitle_text(),
JOptionPane.WARNING_MESSAGE);
});
}
// Even if we fail to close the existing connections, make sure that we
// save the new connection settings, so an Autopsy restart will correctly
// start with the new settings.
EamDbPlatformEnum.setSelectedPlatform(selectedPlatform.name());
EamDbPlatformEnum.saveSelectedPlatform();
switch (selectedPlatform) {
case POSTGRESQL:
// save the new PostgreSQL settings
dbSettingsPostgres.saveSettings();
// Load those newly saved settings into the postgres db manager instance
// in case we are still using the same instance.
EamDb.getInstance().updateSettings();
break;
case SQLITE:
// save the new SQLite settings
dbSettingsSqlite.saveSettings();
// Load those newly saved settings into the sqlite db manager instance
// in case we are still using the same instance.
EamDb.getInstance().updateSettings();
break;
case DISABLED:
break;
}
dispose();
}//GEN-LAST:event_bnOkActionPerformed

View File

@ -561,13 +561,11 @@ final class ImportHashDatabaseDialog extends javax.swing.JDialog {
@NbBundle.Messages({"ImportHashDatabaseDialog.ImportHashDatabaseWorker.displayName=Importing Hash Database"})
private class ImportHashDatabaseWorker extends SwingWorker<Object, Void> {
private final EamDb dbManager;
private final File file;
private final EamArtifactInstance.KnownStatus knownStatus;
private final int globalSetID;
public ImportHashDatabaseWorker(String filename, EamArtifactInstance.KnownStatus knownStatus, int globalSetID) throws EamDbException, UnknownHostException {
this.dbManager = EamDb.getInstance();
this.file = new File(filename);
this.knownStatus = knownStatus;
this.globalSetID = globalSetID;
@ -591,6 +589,7 @@ final class ImportHashDatabaseDialog extends javax.swing.JDialog {
private void importHashDatabase(ProgressHandle progress) throws EamDbException, IOException {
BufferedReader reader = new BufferedReader(new FileReader(file));
String line;
EamDb dbManager = EamDb.getInstance();
long totalLines = numberOfLinesInFile(file);
if (totalLines <= Integer.MAX_VALUE) {