19 package org.sleuthkit.autopsy.centralrepository.datamodel;
21 import java.sql.Connection;
22 import java.sql.SQLException;
23 import java.sql.Statement;
24 import java.util.concurrent.TimeUnit;
25 import java.util.logging.Level;
26 import org.apache.commons.dbcp2.BasicDataSource;
35 final class PostgresEamDb
extends AbstractSqlEamDb {
37 private final static Logger LOGGER = Logger.
getLogger(PostgresEamDb.class.getName());
39 private final static String CONFLICT_CLAUSE =
"ON CONFLICT DO NOTHING";
41 private static PostgresEamDb instance;
43 private static final int CONN_POOL_SIZE = 10;
44 private BasicDataSource connectionPool = null;
46 private final PostgresEamDbSettings dbSettings;
55 public synchronized static PostgresEamDb getInstance() throws EamDbException {
56 if (instance == null) {
57 instance =
new PostgresEamDb();
68 private PostgresEamDb() throws EamDbException {
69 dbSettings =
new PostgresEamDbSettings();
70 bulkArtifactsThreshold = dbSettings.getBulkThreshold();
74 public void shutdownConnections() throws EamDbException {
77 if(connectionPool != null){
78 connectionPool.close();
79 connectionPool = null;
83 }
catch (SQLException ex) {
84 throw new EamDbException(
"Failed to close existing database connections.", ex);
89 public void updateSettings() {
91 dbSettings.loadSettings();
92 bulkArtifactsThreshold = dbSettings.getBulkThreshold();
97 public void saveSettings() {
99 dbSettings.saveSettings();
104 public void reset() throws EamDbException {
105 Connection conn = connect();
108 Statement dropContent = conn.createStatement();
109 dropContent.executeUpdate(
"TRUNCATE TABLE organizations RESTART IDENTITY CASCADE");
110 dropContent.executeUpdate(
"TRUNCATE TABLE cases RESTART IDENTITY CASCADE");
111 dropContent.executeUpdate(
"TRUNCATE TABLE data_sources RESTART IDENTITY CASCADE");
112 dropContent.executeUpdate(
"TRUNCATE TABLE reference_sets RESTART IDENTITY CASCADE");
113 dropContent.executeUpdate(
"TRUNCATE TABLE correlation_types RESTART IDENTITY CASCADE");
114 dropContent.executeUpdate(
"TRUNCATE TABLE db_info RESTART IDENTITY CASCADE");
116 String instancesTemplate =
"TRUNCATE TABLE %s_instances RESTART IDENTITY CASCADE";
117 String referencesTemplate =
"TRUNCATE TABLE reference_%s RESTART IDENTITY CASCADE";
118 for (CorrelationAttributeInstance.Type type : defaultCorrelationTypes) {
119 dropContent.executeUpdate(String.format(instancesTemplate, type.getDbTableName()));
121 if (type.getId() == CorrelationAttributeInstance.FILES_TYPE_ID) {
122 dropContent.executeUpdate(String.format(referencesTemplate, type.getDbTableName()));
125 }
catch (SQLException ex) {
126 LOGGER.log(Level.WARNING,
"Failed to reset database.", ex);
128 EamDbUtil.closeConnection(conn);
131 dbSettings.insertDefaultDatabaseContent();
138 private void setupConnectionPool() throws EamDbException {
139 connectionPool =
new BasicDataSource();
140 connectionPool.setUsername(dbSettings.getUserName());
141 connectionPool.setPassword(dbSettings.getPassword());
142 connectionPool.setDriverClassName(dbSettings.getDriver());
144 StringBuilder connectionURL =
new StringBuilder();
145 connectionURL.append(dbSettings.getJDBCBaseURI());
146 connectionURL.append(dbSettings.getHost());
147 connectionURL.append(
":");
148 connectionURL.append(dbSettings.getPort());
149 connectionURL.append(
"/");
150 connectionURL.append(dbSettings.getDbName());
152 connectionPool.setUrl(connectionURL.toString());
153 connectionPool.setUsername(dbSettings.getUserName());
154 connectionPool.setPassword(dbSettings.getPassword());
157 connectionPool.setInitialSize(5);
158 connectionPool.setMaxIdle(CONN_POOL_SIZE);
159 connectionPool.setValidationQuery(dbSettings.getValidationQuery());
170 protected Connection connect() throws EamDbException {
171 synchronized (
this) {
172 if (!EamDb.isEnabled()) {
173 throw new EamDbException(
"Central Repository module is not enabled");
176 if (connectionPool == null) {
177 setupConnectionPool();
182 return connectionPool.getConnection();
183 }
catch (SQLException ex) {
184 throw new EamDbException(
"Error getting connection from connection pool.", ex);
189 protected String getConflictClause() {
190 return CONFLICT_CLAUSE;
202 public CoordinationService.Lock getExclusiveMultiUserDbLock() throws EamDbException{
205 if( ! UserPreferences.getIsMultiUserModeEnabled()){
209 String databaseNodeName = dbSettings.getHost() +
"_" + dbSettings.getDbName();
210 CoordinationService.Lock lock = CoordinationService.getInstance().tryGetExclusiveLock(CoordinationService.CategoryNode.CENTRAL_REPO, databaseNodeName, 5, TimeUnit.MINUTES);
215 throw new EamDbException(
"Error acquiring database lock");
216 }
catch (InterruptedException ex){
217 throw new EamDbException(
"Error acquiring database lock");
218 }
catch (CoordinationService.CoordinationServiceException ex) {
synchronized static Logger getLogger(String name)