19 package org.sleuthkit.autopsy.centralrepository.datamodel;
21 import com.google.common.cache.Cache;
22 import com.google.common.cache.CacheBuilder;
23 import com.google.common.cache.CacheLoader;
24 import java.net.UnknownHostException;
25 import java.util.ArrayList;
26 import java.util.List;
27 import java.util.Collection;
28 import java.util.LinkedHashSet;
29 import java.util.stream.Collectors;
30 import java.sql.Connection;
31 import java.sql.PreparedStatement;
32 import java.sql.ResultSet;
33 import java.sql.SQLException;
34 import java.sql.Statement;
35 import java.sql.Types;
36 import java.time.LocalDate;
37 import java.util.Arrays;
38 import java.util.HashMap;
41 import java.util.concurrent.ExecutionException;
42 import java.util.concurrent.TimeUnit;
43 import java.util.logging.Level;
44 import org.apache.commons.lang3.tuple.Pair;
45 import org.openide.util.NbBundle.Messages;
53 import org.
sleuthkit.datamodel.CaseDbSchemaVersionNumber;
61 abstract class RdbmsCentralRepo
implements CentralRepository {
63 private final static Logger logger = Logger.getLogger(RdbmsCentralRepo.class.getName());
64 static final String SCHEMA_MAJOR_VERSION_KEY =
"SCHEMA_VERSION";
65 static final String SCHEMA_MINOR_VERSION_KEY =
"SCHEMA_MINOR_VERSION";
66 static final String CREATION_SCHEMA_MAJOR_VERSION_KEY =
"CREATION_SCHEMA_MAJOR_VERSION";
67 static final String CREATION_SCHEMA_MINOR_VERSION_KEY =
"CREATION_SCHEMA_MINOR_VERSION";
68 static final CaseDbSchemaVersionNumber SOFTWARE_CR_DB_SCHEMA_VERSION =
new CaseDbSchemaVersionNumber(1, 4);
70 protected final List<CorrelationAttributeInstance.Type> defaultCorrelationTypes;
72 private int bulkArtifactsCount;
73 protected int bulkArtifactsThreshold;
74 private final Map<String, Collection<CorrelationAttributeInstance>> bulkArtifacts;
75 private static final int CASE_CACHE_TIMEOUT = 5;
76 private static final int DATA_SOURCE_CACHE_TIMEOUT = 5;
77 private static final int ACCOUNTS_CACHE_TIMEOUT = 5;
78 private static final Cache<String, CentralRepoAccountType> accountTypesCache = CacheBuilder.newBuilder().build();
79 private static final Cache<Pair<CentralRepoAccountType, String>, CentralRepoAccount> accountsCache = CacheBuilder.newBuilder()
80 .expireAfterWrite(ACCOUNTS_CACHE_TIMEOUT, TimeUnit.MINUTES).
83 private boolean isCRTypeCacheInitialized;
84 private static final Cache<Integer, CorrelationAttributeInstance.Type> typeCache = CacheBuilder.newBuilder().build();
85 private static final Cache<String, CorrelationCase> caseCacheByUUID = CacheBuilder.newBuilder()
86 .expireAfterWrite(CASE_CACHE_TIMEOUT, TimeUnit.MINUTES).
88 private static final Cache<Integer, CorrelationCase> caseCacheById = CacheBuilder.newBuilder()
89 .expireAfterWrite(CASE_CACHE_TIMEOUT, TimeUnit.MINUTES).
91 private static final Cache<String, CorrelationDataSource> dataSourceCacheByDsObjectId = CacheBuilder.newBuilder()
92 .expireAfterWrite(DATA_SOURCE_CACHE_TIMEOUT, TimeUnit.MINUTES).
94 private static final Cache<String, CorrelationDataSource> dataSourceCacheById = CacheBuilder.newBuilder()
95 .expireAfterWrite(DATA_SOURCE_CACHE_TIMEOUT, TimeUnit.MINUTES).
98 static final int MAX_VALUE_LENGTH = 256;
102 static final int DEFAULT_BULK_THRESHHOLD = 1000;
109 protected RdbmsCentralRepo() throws CentralRepoException {
110 isCRTypeCacheInitialized =
false;
111 bulkArtifactsCount = 0;
112 bulkArtifacts =
new HashMap<>();
114 defaultCorrelationTypes = CorrelationAttributeInstance.getDefaultCorrelationTypes();
115 defaultCorrelationTypes.forEach((type) -> {
116 bulkArtifacts.put(CentralRepoDbUtil.correlationTypeToInstanceTableName(type),
new ArrayList<>());
123 protected abstract Connection connect(
boolean foreignKeys)
throws CentralRepoException;
128 protected abstract Connection connect() throws CentralRepoException;
133 protected abstract Connection getEphemeralConnection();
143 public
void newDbInfo(String name, String value) throws CentralRepoException {
144 Connection conn = connect();
146 PreparedStatement preparedStatement = null;
147 String sql =
"INSERT INTO db_info (name, value) VALUES (?, ?) "
148 + getConflictClause();
150 preparedStatement = conn.prepareStatement(sql);
151 preparedStatement.setString(1, name);
152 preparedStatement.setString(2, value);
153 preparedStatement.executeUpdate();
154 }
catch (SQLException ex) {
155 throw new CentralRepoException(
"Error adding new name/value pair to db_info.", ex);
157 CentralRepoDbUtil.closeStatement(preparedStatement);
158 CentralRepoDbUtil.closeConnection(conn);
164 public void addDataSourceObjectId(
int rowId,
long dataSourceObjectId)
throws CentralRepoException {
165 Connection conn = connect();
166 PreparedStatement preparedStatement = null;
167 String sql =
"UPDATE data_sources SET datasource_obj_id=? WHERE id=?";
169 preparedStatement = conn.prepareStatement(sql);
170 preparedStatement.setLong(1, dataSourceObjectId);
171 preparedStatement.setInt(2, rowId);
172 preparedStatement.executeUpdate();
173 }
catch (SQLException ex) {
174 throw new CentralRepoException(
"Error updating data source object id for data_sources row " + rowId, ex);
176 CentralRepoDbUtil.closeStatement(preparedStatement);
177 CentralRepoDbUtil.closeConnection(conn);
191 public String getDbInfo(String name)
throws CentralRepoException {
192 Connection conn = connect();
194 PreparedStatement preparedStatement = null;
195 ResultSet resultSet = null;
197 String sql =
"SELECT value FROM db_info WHERE name=?";
199 preparedStatement = conn.prepareStatement(sql);
200 preparedStatement.setString(1, name);
201 resultSet = preparedStatement.executeQuery();
202 if (resultSet.next()) {
203 value = resultSet.getString(
"value");
205 }
catch (SQLException ex) {
206 throw new CentralRepoException(
"Error getting value for name.", ex);
208 CentralRepoDbUtil.closeStatement(preparedStatement);
209 CentralRepoDbUtil.closeResultSet(resultSet);
210 CentralRepoDbUtil.closeConnection(conn);
219 protected final void clearCaches() {
220 synchronized(typeCache) {
221 typeCache.invalidateAll();
222 isCRTypeCacheInitialized =
false;
224 caseCacheByUUID.invalidateAll();
225 caseCacheById.invalidateAll();
226 dataSourceCacheByDsObjectId.invalidateAll();
227 dataSourceCacheById.invalidateAll();
239 public void updateDbInfo(String name, String value)
throws CentralRepoException {
240 Connection conn = connect();
242 PreparedStatement preparedStatement = null;
243 String sql =
"UPDATE db_info SET value=? WHERE name=?";
245 preparedStatement = conn.prepareStatement(sql);
246 preparedStatement.setString(1, value);
247 preparedStatement.setString(2, name);
248 preparedStatement.executeUpdate();
249 }
catch (SQLException ex) {
250 throw new CentralRepoException(
"Error updating value for name.", ex);
252 CentralRepoDbUtil.closeStatement(preparedStatement);
253 CentralRepoDbUtil.closeConnection(conn);
267 public synchronized CorrelationCase newCase(CorrelationCase eamCase)
throws CentralRepoException {
269 if (eamCase.getCaseUUID() == null) {
270 throw new CentralRepoException(
"Case UUID is null");
274 CorrelationCase cRCase = getCaseByUUID(eamCase.getCaseUUID());
275 if (cRCase != null) {
279 Connection conn = connect();
280 PreparedStatement preparedStatement = null;
282 String sql =
"INSERT INTO cases(case_uid, org_id, case_name, creation_date, case_number, "
283 +
"examiner_name, examiner_email, examiner_phone, notes) "
284 +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) "
285 + getConflictClause();
286 ResultSet resultSet = null;
288 preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
290 preparedStatement.setString(1, eamCase.getCaseUUID());
291 if (null == eamCase.getOrg()) {
292 preparedStatement.setNull(2, Types.INTEGER);
294 preparedStatement.setInt(2, eamCase.getOrg().getOrgID());
296 preparedStatement.setString(3, eamCase.getDisplayName());
297 preparedStatement.setString(4, eamCase.getCreationDate());
298 if (
"".equals(eamCase.getCaseNumber())) {
299 preparedStatement.setNull(5, Types.INTEGER);
301 preparedStatement.setString(5, eamCase.getCaseNumber());
303 if (
"".equals(eamCase.getExaminerName())) {
304 preparedStatement.setNull(6, Types.INTEGER);
306 preparedStatement.setString(6, eamCase.getExaminerName());
308 if (
"".equals(eamCase.getExaminerEmail())) {
309 preparedStatement.setNull(7, Types.INTEGER);
311 preparedStatement.setString(7, eamCase.getExaminerEmail());
313 if (
"".equals(eamCase.getExaminerPhone())) {
314 preparedStatement.setNull(8, Types.INTEGER);
316 preparedStatement.setString(8, eamCase.getExaminerPhone());
318 if (
"".equals(eamCase.getNotes())) {
319 preparedStatement.setNull(9, Types.INTEGER);
321 preparedStatement.setString(9, eamCase.getNotes());
324 preparedStatement.executeUpdate();
326 resultSet = preparedStatement.getGeneratedKeys();
327 if (!resultSet.next()) {
328 throw new CentralRepoException(String.format(
"Failed to INSERT case %s in central repo", eamCase.getCaseUUID()));
330 int caseID = resultSet.getInt(1);
331 CorrelationCase correlationCase =
new CorrelationCase(caseID, eamCase.getCaseUUID(), eamCase.getOrg(),
332 eamCase.getDisplayName(), eamCase.getCreationDate(), eamCase.getCaseNumber(), eamCase.getExaminerName(),
333 eamCase.getExaminerEmail(), eamCase.getExaminerPhone(), eamCase.getNotes());
334 caseCacheByUUID.put(eamCase.getCaseUUID(), correlationCase);
335 caseCacheById.put(caseID, correlationCase);
336 }
catch (SQLException ex) {
337 throw new CentralRepoException(
"Error inserting new case.", ex);
339 CentralRepoDbUtil.closeResultSet(resultSet);
340 CentralRepoDbUtil.closeStatement(preparedStatement);
341 CentralRepoDbUtil.closeConnection(conn);
345 return getCaseByUUID(eamCase.getCaseUUID());
354 public CorrelationCase newCase(Case autopsyCase)
throws CentralRepoException {
355 if (autopsyCase == null) {
356 throw new CentralRepoException(
"Case is null");
359 CorrelationCase curCeCase =
new CorrelationCase(
361 autopsyCase.getName(),
362 CentralRepoOrganization.getDefault(),
363 autopsyCase.getDisplayName(),
364 autopsyCase.getCreatedDate(),
365 autopsyCase.getNumber(),
366 autopsyCase.getExaminer(),
367 autopsyCase.getExaminerEmail(),
368 autopsyCase.getExaminerPhone(),
369 autopsyCase.getCaseNotes());
370 return newCase(curCeCase);
374 public CorrelationCase getCase(Case autopsyCase)
throws CentralRepoException {
375 return getCaseByUUID(autopsyCase.getName());
384 public void updateCase(CorrelationCase eamCase)
throws CentralRepoException {
385 if (eamCase == null) {
386 throw new CentralRepoException(
"Correlation case is null");
389 Connection conn = connect();
391 PreparedStatement preparedStatement = null;
392 String sql =
"UPDATE cases "
393 +
"SET org_id=?, case_name=?, creation_date=?, case_number=?, examiner_name=?, examiner_email=?, examiner_phone=?, notes=? "
394 +
"WHERE case_uid=?";
397 preparedStatement = conn.prepareStatement(sql);
399 if (null == eamCase.getOrg()) {
400 preparedStatement.setNull(1, Types.INTEGER);
402 preparedStatement.setInt(1, eamCase.getOrg().getOrgID());
404 preparedStatement.setString(2, eamCase.getDisplayName());
405 preparedStatement.setString(3, eamCase.getCreationDate());
407 if (
"".equals(eamCase.getCaseNumber())) {
408 preparedStatement.setNull(4, Types.INTEGER);
410 preparedStatement.setString(4, eamCase.getCaseNumber());
412 if (
"".equals(eamCase.getExaminerName())) {
413 preparedStatement.setNull(5, Types.INTEGER);
415 preparedStatement.setString(5, eamCase.getExaminerName());
417 if (
"".equals(eamCase.getExaminerEmail())) {
418 preparedStatement.setNull(6, Types.INTEGER);
420 preparedStatement.setString(6, eamCase.getExaminerEmail());
422 if (
"".equals(eamCase.getExaminerPhone())) {
423 preparedStatement.setNull(7, Types.INTEGER);
425 preparedStatement.setString(7, eamCase.getExaminerPhone());
427 if (
"".equals(eamCase.getNotes())) {
428 preparedStatement.setNull(8, Types.INTEGER);
430 preparedStatement.setString(8, eamCase.getNotes());
433 preparedStatement.setString(9, eamCase.getCaseUUID());
435 preparedStatement.executeUpdate();
437 caseCacheById.put(eamCase.getID(), eamCase);
438 caseCacheByUUID.put(eamCase.getCaseUUID(), eamCase);
439 }
catch (SQLException ex) {
440 throw new CentralRepoException(
"Error updating case.", ex);
442 CentralRepoDbUtil.closeStatement(preparedStatement);
443 CentralRepoDbUtil.closeConnection(conn);
455 public CorrelationCase getCaseByUUID(String caseUUID)
throws CentralRepoException {
457 return caseCacheByUUID.get(caseUUID, () -> getCaseByUUIDFromCr(caseUUID));
458 }
catch (CacheLoader.InvalidCacheLoadException ignored) {
461 }
catch (ExecutionException ex) {
462 throw new CentralRepoException(
"Error getting autopsy case from Central repo", ex);
473 private CorrelationCase getCaseByUUIDFromCr(String caseUUID)
throws CentralRepoException {
474 Connection conn = connect();
476 CorrelationCase eamCaseResult = null;
477 PreparedStatement preparedStatement = null;
478 ResultSet resultSet = null;
480 String sql =
"SELECT cases.id as case_id, case_uid, case_name, creation_date, case_number, examiner_name, "
481 +
"examiner_email, examiner_phone, notes, organizations.id as org_id, org_name, poc_name, poc_email, poc_phone "
483 +
"LEFT JOIN organizations ON cases.org_id=organizations.id "
484 +
"WHERE case_uid=?";
487 preparedStatement = conn.prepareStatement(sql);
488 preparedStatement.setString(1, caseUUID);
489 resultSet = preparedStatement.executeQuery();
490 if (resultSet.next()) {
491 eamCaseResult = getEamCaseFromResultSet(resultSet);
493 if (eamCaseResult != null) {
495 caseCacheById.put(eamCaseResult.getID(), eamCaseResult);
497 }
catch (SQLException ex) {
498 throw new CentralRepoException(
"Error getting case details.", ex);
500 CentralRepoDbUtil.closeStatement(preparedStatement);
501 CentralRepoDbUtil.closeResultSet(resultSet);
502 CentralRepoDbUtil.closeConnection(conn);
505 return eamCaseResult;
516 public CorrelationCase getCaseById(
int caseId)
throws CentralRepoException {
518 return caseCacheById.get(caseId, () -> getCaseByIdFromCr(caseId));
519 }
catch (CacheLoader.InvalidCacheLoadException ignored) {
522 }
catch (ExecutionException ex) {
523 throw new CentralRepoException(
"Error getting autopsy case from Central repo", ex);
534 private CorrelationCase getCaseByIdFromCr(
int caseId)
throws CentralRepoException {
535 Connection conn = connect();
537 CorrelationCase eamCaseResult = null;
538 PreparedStatement preparedStatement = null;
539 ResultSet resultSet = null;
541 String sql =
"SELECT cases.id as case_id, case_uid, case_name, creation_date, case_number, examiner_name, "
542 +
"examiner_email, examiner_phone, notes, organizations.id as org_id, org_name, poc_name, poc_email, poc_phone "
544 +
"LEFT JOIN organizations ON cases.org_id=organizations.id "
545 +
"WHERE cases.id=?";
547 preparedStatement = conn.prepareStatement(sql);
548 preparedStatement.setInt(1, caseId);
549 resultSet = preparedStatement.executeQuery();
550 if (resultSet.next()) {
551 eamCaseResult = getEamCaseFromResultSet(resultSet);
553 if (eamCaseResult != null) {
555 caseCacheByUUID.put(eamCaseResult.getCaseUUID(), eamCaseResult);
557 }
catch (SQLException ex) {
558 throw new CentralRepoException(
"Error getting case details.", ex);
560 CentralRepoDbUtil.closeStatement(preparedStatement);
561 CentralRepoDbUtil.closeResultSet(resultSet);
562 CentralRepoDbUtil.closeConnection(conn);
565 return eamCaseResult;
574 public List<CorrelationCase> getCases() throws CentralRepoException {
575 Connection conn = connect();
577 List<CorrelationCase> cases =
new ArrayList<>();
578 CorrelationCase eamCaseResult;
579 PreparedStatement preparedStatement = null;
580 ResultSet resultSet = null;
582 String sql =
"SELECT cases.id as case_id, case_uid, case_name, creation_date, case_number, examiner_name, "
583 +
"examiner_email, examiner_phone, notes, organizations.id as org_id, org_name, poc_name, poc_email, poc_phone "
585 +
"LEFT JOIN organizations ON cases.org_id=organizations.id";
588 preparedStatement = conn.prepareStatement(sql);
589 resultSet = preparedStatement.executeQuery();
590 while (resultSet.next()) {
591 eamCaseResult = getEamCaseFromResultSet(resultSet);
592 cases.add(eamCaseResult);
594 }
catch (SQLException ex) {
595 throw new CentralRepoException(
"Error getting all cases.", ex);
597 CentralRepoDbUtil.closeStatement(preparedStatement);
598 CentralRepoDbUtil.closeResultSet(resultSet);
599 CentralRepoDbUtil.closeConnection(conn);
615 private static String getDataSourceByDSObjectIdCacheKey(
int caseId, Long dataSourceObjectId) {
616 return "Case" + caseId +
"DsObjectId" + dataSourceObjectId;
628 private static String getDataSourceByIdCacheKey(
int caseId,
int dataSourceId) {
629 return "Case" + caseId +
"Id" + dataSourceId;
638 public CorrelationDataSource newDataSource(CorrelationDataSource eamDataSource)
throws CentralRepoException {
639 if (eamDataSource.getCaseID() == -1) {
640 throw new CentralRepoException(
"Case ID is -1");
642 if (eamDataSource.getDeviceID() == null) {
643 throw new CentralRepoException(
"Device ID is null");
645 if (eamDataSource.getName() == null) {
646 throw new CentralRepoException(
"Name is null");
648 if (eamDataSource.getID() != -1) {
650 return eamDataSource;
653 Connection conn = connect();
655 PreparedStatement preparedStatement = null;
657 String sql =
"INSERT INTO data_sources(device_id, case_id, name, datasource_obj_id, md5, sha1, sha256) VALUES (?, ?, ?, ?, ?, ?, ?) "
658 + getConflictClause();
659 ResultSet resultSet = null;
661 preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
663 preparedStatement.setString(1, eamDataSource.getDeviceID());
664 preparedStatement.setInt(2, eamDataSource.getCaseID());
665 preparedStatement.setString(3, eamDataSource.getName());
666 preparedStatement.setLong(4, eamDataSource.getDataSourceObjectID());
667 preparedStatement.setString(5, eamDataSource.getMd5());
668 preparedStatement.setString(6, eamDataSource.getSha1());
669 preparedStatement.setString(7, eamDataSource.getSha256());
671 preparedStatement.executeUpdate();
672 resultSet = preparedStatement.getGeneratedKeys();
673 if (!resultSet.next()) {
682 return dataSourceCacheByDsObjectId.get(getDataSourceByDSObjectIdCacheKey(
683 eamDataSource.getCaseID(), eamDataSource.getDataSourceObjectID()),
684 () -> getDataSourceFromCr(eamDataSource.getCaseID(), eamDataSource.getDataSourceObjectID()));
685 }
catch (CacheLoader.InvalidCacheLoadException | ExecutionException getException) {
686 throw new CentralRepoException(String.format(
"Unable to to INSERT or get data source %s in central repo:", eamDataSource.getName()), getException);
690 int dataSourceId = resultSet.getInt(1);
691 CorrelationDataSource dataSource =
new CorrelationDataSource(eamDataSource.getCaseID(), dataSourceId, eamDataSource.getDeviceID(), eamDataSource.getName(), eamDataSource.getDataSourceObjectID(), eamDataSource.getMd5(), eamDataSource.getSha1(), eamDataSource.getSha256());
692 dataSourceCacheByDsObjectId.put(getDataSourceByDSObjectIdCacheKey(dataSource.getCaseID(), dataSource.getDataSourceObjectID()), dataSource);
693 dataSourceCacheById.put(getDataSourceByIdCacheKey(dataSource.getCaseID(), dataSource.getID()), dataSource);
697 }
catch (SQLException insertException) {
707 return dataSourceCacheByDsObjectId.get(getDataSourceByDSObjectIdCacheKey(
708 eamDataSource.getCaseID(), eamDataSource.getDataSourceObjectID()),
709 () -> getDataSourceFromCr(eamDataSource.getCaseID(), eamDataSource.getDataSourceObjectID()));
710 }
catch (CacheLoader.InvalidCacheLoadException | ExecutionException getException) {
711 throw new CentralRepoException(String.format(
"Unable to to INSERT or get data source %s in central repo, insert failed due to Exception: %s", eamDataSource.getName(), insertException.getMessage()), getException);
714 CentralRepoDbUtil.closeResultSet(resultSet);
715 CentralRepoDbUtil.closeStatement(preparedStatement);
716 CentralRepoDbUtil.closeConnection(conn);
732 public CorrelationDataSource getDataSource(CorrelationCase correlationCase, Long dataSourceObjectId)
throws CentralRepoException {
734 if (correlationCase == null) {
735 throw new CentralRepoException(
"Correlation case is null");
738 return dataSourceCacheByDsObjectId.get(getDataSourceByDSObjectIdCacheKey(correlationCase.getID(), dataSourceObjectId), () -> getDataSourceFromCr(correlationCase.getID(), dataSourceObjectId));
739 }
catch (CacheLoader.InvalidCacheLoadException ignored) {
742 }
catch (ExecutionException ex) {
743 throw new CentralRepoException(
"Error getting data source from central repository", ex);
759 private CorrelationDataSource getDataSourceFromCr(
int correlationCaseId, Long dataSourceObjectId)
throws CentralRepoException {
760 Connection conn = connect();
762 CorrelationDataSource eamDataSourceResult = null;
763 PreparedStatement preparedStatement = null;
764 ResultSet resultSet = null;
766 String sql =
"SELECT * FROM data_sources WHERE datasource_obj_id=? AND case_id=?";
769 preparedStatement = conn.prepareStatement(sql);
770 preparedStatement.setLong(1, dataSourceObjectId);
771 preparedStatement.setInt(2, correlationCaseId);
772 resultSet = preparedStatement.executeQuery();
773 if (resultSet.next()) {
774 eamDataSourceResult = getEamDataSourceFromResultSet(resultSet);
776 if (eamDataSourceResult != null) {
777 dataSourceCacheById.put(getDataSourceByIdCacheKey(correlationCaseId, eamDataSourceResult.getID()), eamDataSourceResult);
779 }
catch (SQLException ex) {
780 throw new CentralRepoException(
"Error getting data source.", ex);
782 CentralRepoDbUtil.closeStatement(preparedStatement);
783 CentralRepoDbUtil.closeResultSet(resultSet);
784 CentralRepoDbUtil.closeConnection(conn);
787 return eamDataSourceResult;
800 public CorrelationDataSource getDataSourceById(CorrelationCase correlationCase,
int dataSourceId)
throws CentralRepoException {
801 if (correlationCase == null) {
802 throw new CentralRepoException(
"Correlation case is null");
805 return dataSourceCacheById.get(getDataSourceByIdCacheKey(correlationCase.getID(), dataSourceId), () -> getDataSourceByIdFromCr(correlationCase, dataSourceId));
806 }
catch (CacheLoader.InvalidCacheLoadException ignored) {
809 }
catch (ExecutionException ex) {
810 throw new CentralRepoException(
"Error getting data source from central repository", ex);
823 private CorrelationDataSource getDataSourceByIdFromCr(CorrelationCase correlationCase,
int dataSourceId)
throws CentralRepoException {
824 Connection conn = connect();
826 CorrelationDataSource eamDataSourceResult = null;
827 PreparedStatement preparedStatement = null;
828 ResultSet resultSet = null;
830 String sql =
"SELECT * FROM data_sources WHERE id=? AND case_id=?";
833 preparedStatement = conn.prepareStatement(sql);
834 preparedStatement.setInt(1, dataSourceId);
835 preparedStatement.setInt(2, correlationCase.getID());
836 resultSet = preparedStatement.executeQuery();
837 if (resultSet.next()) {
838 eamDataSourceResult = getEamDataSourceFromResultSet(resultSet);
840 if (eamDataSourceResult != null) {
841 dataSourceCacheByDsObjectId.put(getDataSourceByDSObjectIdCacheKey(correlationCase.getID(), eamDataSourceResult.getDataSourceObjectID()), eamDataSourceResult);
843 }
catch (SQLException ex) {
844 throw new CentralRepoException(
"Error getting data source.", ex);
846 CentralRepoDbUtil.closeStatement(preparedStatement);
847 CentralRepoDbUtil.closeResultSet(resultSet);
848 CentralRepoDbUtil.closeConnection(conn);
851 return eamDataSourceResult;
860 public List<CorrelationDataSource> getDataSources() throws CentralRepoException {
861 Connection conn = connect();
863 List<CorrelationDataSource> dataSources =
new ArrayList<>();
864 CorrelationDataSource eamDataSourceResult;
865 PreparedStatement preparedStatement = null;
866 ResultSet resultSet = null;
868 String sql =
"SELECT * FROM data_sources";
871 preparedStatement = conn.prepareStatement(sql);
872 resultSet = preparedStatement.executeQuery();
873 while (resultSet.next()) {
874 eamDataSourceResult = getEamDataSourceFromResultSet(resultSet);
875 dataSources.add(eamDataSourceResult);
877 }
catch (SQLException ex) {
878 throw new CentralRepoException(
"Error getting all data sources.", ex);
880 CentralRepoDbUtil.closeStatement(preparedStatement);
881 CentralRepoDbUtil.closeResultSet(resultSet);
882 CentralRepoDbUtil.closeConnection(conn);
894 public void updateDataSourceMd5Hash(CorrelationDataSource eamDataSource)
throws CentralRepoException {
895 updateDataSourceStringValue(eamDataSource,
"md5", eamDataSource.getMd5());
904 public void updateDataSourceSha1Hash(CorrelationDataSource eamDataSource)
throws CentralRepoException {
905 updateDataSourceStringValue(eamDataSource,
"sha1", eamDataSource.getSha1());
915 public void updateDataSourceSha256Hash(CorrelationDataSource eamDataSource)
throws CentralRepoException {
916 updateDataSourceStringValue(eamDataSource,
"sha256", eamDataSource.getSha256());
926 private void updateDataSourceStringValue(CorrelationDataSource eamDataSource, String column, String value)
throws CentralRepoException {
927 if (eamDataSource == null) {
928 throw new CentralRepoException(
"Correlation data source is null");
931 Connection conn = connect();
933 PreparedStatement preparedStatement = null;
934 String sql =
"UPDATE data_sources "
935 +
"SET " + column +
"=? "
939 preparedStatement = conn.prepareStatement(sql);
941 preparedStatement.setString(1, value);
942 preparedStatement.setInt(2, eamDataSource.getID());
944 preparedStatement.executeUpdate();
946 dataSourceCacheByDsObjectId.put(getDataSourceByDSObjectIdCacheKey(eamDataSource.getCaseID(), eamDataSource.getDataSourceObjectID()), eamDataSource);
947 dataSourceCacheById.put(getDataSourceByIdCacheKey(eamDataSource.getCaseID(), eamDataSource.getID()), eamDataSource);
948 }
catch (SQLException ex) {
949 throw new CentralRepoException(String.format(
"Error updating data source (obj_id=%d).", eamDataSource.getDataSourceObjectID()), ex);
951 CentralRepoDbUtil.closeStatement(preparedStatement);
952 CentralRepoDbUtil.closeConnection(conn);
965 public void updateDataSourceName(CorrelationDataSource eamDataSource, String newName)
throws CentralRepoException {
967 Connection conn = connect();
969 PreparedStatement preparedStatement = null;
971 String sql =
"UPDATE data_sources SET name = ? WHERE id = ?";
974 preparedStatement = conn.prepareStatement(sql);
975 preparedStatement.setString(1, newName);
976 preparedStatement.setInt(2, eamDataSource.getID());
977 preparedStatement.executeUpdate();
979 CorrelationDataSource updatedDataSource =
new CorrelationDataSource(
980 eamDataSource.getCaseID(),
981 eamDataSource.getID(),
982 eamDataSource.getDeviceID(),
984 eamDataSource.getDataSourceObjectID(),
985 eamDataSource.getMd5(),
986 eamDataSource.getSha1(),
987 eamDataSource.getSha256());
989 dataSourceCacheByDsObjectId.put(getDataSourceByDSObjectIdCacheKey(updatedDataSource.getCaseID(), updatedDataSource.getDataSourceObjectID()), updatedDataSource);
990 dataSourceCacheById.put(getDataSourceByIdCacheKey(updatedDataSource.getCaseID(), updatedDataSource.getID()), updatedDataSource);
991 }
catch (SQLException ex) {
992 throw new CentralRepoException(
"Error updating name of data source with ID " + eamDataSource.getDataSourceObjectID()
993 +
" to " + newName, ex);
995 CentralRepoDbUtil.closeStatement(preparedStatement);
996 CentralRepoDbUtil.closeConnection(conn);
1007 public void addArtifactInstance(CorrelationAttributeInstance eamArtifact)
throws CentralRepoException {
1008 checkAddArtifactInstanceNulls(eamArtifact);
1011 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType());
1012 boolean artifactHasAnAccount = CentralRepoDbUtil.correlationAttribHasAnAccount(eamArtifact.getCorrelationType());
1016 if (artifactHasAnAccount) {
1017 sql =
"INSERT INTO "
1019 +
"(case_id, data_source_id, value, file_path, known_status, comment, file_obj_id, account_id) "
1020 +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?) "
1021 + getConflictClause();
1024 sql =
"INSERT INTO "
1026 +
"(case_id, data_source_id, value, file_path, known_status, comment, file_obj_id) "
1027 +
"VALUES (?, ?, ?, ?, ?, ?, ?) "
1028 + getConflictClause();
1031 try (Connection conn = connect();
1032 PreparedStatement preparedStatement = conn.prepareStatement(sql);) {
1034 if (!eamArtifact.getCorrelationValue().isEmpty()) {
1035 preparedStatement.setInt(1, eamArtifact.getCorrelationCase().getID());
1036 preparedStatement.setInt(2, eamArtifact.getCorrelationDataSource().getID());
1037 preparedStatement.setString(3, eamArtifact.getCorrelationValue());
1038 preparedStatement.setString(4, eamArtifact.getFilePath().toLowerCase());
1039 preparedStatement.setByte(5, eamArtifact.getKnownStatus().getFileKnownValue());
1041 if (
"".equals(eamArtifact.getComment())) {
1042 preparedStatement.setNull(6, Types.INTEGER);
1044 preparedStatement.setString(6, eamArtifact.getComment());
1046 preparedStatement.setLong(7, eamArtifact.getFileObjectId());
1049 if (artifactHasAnAccount) {
1050 if (eamArtifact.getAccountId() >= 0) {
1051 preparedStatement.setLong(8, eamArtifact.getAccountId());
1053 preparedStatement.setNull(8, Types.INTEGER);
1057 preparedStatement.executeUpdate();
1060 }
catch (SQLException ex) {
1061 throw new CentralRepoException(
"Error inserting new artifact into artifacts table.", ex);
1078 public CentralRepoAccount
getOrCreateAccount(CentralRepoAccountType crAccountType, String accountUniqueID)
throws CentralRepoException {
1080 CentralRepoAccount account = getAccount(crAccountType, accountUniqueID);
1083 if (null == account) {
1085 String query =
"INSERT INTO accounts (account_type_id, account_unique_identifier) "
1086 +
"VALUES ( " + crAccountType.getAccountTypeId() +
", '"
1087 + accountUniqueID +
"' )";
1089 try (Connection connection = connect();
1090 Statement s = connection.createStatement();) {
1094 account = getAccount(crAccountType, accountUniqueID);
1095 }
catch (SQLException ex) {
1096 throw new CentralRepoException(
"Error adding an account to CR database.", ex);
1105 public CentralRepoAccountType getAccountTypeByName(String accountTypeName)
throws CentralRepoException {
1107 return accountTypesCache.get(accountTypeName, () -> getCRAccountTypeFromDb(accountTypeName));
1108 }
catch (CacheLoader.InvalidCacheLoadException | ExecutionException ex) {
1109 throw new CentralRepoException(
"Error looking up CR account type in cache.", ex);
1122 private CentralRepoAccountType getCRAccountTypeFromDb(String accountTypeName)
throws CentralRepoException {
1124 String sql =
"SELECT * FROM account_types WHERE type_name = ?";
1125 try ( Connection conn = connect();
1126 PreparedStatement preparedStatement = conn.prepareStatement(sql);) {
1128 preparedStatement.setString(1, accountTypeName);
1129 try (ResultSet resultSet = preparedStatement.executeQuery();) {
1130 if (resultSet.next()) {
1131 Account.Type acctType =
new Account.Type(accountTypeName, resultSet.getString(
"display_name"));
1132 CentralRepoAccountType crAccountType =
new CentralRepoAccountType(resultSet.getInt(
"id"), acctType, resultSet.getInt(
"correlation_type_id"));
1133 accountTypesCache.put(accountTypeName, crAccountType);
1134 return crAccountType;
1136 throw new CentralRepoException(
"Failed to find entry for account type = " + accountTypeName);
1139 }
catch (SQLException ex) {
1140 throw new CentralRepoException(
"Error getting correlation type by id.", ex);
1157 private CentralRepoAccount getAccount(CentralRepoAccountType crAccountType, String accountUniqueID)
throws CentralRepoException {
1159 CentralRepoAccount crAccount = accountsCache.getIfPresent(Pair.of(crAccountType, accountUniqueID));
1160 if (crAccount == null) {
1161 crAccount = getCRAccountFromDb(crAccountType, accountUniqueID);
1162 if (crAccount != null) {
1163 accountsCache.put(Pair.of(crAccountType, accountUniqueID), crAccount);
1183 private CentralRepoAccount getCRAccountFromDb(CentralRepoAccountType crAccountType, String accountUniqueID)
throws CentralRepoException {
1185 CentralRepoAccount account = null;
1187 String sql =
"SELECT * FROM accounts WHERE account_type_id = ? AND account_unique_identifier = ?";
1188 try ( Connection connection = connect();
1189 PreparedStatement preparedStatement = connection.prepareStatement(sql);) {
1191 preparedStatement.setInt(1, crAccountType.getAccountTypeId());
1192 preparedStatement.setString(2, accountUniqueID);
1194 try (ResultSet resultSet = preparedStatement.executeQuery();) {
1195 if (resultSet.next()) {
1196 account =
new CentralRepoAccount(resultSet.getInt(
"id"), crAccountType, resultSet.getString(
"account_unique_identifier"));
1199 }
catch (SQLException ex) {
1200 throw new CentralRepoException(
"Error getting account type id", ex);
1207 private void checkAddArtifactInstanceNulls(CorrelationAttributeInstance eamArtifact)
throws CentralRepoException {
1208 if (eamArtifact == null) {
1209 throw new CentralRepoException(
"CorrelationAttribute is null");
1211 if (eamArtifact.getCorrelationType() == null) {
1212 throw new CentralRepoException(
"Correlation type is null");
1214 if (eamArtifact.getCorrelationValue() == null) {
1215 throw new CentralRepoException(
"Correlation value is null");
1217 if (eamArtifact.getCorrelationValue().length() >= MAX_VALUE_LENGTH) {
1218 throw new CentralRepoException(
"Artifact value too long for central repository."
1219 +
"\nCorrelationArtifact ID: " + eamArtifact.getID()
1220 +
"\nCorrelationArtifact Type: " + eamArtifact.getCorrelationType().getDisplayName()
1221 +
"\nCorrelationArtifact Value: " + eamArtifact.getCorrelationValue());
1224 if (eamArtifact.getCorrelationCase() == null) {
1225 throw new CentralRepoException(
"CorrelationAttributeInstance case is null");
1227 if (eamArtifact.getCorrelationDataSource() == null) {
1228 throw new CentralRepoException(
"CorrelationAttributeInstance data source is null");
1230 if (eamArtifact.getKnownStatus() == null) {
1231 throw new CentralRepoException(
"CorrelationAttributeInstance known status is null");
1236 public List<CorrelationAttributeInstance> getArtifactInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1237 if (value == null) {
1238 throw new CorrelationAttributeNormalizationException(
"Cannot get artifact instances for null value");
1240 return getArtifactInstancesByTypeValues(aType, Arrays.asList(value));
1244 public List<CorrelationAttributeInstance> getArtifactInstancesByTypeValues(CorrelationAttributeInstance.Type aType, List<String> values)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1245 if (aType == null) {
1246 throw new CorrelationAttributeNormalizationException(
"Cannot get artifact instances for null type");
1248 if (values == null || values.isEmpty()) {
1249 throw new CorrelationAttributeNormalizationException(
"Cannot get artifact instances without specified values");
1251 return getArtifactInstances(prepareGetInstancesSql(aType, values), aType);
1255 public List<CorrelationAttributeInstance> getArtifactInstancesByTypeValuesAndCases(CorrelationAttributeInstance.Type aType, List<String> values, List<Integer> caseIds)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1256 if (aType == null) {
1257 throw new CorrelationAttributeNormalizationException(
"Cannot get artifact instances for null type");
1259 if (values == null || values.isEmpty()) {
1260 throw new CorrelationAttributeNormalizationException(
"Cannot get artifact instances without specified values");
1262 if (caseIds == null || caseIds.isEmpty()) {
1263 throw new CorrelationAttributeNormalizationException(
"Cannot get artifact instances without specified cases");
1265 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(aType);
1270 StringBuilder inValuesBuilder =
new StringBuilder(prepareGetInstancesSql(aType, values));
1271 inValuesBuilder.append(sql);
1272 inValuesBuilder.append(caseIds.stream().map(String::valueOf).collect(Collectors.joining(
"', '")));
1273 inValuesBuilder.append(
"')");
1274 return getArtifactInstances(inValuesBuilder.toString(), aType);
1289 private String prepareGetInstancesSql(CorrelationAttributeInstance.Type aType, List<String> values)
throws CorrelationAttributeNormalizationException {
1290 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(aType);
1294 +
".id as instance_id,"
1299 +
" cases.*, organizations.org_name, organizations.poc_name, organizations.poc_email, organizations.poc_phone, data_sources.id AS data_source_id, data_sources.name, device_id, file_path, known_status, comment, data_sources.datasource_obj_id, data_sources.md5, data_sources.sha1, data_sources.sha256 FROM "
1301 +
" LEFT JOIN cases ON "
1303 +
".case_id=cases.id"
1304 +
" LEFT JOIN organizations ON cases.org_id=organizations.id"
1305 +
" LEFT JOIN data_sources ON "
1307 +
".data_source_id=data_sources.id"
1308 +
" WHERE value IN (";
1309 StringBuilder inValuesBuilder =
new StringBuilder(sql);
1310 for (String value : values) {
1311 if (value != null) {
1312 inValuesBuilder.append(
"'");
1313 inValuesBuilder.append(CorrelationAttributeNormalizer.normalize(aType, value));
1314 inValuesBuilder.append(
"',");
1317 inValuesBuilder.deleteCharAt(inValuesBuilder.length() - 1);
1318 inValuesBuilder.append(
")");
1319 return inValuesBuilder.toString();
1336 private List<CorrelationAttributeInstance> getArtifactInstances(String sql, CorrelationAttributeInstance.Type aType) throws CorrelationAttributeNormalizationException, CentralRepoException {
1337 Connection conn = connect();
1338 List<CorrelationAttributeInstance> artifactInstances =
new ArrayList<>();
1339 CorrelationAttributeInstance artifactInstance;
1340 PreparedStatement preparedStatement = null;
1341 ResultSet resultSet = null;
1343 preparedStatement = conn.prepareStatement(sql);
1344 resultSet = preparedStatement.executeQuery();
1345 while (resultSet.next()) {
1346 artifactInstance = getEamArtifactInstanceFromResultSet(resultSet, aType);
1347 artifactInstances.add(artifactInstance);
1349 }
catch (SQLException ex) {
1350 throw new CentralRepoException(
"Error getting artifact instances by artifactType and artifactValue.", ex);
1352 CentralRepoDbUtil.closeStatement(preparedStatement);
1353 CentralRepoDbUtil.closeResultSet(resultSet);
1354 CentralRepoDbUtil.closeConnection(conn);
1356 return artifactInstances;
1370 public Long getCountArtifactInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1371 String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
1373 Connection conn = connect();
1375 Long instanceCount = 0L;
1376 PreparedStatement preparedStatement = null;
1377 ResultSet resultSet = null;
1379 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(aType);
1381 =
"SELECT count(*) FROM "
1386 preparedStatement = conn.prepareStatement(sql);
1387 preparedStatement.setString(1, normalizedValue);
1388 resultSet = preparedStatement.executeQuery();
1390 instanceCount = resultSet.getLong(1);
1391 }
catch (SQLException ex) {
1392 throw new CentralRepoException(
"Error getting count of artifact instances by artifactType and artifactValue.", ex);
1394 CentralRepoDbUtil.closeStatement(preparedStatement);
1395 CentralRepoDbUtil.closeResultSet(resultSet);
1396 CentralRepoDbUtil.closeConnection(conn);
1399 return instanceCount;
1403 public int getFrequencyPercentage(CorrelationAttributeInstance corAttr)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1404 if (corAttr == null) {
1405 throw new CentralRepoException(
"CorrelationAttribute is null");
1407 Double uniqueTypeValueTuples = getCountUniqueCaseDataSourceTuplesHavingTypeValue(corAttr.getCorrelationType(), corAttr.getCorrelationValue()).doubleValue();
1408 Double uniqueCaseDataSourceTuples = getCountUniqueDataSources().doubleValue();
1409 Double commonalityPercentage = uniqueTypeValueTuples / uniqueCaseDataSourceTuples * 100;
1410 return commonalityPercentage.intValue();
1424 public Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1425 String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
1427 Connection conn = connect();
1429 Long instanceCount = 0L;
1430 PreparedStatement preparedStatement = null;
1431 ResultSet resultSet = null;
1433 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(aType);
1435 =
"SELECT count(*) FROM (SELECT DISTINCT case_id, data_source_id FROM "
1437 +
" WHERE value=?) AS "
1439 +
"_distinct_case_data_source_tuple";
1442 preparedStatement = conn.prepareStatement(sql);
1443 preparedStatement.setString(1, normalizedValue);
1444 resultSet = preparedStatement.executeQuery();
1446 instanceCount = resultSet.getLong(1);
1447 }
catch (SQLException ex) {
1448 throw new CentralRepoException(
"Error counting unique caseDisplayName/dataSource tuples having artifactType and artifactValue.", ex);
1450 CentralRepoDbUtil.closeStatement(preparedStatement);
1451 CentralRepoDbUtil.closeResultSet(resultSet);
1452 CentralRepoDbUtil.closeConnection(conn);
1455 return instanceCount;
1459 public Long getCountUniqueDataSources() throws CentralRepoException {
1460 Connection conn = connect();
1462 Long instanceCount = 0L;
1463 PreparedStatement preparedStatement = null;
1464 ResultSet resultSet = null;
1466 String stmt =
"SELECT count(*) FROM data_sources";
1469 preparedStatement = conn.prepareStatement(stmt);
1470 resultSet = preparedStatement.executeQuery();
1472 instanceCount = resultSet.getLong(1);
1473 }
catch (SQLException ex) {
1474 throw new CentralRepoException(
"Error counting data sources.", ex);
1476 CentralRepoDbUtil.closeStatement(preparedStatement);
1477 CentralRepoDbUtil.closeResultSet(resultSet);
1478 CentralRepoDbUtil.closeConnection(conn);
1481 return instanceCount;
1496 public Long getCountArtifactInstancesByCaseDataSource(CorrelationDataSource correlationDataSource)
throws CentralRepoException {
1497 Connection conn = connect();
1499 Long instanceCount = 0L;
1500 List<CorrelationAttributeInstance.Type> artifactTypes = getDefinedCorrelationTypes();
1501 PreparedStatement preparedStatement = null;
1502 ResultSet resultSet = null;
1505 String sql =
"SELECT 0 ";
1507 for (CorrelationAttributeInstance.Type type : artifactTypes) {
1508 String table_name = CentralRepoDbUtil.correlationTypeToInstanceTableName(type);
1510 +=
"+ (SELECT count(*) FROM "
1512 +
" WHERE data_source_id=" + correlationDataSource.getID() +
")";
1515 preparedStatement = conn.prepareStatement(sql);
1517 resultSet = preparedStatement.executeQuery();
1519 instanceCount = resultSet.getLong(1);
1520 }
catch (SQLException ex) {
1521 throw new CentralRepoException(
"Error counting artifact instances by caseName/dataSource.", ex);
1523 CentralRepoDbUtil.closeStatement(preparedStatement);
1524 CentralRepoDbUtil.closeResultSet(resultSet);
1525 CentralRepoDbUtil.closeConnection(conn);
1528 return instanceCount;
1539 public void addAttributeInstanceBulk(CorrelationAttributeInstance eamArtifact)
throws CentralRepoException {
1541 if (eamArtifact.getCorrelationType() == null) {
1542 throw new CentralRepoException(
"Correlation type is null");
1545 synchronized (bulkArtifacts) {
1546 if (bulkArtifacts.get(CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType())) == null) {
1547 bulkArtifacts.put(CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType()),
new ArrayList<>());
1549 bulkArtifacts.get(CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType())).add(eamArtifact);
1550 bulkArtifactsCount++;
1552 if (bulkArtifactsCount >= bulkArtifactsThreshold) {
1553 commitAttributeInstancesBulk();
1563 protected abstract String getConflictClause();
1570 public void commitAttributeInstancesBulk() throws CentralRepoException {
1571 List<CorrelationAttributeInstance.Type> artifactTypes = getDefinedCorrelationTypes();
1573 Connection conn = connect();
1574 PreparedStatement bulkPs = null;
1577 synchronized (bulkArtifacts) {
1578 if (bulkArtifactsCount == 0) {
1582 for (String tableName : bulkArtifacts.keySet()) {
1587 +
" (case_id, data_source_id, value, file_path, known_status, comment, file_obj_id) "
1588 +
"VALUES ((SELECT id FROM cases WHERE case_uid=? LIMIT 1), "
1589 +
"(SELECT id FROM data_sources WHERE datasource_obj_id=? AND case_id=? LIMIT 1), ?, ?, ?, ?, ?) "
1590 + getConflictClause();
1592 bulkPs = conn.prepareStatement(sql);
1594 Collection<CorrelationAttributeInstance> eamArtifacts = bulkArtifacts.get(tableName);
1595 for (CorrelationAttributeInstance eamArtifact : eamArtifacts) {
1597 if (!eamArtifact.getCorrelationValue().isEmpty()) {
1599 if (eamArtifact.getCorrelationCase() == null) {
1600 throw new CentralRepoException(
"CorrelationAttributeInstance case is null for: "
1601 +
"\n\tCorrelationArtifact ID: " + eamArtifact.getID()
1602 +
"\n\tCorrelationArtifact Type: " + eamArtifact.getCorrelationType().getDisplayName()
1603 +
"\n\tCorrelationArtifact Value: " + eamArtifact.getCorrelationValue());
1605 if (eamArtifact.getCorrelationDataSource() == null) {
1606 throw new CentralRepoException(
"CorrelationAttributeInstance data source is null for: "
1607 +
"\n\tCorrelationArtifact ID: " + eamArtifact.getID()
1608 +
"\n\tCorrelationArtifact Type: " + eamArtifact.getCorrelationType().getDisplayName()
1609 +
"\n\tCorrelationArtifact Value: " + eamArtifact.getCorrelationValue());
1611 if (eamArtifact.getKnownStatus() == null) {
1612 throw new CentralRepoException(
"CorrelationAttributeInstance known status is null for: "
1613 +
"\n\tCorrelationArtifact ID: " + eamArtifact.getID()
1614 +
"\n\tCorrelationArtifact Type: " + eamArtifact.getCorrelationType().getDisplayName()
1615 +
"\n\tCorrelationArtifact Value: " + eamArtifact.getCorrelationValue()
1616 +
"\n\tEam Instance: "
1617 +
"\n\t\tCaseId: " + eamArtifact.getCorrelationDataSource().getCaseID()
1618 +
"\n\t\tDeviceID: " + eamArtifact.getCorrelationDataSource().getDeviceID());
1621 if (eamArtifact.getCorrelationValue().length() < MAX_VALUE_LENGTH) {
1622 bulkPs.setString(1, eamArtifact.getCorrelationCase().getCaseUUID());
1623 bulkPs.setLong(2, eamArtifact.getCorrelationDataSource().getDataSourceObjectID());
1624 bulkPs.setInt(3, eamArtifact.getCorrelationDataSource().getCaseID());
1625 bulkPs.setString(4, eamArtifact.getCorrelationValue());
1626 bulkPs.setString(5, eamArtifact.getFilePath());
1627 bulkPs.setByte(6, eamArtifact.getKnownStatus().getFileKnownValue());
1628 if (
"".equals(eamArtifact.getComment())) {
1629 bulkPs.setNull(7, Types.INTEGER);
1631 bulkPs.setString(7, eamArtifact.getComment());
1633 bulkPs.setLong(8, eamArtifact.getFileObjectId());
1636 logger.log(Level.WARNING, (
"Artifact value too long for central repository."
1637 +
"\n\tCorrelationArtifact ID: " + eamArtifact.getID()
1638 +
"\n\tCorrelationArtifact Type: " + eamArtifact.getCorrelationType().getDisplayName()
1639 +
"\n\tCorrelationArtifact Value: " + eamArtifact.getCorrelationValue())
1640 +
"\n\tEam Instance: "
1641 +
"\n\t\tCaseId: " + eamArtifact.getCorrelationDataSource().getCaseID()
1642 +
"\n\t\tDeviceID: " + eamArtifact.getCorrelationDataSource().getDeviceID()
1643 +
"\n\t\tFilePath: " + eamArtifact.getFilePath());
1649 bulkPs.executeBatch();
1650 bulkArtifacts.get(tableName).clear();
1653 TimingMetric timingMetric = HealthMonitor.getTimingMetric(
"Correlation Engine: Bulk insert");
1654 HealthMonitor.submitTimingMetric(timingMetric);
1657 bulkArtifactsCount = 0;
1659 }
catch (SQLException ex) {
1660 throw new CentralRepoException(
"Error inserting bulk artifacts.", ex);
1662 CentralRepoDbUtil.closeStatement(bulkPs);
1663 CentralRepoDbUtil.closeConnection(conn);
1671 public void bulkInsertCases(List<CorrelationCase> cases)
throws CentralRepoException {
1672 if (cases == null) {
1673 throw new CentralRepoException(
"cases argument is null");
1676 if (cases.isEmpty()) {
1680 Connection conn = connect();
1683 PreparedStatement bulkPs = null;
1685 String sql =
"INSERT INTO cases(case_uid, org_id, case_name, creation_date, case_number, "
1686 +
"examiner_name, examiner_email, examiner_phone, notes) "
1687 +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) "
1688 + getConflictClause();
1689 bulkPs = conn.prepareStatement(sql);
1691 for (CorrelationCase eamCase : cases) {
1692 bulkPs.setString(1, eamCase.getCaseUUID());
1693 if (null == eamCase.getOrg()) {
1694 bulkPs.setNull(2, Types.INTEGER);
1696 bulkPs.setInt(2, eamCase.getOrg().getOrgID());
1698 bulkPs.setString(3, eamCase.getDisplayName());
1699 bulkPs.setString(4, eamCase.getCreationDate());
1701 if (
"".equals(eamCase.getCaseNumber())) {
1702 bulkPs.setNull(5, Types.INTEGER);
1704 bulkPs.setString(5, eamCase.getCaseNumber());
1706 if (
"".equals(eamCase.getExaminerName())) {
1707 bulkPs.setNull(6, Types.INTEGER);
1709 bulkPs.setString(6, eamCase.getExaminerName());
1711 if (
"".equals(eamCase.getExaminerEmail())) {
1712 bulkPs.setNull(7, Types.INTEGER);
1714 bulkPs.setString(7, eamCase.getExaminerEmail());
1716 if (
"".equals(eamCase.getExaminerPhone())) {
1717 bulkPs.setNull(8, Types.INTEGER);
1719 bulkPs.setString(8, eamCase.getExaminerPhone());
1721 if (
"".equals(eamCase.getNotes())) {
1722 bulkPs.setNull(9, Types.INTEGER);
1724 bulkPs.setString(9, eamCase.getNotes());
1732 if (counter >= bulkArtifactsThreshold) {
1733 bulkPs.executeBatch();
1738 bulkPs.executeBatch();
1739 }
catch (SQLException ex) {
1740 throw new CentralRepoException(
"Error inserting bulk cases.", ex);
1742 CentralRepoDbUtil.closeStatement(bulkPs);
1743 CentralRepoDbUtil.closeConnection(conn);
1757 public void updateAttributeInstanceComment(CorrelationAttributeInstance eamArtifact)
throws CentralRepoException {
1759 if (eamArtifact == null) {
1760 throw new CentralRepoException(
"CorrelationAttributeInstance is null");
1762 if (eamArtifact.getCorrelationCase() == null) {
1763 throw new CentralRepoException(
"Correlation case is null");
1765 if (eamArtifact.getCorrelationDataSource() == null) {
1766 throw new CentralRepoException(
"Correlation data source is null");
1768 Connection conn = connect();
1769 PreparedStatement preparedQuery = null;
1770 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType());
1775 +
"WHERE case_id=? "
1776 +
"AND data_source_id=? "
1778 +
"AND file_path=?";
1781 preparedQuery = conn.prepareStatement(sqlUpdate);
1782 preparedQuery.setString(1, eamArtifact.getComment());
1783 preparedQuery.setInt(2, eamArtifact.getCorrelationCase().getID());
1784 preparedQuery.setInt(3, eamArtifact.getCorrelationDataSource().getID());
1785 preparedQuery.setString(4, eamArtifact.getCorrelationValue());
1786 preparedQuery.setString(5, eamArtifact.getFilePath().toLowerCase());
1787 preparedQuery.executeUpdate();
1788 }
catch (SQLException ex) {
1789 throw new CentralRepoException(
"Error getting/setting artifact instance comment=" + eamArtifact.getComment(), ex);
1791 CentralRepoDbUtil.closeStatement(preparedQuery);
1792 CentralRepoDbUtil.closeConnection(conn);
1811 public CorrelationAttributeInstance getCorrelationAttributeInstance(CorrelationAttributeInstance.Type type, CorrelationCase correlationCase,
1812 CorrelationDataSource correlationDataSource,
long objectID)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1814 if (correlationCase == null) {
1815 throw new CentralRepoException(
"Correlation case is null");
1818 Connection conn = connect();
1820 PreparedStatement preparedStatement = null;
1821 ResultSet resultSet = null;
1822 CorrelationAttributeInstance correlationAttributeInstance = null;
1826 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(type);
1828 =
"SELECT id, value, file_path, known_status, comment FROM "
1830 +
" WHERE case_id=?"
1831 +
" AND file_obj_id=?";
1833 preparedStatement = conn.prepareStatement(sql);
1834 preparedStatement.setInt(1, correlationCase.getID());
1835 preparedStatement.setInt(2, (
int) objectID);
1836 resultSet = preparedStatement.executeQuery();
1837 if (resultSet.next()) {
1838 int instanceId = resultSet.getInt(1);
1839 String value = resultSet.getString(2);
1840 String filePath = resultSet.getString(3);
1841 int knownStatus = resultSet.getInt(4);
1842 String comment = resultSet.getString(5);
1844 correlationAttributeInstance =
new CorrelationAttributeInstance(type, value,
1845 instanceId, correlationCase, correlationDataSource, filePath, comment, TskData.FileKnown.valueOf((byte) knownStatus), objectID);
1847 }
catch (SQLException ex) {
1848 throw new CentralRepoException(
"Error getting notable artifact instances.", ex);
1850 CentralRepoDbUtil.closeStatement(preparedStatement);
1851 CentralRepoDbUtil.closeResultSet(resultSet);
1852 CentralRepoDbUtil.closeConnection(conn);
1855 return correlationAttributeInstance;
1873 public CorrelationAttributeInstance getCorrelationAttributeInstance(CorrelationAttributeInstance.Type type, CorrelationCase correlationCase,
1874 CorrelationDataSource correlationDataSource, String value, String filePath)
throws CentralRepoException, CorrelationAttributeNormalizationException {
1876 if (correlationCase == null) {
1877 throw new CentralRepoException(
"Correlation case is null");
1879 if (correlationDataSource == null) {
1880 throw new CentralRepoException(
"Correlation data source is null");
1882 if (filePath == null) {
1883 throw new CentralRepoException(
"Correlation file path is null");
1886 Connection conn = connect();
1888 PreparedStatement preparedStatement = null;
1889 ResultSet resultSet = null;
1890 CorrelationAttributeInstance correlationAttributeInstance = null;
1893 String normalizedValue = CorrelationAttributeNormalizer.normalize(type, value);
1895 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(type);
1897 =
"SELECT id, known_status, comment FROM "
1899 +
" WHERE case_id=?"
1900 +
" AND data_source_id=?"
1902 +
" AND file_path=?";
1904 preparedStatement = conn.prepareStatement(sql);
1905 preparedStatement.setInt(1, correlationCase.getID());
1906 preparedStatement.setInt(2, correlationDataSource.getID());
1907 preparedStatement.setString(3, normalizedValue);
1908 preparedStatement.setString(4, filePath.toLowerCase());
1909 resultSet = preparedStatement.executeQuery();
1910 if (resultSet.next()) {
1911 int instanceId = resultSet.getInt(1);
1912 int knownStatus = resultSet.getInt(2);
1913 String comment = resultSet.getString(3);
1915 correlationAttributeInstance =
new CorrelationAttributeInstance(type, value,
1916 instanceId, correlationCase, correlationDataSource, filePath, comment, TskData.FileKnown.valueOf((byte) knownStatus), null);
1918 }
catch (SQLException ex) {
1919 throw new CentralRepoException(
"Error getting notable artifact instances.", ex);
1921 CentralRepoDbUtil.closeStatement(preparedStatement);
1922 CentralRepoDbUtil.closeResultSet(resultSet);
1923 CentralRepoDbUtil.closeConnection(conn);
1926 return correlationAttributeInstance;
1940 public void setAttributeInstanceKnownStatus(CorrelationAttributeInstance eamArtifact, TskData.FileKnown knownStatus) throws CentralRepoException {
1941 if (eamArtifact == null) {
1942 throw new CentralRepoException(
"CorrelationAttribute is null");
1944 if (knownStatus == null) {
1945 throw new CentralRepoException(
"Known status is null");
1948 if (eamArtifact.getCorrelationCase() == null) {
1949 throw new CentralRepoException(
"Correlation case is null");
1951 if (eamArtifact.getCorrelationDataSource() == null) {
1952 throw new CentralRepoException(
"Correlation data source is null");
1955 Connection conn = connect();
1957 PreparedStatement preparedUpdate = null;
1958 PreparedStatement preparedQuery = null;
1959 ResultSet resultSet = null;
1961 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType());
1966 +
" WHERE case_id=? "
1967 +
"AND data_source_id=? "
1969 +
"AND file_path=?";
1974 +
" SET known_status=?, comment=? "
1978 preparedQuery = conn.prepareStatement(sqlQuery);
1979 preparedQuery.setInt(1, eamArtifact.getCorrelationCase().getID());
1980 preparedQuery.setInt(2, eamArtifact.getCorrelationDataSource().getID());
1981 preparedQuery.setString(3, eamArtifact.getCorrelationValue());
1982 preparedQuery.setString(4, eamArtifact.getFilePath());
1983 resultSet = preparedQuery.executeQuery();
1984 if (resultSet.next()) {
1985 int instance_id = resultSet.getInt(
"id");
1986 preparedUpdate = conn.prepareStatement(sqlUpdate);
1988 preparedUpdate.setByte(1, knownStatus.getFileKnownValue());
1992 if (
"".equals(eamArtifact.getComment())) {
1993 preparedUpdate.setNull(2, Types.INTEGER);
1995 preparedUpdate.setString(2, eamArtifact.getComment());
1997 preparedUpdate.setInt(3, instance_id);
1999 preparedUpdate.executeUpdate();
2006 CorrelationCase correlationCaseWithId = getCaseByUUID(eamArtifact.getCorrelationCase().getCaseUUID());
2007 if (null == getDataSource(correlationCaseWithId, eamArtifact.getCorrelationDataSource().getDataSourceObjectID())) {
2008 newDataSource(eamArtifact.getCorrelationDataSource());
2010 eamArtifact.setKnownStatus(knownStatus);
2011 addArtifactInstance(eamArtifact);
2014 }
catch (SQLException ex) {
2015 throw new CentralRepoException(
"Error getting/setting artifact instance knownStatus=" + knownStatus.getName(), ex);
2017 CentralRepoDbUtil.closeStatement(preparedUpdate);
2018 CentralRepoDbUtil.closeStatement(preparedQuery);
2019 CentralRepoDbUtil.closeResultSet(resultSet);
2020 CentralRepoDbUtil.closeConnection(conn);
2033 public Long getCountArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2035 String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
2037 Connection conn = connect();
2039 Long badInstances = 0L;
2040 PreparedStatement preparedStatement = null;
2041 ResultSet resultSet = null;
2043 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(aType);
2045 =
"SELECT count(*) FROM "
2047 +
" WHERE value=? AND known_status=?";
2050 preparedStatement = conn.prepareStatement(sql);
2051 preparedStatement.setString(1, normalizedValue);
2052 preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
2053 resultSet = preparedStatement.executeQuery();
2055 badInstances = resultSet.getLong(1);
2056 }
catch (SQLException ex) {
2057 throw new CentralRepoException(
"Error getting count of notable artifact instances.", ex);
2059 CentralRepoDbUtil.closeStatement(preparedStatement);
2060 CentralRepoDbUtil.closeResultSet(resultSet);
2061 CentralRepoDbUtil.closeConnection(conn);
2064 return badInstances;
2080 public List<String> getListCasesHavingArtifactInstancesKnownBad(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2082 String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
2084 Connection conn = connect();
2086 Collection<String> caseNames =
new LinkedHashSet<>();
2088 PreparedStatement preparedStatement = null;
2089 ResultSet resultSet = null;
2091 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(aType);
2093 =
"SELECT DISTINCT case_name FROM "
2095 +
" INNER JOIN cases ON "
2097 +
".case_id=cases.id WHERE "
2101 +
".known_status=?";
2104 preparedStatement = conn.prepareStatement(sql);
2105 preparedStatement.setString(1, normalizedValue);
2106 preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
2107 resultSet = preparedStatement.executeQuery();
2108 while (resultSet.next()) {
2109 caseNames.add(resultSet.getString(
"case_name"));
2111 }
catch (SQLException ex) {
2112 throw new CentralRepoException(
"Error getting notable artifact instances.", ex);
2114 CentralRepoDbUtil.closeStatement(preparedStatement);
2115 CentralRepoDbUtil.closeResultSet(resultSet);
2116 CentralRepoDbUtil.closeConnection(conn);
2119 return caseNames.stream().collect(Collectors.toList());
2135 public List<String> getListCasesHavingArtifactInstances(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2137 String normalizedValue = CorrelationAttributeNormalizer.normalize(aType, value);
2139 Connection conn = connect();
2141 Collection<String> caseNames =
new LinkedHashSet<>();
2143 PreparedStatement preparedStatement = null;
2144 ResultSet resultSet = null;
2146 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(aType);
2148 =
"SELECT DISTINCT case_name FROM "
2150 +
" INNER JOIN cases ON "
2152 +
".case_id=cases.id WHERE "
2157 preparedStatement = conn.prepareStatement(sql);
2158 preparedStatement.setString(1, normalizedValue);
2159 resultSet = preparedStatement.executeQuery();
2160 while (resultSet.next()) {
2161 caseNames.add(resultSet.getString(
"case_name"));
2163 }
catch (SQLException ex) {
2164 throw new CentralRepoException(
"Error getting notable artifact instances.", ex);
2166 CentralRepoDbUtil.closeStatement(preparedStatement);
2167 CentralRepoDbUtil.closeResultSet(resultSet);
2168 CentralRepoDbUtil.closeConnection(conn);
2171 return caseNames.stream().collect(Collectors.toList());
2182 public void deleteReferenceSet(
int referenceSetID)
throws CentralRepoException {
2183 deleteReferenceSetEntries(referenceSetID);
2184 deleteReferenceSetEntry(referenceSetID);
2194 private void deleteReferenceSetEntry(
int referenceSetID)
throws CentralRepoException {
2195 Connection conn = connect();
2197 PreparedStatement preparedStatement = null;
2198 String sql =
"DELETE FROM reference_sets WHERE id=?";
2201 preparedStatement = conn.prepareStatement(sql);
2202 preparedStatement.setInt(1, referenceSetID);
2203 preparedStatement.executeUpdate();
2204 }
catch (SQLException ex) {
2205 throw new CentralRepoException(
"Error deleting reference set " + referenceSetID, ex);
2207 CentralRepoDbUtil.closeStatement(preparedStatement);
2208 CentralRepoDbUtil.closeConnection(conn);
2220 private void deleteReferenceSetEntries(
int referenceSetID)
throws CentralRepoException {
2221 Connection conn = connect();
2223 PreparedStatement preparedStatement = null;
2224 String sql =
"DELETE FROM %s WHERE reference_set_id=?";
2227 String fileTableName = CentralRepoDbUtil.correlationTypeToReferenceTableName(getCorrelationTypeById(CorrelationAttributeInstance.FILES_TYPE_ID));
2230 preparedStatement = conn.prepareStatement(String.format(sql, fileTableName));
2231 preparedStatement.setInt(1, referenceSetID);
2232 preparedStatement.executeUpdate();
2233 }
catch (SQLException ex) {
2234 throw new CentralRepoException(
"Error deleting files from reference set " + referenceSetID, ex);
2236 CentralRepoDbUtil.closeStatement(preparedStatement);
2237 CentralRepoDbUtil.closeConnection(conn);
2255 public boolean referenceSetIsValid(
int referenceSetID, String setName, String version)
throws CentralRepoException {
2256 CentralRepoFileSet refSet = this.getReferenceSetByID(referenceSetID);
2257 if (refSet == null) {
2261 return (refSet.getSetName().equals(setName) && refSet.getVersion().equals(version));
2276 public boolean isFileHashInReferenceSet(String hash,
int referenceSetID)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2277 return isValueInReferenceSet(hash, referenceSetID, CorrelationAttributeInstance.FILES_TYPE_ID);
2290 public boolean isValueInReferenceSet(String value,
int referenceSetID,
int correlationTypeID)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2292 String normalizeValued = CorrelationAttributeNormalizer.normalize(this.getCorrelationTypeById(correlationTypeID), value);
2294 Connection conn = connect();
2296 Long matchingInstances = 0L;
2297 PreparedStatement preparedStatement = null;
2298 ResultSet resultSet = null;
2299 String sql =
"SELECT count(*) FROM %s WHERE value=? AND reference_set_id=?";
2301 String fileTableName = CentralRepoDbUtil.correlationTypeToReferenceTableName(getCorrelationTypeById(correlationTypeID));
2304 preparedStatement = conn.prepareStatement(String.format(sql, fileTableName));
2305 preparedStatement.setString(1, normalizeValued);
2306 preparedStatement.setInt(2, referenceSetID);
2307 resultSet = preparedStatement.executeQuery();
2309 matchingInstances = resultSet.getLong(1);
2310 }
catch (SQLException ex) {
2311 throw new CentralRepoException(
"Error determining if value (" + normalizeValued +
") is in reference set " + referenceSetID, ex);
2313 CentralRepoDbUtil.closeStatement(preparedStatement);
2314 CentralRepoDbUtil.closeResultSet(resultSet);
2315 CentralRepoDbUtil.closeConnection(conn);
2318 return 0 < matchingInstances;
2330 public boolean isArtifactKnownBadByReference(CorrelationAttributeInstance.Type aType, String value)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2333 String normalizeValued = CorrelationAttributeNormalizer.normalize(aType, value);
2336 if (aType.getId() != CorrelationAttributeInstance.FILES_TYPE_ID) {
2340 Connection conn = connect();
2342 Long badInstances = 0L;
2343 PreparedStatement preparedStatement = null;
2344 ResultSet resultSet = null;
2345 String sql =
"SELECT count(*) FROM %s WHERE value=? AND known_status=?";
2348 preparedStatement = conn.prepareStatement(String.format(sql, CentralRepoDbUtil.correlationTypeToReferenceTableName(aType)));
2349 preparedStatement.setString(1, normalizeValued);
2350 preparedStatement.setByte(2, TskData.FileKnown.BAD.getFileKnownValue());
2351 resultSet = preparedStatement.executeQuery();
2353 badInstances = resultSet.getLong(1);
2354 }
catch (SQLException ex) {
2355 throw new CentralRepoException(
"Error determining if artifact is notable by reference.", ex);
2357 CentralRepoDbUtil.closeStatement(preparedStatement);
2358 CentralRepoDbUtil.closeResultSet(resultSet);
2359 CentralRepoDbUtil.closeConnection(conn);
2362 return 0 < badInstances;
2374 public void processInstanceTable(CorrelationAttributeInstance.Type type, InstanceTableCallback instanceTableCallback)
throws CentralRepoException {
2376 throw new CentralRepoException(
"Correlation type is null");
2379 if (instanceTableCallback == null) {
2380 throw new CentralRepoException(
"Callback interface is null");
2383 Connection conn = connect();
2384 PreparedStatement preparedStatement = null;
2385 ResultSet resultSet = null;
2386 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(type);
2387 StringBuilder sql =
new StringBuilder();
2388 sql.append(
"select * from ");
2389 sql.append(tableName);
2392 preparedStatement = conn.prepareStatement(sql.toString());
2393 resultSet = preparedStatement.executeQuery();
2394 instanceTableCallback.process(resultSet);
2395 }
catch (SQLException ex) {
2396 throw new CentralRepoException(
"Error getting all artifact instances from instances table", ex);
2398 CentralRepoDbUtil.closeStatement(preparedStatement);
2399 CentralRepoDbUtil.closeResultSet(resultSet);
2400 CentralRepoDbUtil.closeConnection(conn);
2414 public void processInstanceTableWhere(CorrelationAttributeInstance.Type type, String whereClause, InstanceTableCallback instanceTableCallback)
throws CentralRepoException {
2416 throw new CentralRepoException(
"Correlation type is null");
2419 if (instanceTableCallback == null) {
2420 throw new CentralRepoException(
"Callback interface is null");
2423 if (whereClause == null) {
2424 throw new CentralRepoException(
"Where clause is null");
2427 Connection conn = connect();
2428 PreparedStatement preparedStatement = null;
2429 ResultSet resultSet = null;
2430 String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(type);
2431 StringBuilder sql =
new StringBuilder(300);
2432 sql.append(
"select * from ")
2435 .append(whereClause);
2438 preparedStatement = conn.prepareStatement(sql.toString());
2439 resultSet = preparedStatement.executeQuery();
2440 instanceTableCallback.process(resultSet);
2441 }
catch (SQLException ex) {
2442 throw new CentralRepoException(
"Error getting all artifact instances from instances table", ex);
2444 CentralRepoDbUtil.closeStatement(preparedStatement);
2445 CentralRepoDbUtil.closeResultSet(resultSet);
2446 CentralRepoDbUtil.closeConnection(conn);
2459 public void processSelectClause(String selectClause, InstanceTableCallback instanceTableCallback)
throws CentralRepoException {
2461 if (instanceTableCallback == null) {
2462 throw new CentralRepoException(
"Callback interface is null");
2465 if (selectClause == null) {
2466 throw new CentralRepoException(
"Select clause is null");
2469 Connection conn = connect();
2470 PreparedStatement preparedStatement = null;
2471 ResultSet resultSet = null;
2472 StringBuilder sql =
new StringBuilder(300);
2473 sql.append(
"select ")
2474 .append(selectClause);
2477 preparedStatement = conn.prepareStatement(sql.toString());
2478 resultSet = preparedStatement.executeQuery();
2479 instanceTableCallback.process(resultSet);
2480 }
catch (SQLException ex) {
2481 throw new CentralRepoException(
"Error running query", ex);
2483 CentralRepoDbUtil.closeStatement(preparedStatement);
2484 CentralRepoDbUtil.closeResultSet(resultSet);
2485 CentralRepoDbUtil.closeConnection(conn);
2490 public CentralRepoOrganization newOrganization(CentralRepoOrganization eamOrg)
throws CentralRepoException {
2491 if (eamOrg == null) {
2492 throw new CentralRepoException(
"EamOrganization is null");
2493 }
else if (eamOrg.getOrgID() != -1) {
2494 throw new CentralRepoException(
"EamOrganization already has an ID");
2497 Connection conn = connect();
2498 ResultSet generatedKeys = null;
2499 PreparedStatement preparedStatement = null;
2500 String sql =
"INSERT INTO organizations(org_name, poc_name, poc_email, poc_phone) VALUES (?, ?, ?, ?) "
2501 + getConflictClause();
2504 preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
2505 preparedStatement.setString(1, eamOrg.getName());
2506 preparedStatement.setString(2, eamOrg.getPocName());
2507 preparedStatement.setString(3, eamOrg.getPocEmail());
2508 preparedStatement.setString(4, eamOrg.getPocPhone());
2510 preparedStatement.executeUpdate();
2511 generatedKeys = preparedStatement.getGeneratedKeys();
2512 if (generatedKeys.next()) {
2513 eamOrg.setOrgID((
int) generatedKeys.getLong(1));
2516 throw new SQLException(
"Creating user failed, no ID obtained.");
2518 }
catch (SQLException ex) {
2519 throw new CentralRepoException(
"Error inserting new organization.", ex);
2521 CentralRepoDbUtil.closeStatement(preparedStatement);
2522 CentralRepoDbUtil.closeResultSet(generatedKeys);
2523 CentralRepoDbUtil.closeConnection(conn);
2535 public List<CentralRepoOrganization> getOrganizations() throws CentralRepoException {
2536 Connection conn = connect();
2538 List<CentralRepoOrganization> orgs =
new ArrayList<>();
2539 PreparedStatement preparedStatement = null;
2540 ResultSet resultSet = null;
2541 String sql =
"SELECT * FROM organizations";
2544 preparedStatement = conn.prepareStatement(sql);
2545 resultSet = preparedStatement.executeQuery();
2546 while (resultSet.next()) {
2547 orgs.add(getEamOrganizationFromResultSet(resultSet));
2551 }
catch (SQLException ex) {
2552 throw new CentralRepoException(
"Error getting all organizations.", ex);
2554 CentralRepoDbUtil.closeStatement(preparedStatement);
2555 CentralRepoDbUtil.closeResultSet(resultSet);
2556 CentralRepoDbUtil.closeConnection(conn);
2570 public CentralRepoOrganization getOrganizationByID(
int orgID)
throws CentralRepoException {
2571 Connection conn = connect();
2573 PreparedStatement preparedStatement = null;
2574 ResultSet resultSet = null;
2575 String sql =
"SELECT * FROM organizations WHERE id=?";
2578 preparedStatement = conn.prepareStatement(sql);
2579 preparedStatement.setInt(1, orgID);
2580 resultSet = preparedStatement.executeQuery();
2582 return getEamOrganizationFromResultSet(resultSet);
2584 }
catch (SQLException ex) {
2585 throw new CentralRepoException(
"Error getting organization by id.", ex);
2587 CentralRepoDbUtil.closeStatement(preparedStatement);
2588 CentralRepoDbUtil.closeResultSet(resultSet);
2589 CentralRepoDbUtil.closeConnection(conn);
2603 public CentralRepoOrganization getReferenceSetOrganization(
int referenceSetID)
throws CentralRepoException {
2605 CentralRepoFileSet globalSet = getReferenceSetByID(referenceSetID);
2606 if (globalSet == null) {
2607 throw new CentralRepoException(
"Reference set with ID " + referenceSetID +
" not found");
2609 return (getOrganizationByID(globalSet.getOrgID()));
2619 private void testArgument(CentralRepoOrganization
org)
throws CentralRepoException {
2621 throw new CentralRepoException(
"EamOrganization is null");
2622 }
else if (
org.getOrgID() == -1) {
2623 throw new CentralRepoException(
"Organization has -1 row ID");
2636 public void updateOrganization(CentralRepoOrganization updatedOrganization)
throws CentralRepoException {
2637 testArgument(updatedOrganization);
2639 Connection conn = connect();
2640 PreparedStatement preparedStatement = null;
2641 String sql =
"UPDATE organizations SET org_name = ?, poc_name = ?, poc_email = ?, poc_phone = ? WHERE id = ?";
2643 preparedStatement = conn.prepareStatement(sql);
2644 preparedStatement.setString(1, updatedOrganization.getName());
2645 preparedStatement.setString(2, updatedOrganization.getPocName());
2646 preparedStatement.setString(3, updatedOrganization.getPocEmail());
2647 preparedStatement.setString(4, updatedOrganization.getPocPhone());
2648 preparedStatement.setInt(5, updatedOrganization.getOrgID());
2649 preparedStatement.executeUpdate();
2650 }
catch (SQLException ex) {
2651 throw new CentralRepoException(
"Error updating organization.", ex);
2653 CentralRepoDbUtil.closeStatement(preparedStatement);
2654 CentralRepoDbUtil.closeConnection(conn);
2659 public void deleteOrganization(CentralRepoOrganization organizationToDelete)
throws CentralRepoException {
2660 testArgument(organizationToDelete);
2662 Connection conn = connect();
2663 PreparedStatement checkIfUsedStatement = null;
2664 ResultSet resultSet = null;
2665 String checkIfUsedSql =
"SELECT (select count(*) FROM cases WHERE org_id=?) + (select count(*) FROM reference_sets WHERE org_id=?)";
2666 PreparedStatement deleteOrgStatement = null;
2667 String deleteOrgSql =
"DELETE FROM organizations WHERE id=?";
2669 checkIfUsedStatement = conn.prepareStatement(checkIfUsedSql);
2670 checkIfUsedStatement.setInt(1, organizationToDelete.getOrgID());
2671 checkIfUsedStatement.setInt(2, organizationToDelete.getOrgID());
2672 resultSet = checkIfUsedStatement.executeQuery();
2674 if (resultSet.getLong(1) > 0) {
2675 throw new CentralRepoException(
"Can not delete organization which is currently in use by a case or reference set in the central repository.");
2677 deleteOrgStatement = conn.prepareStatement(deleteOrgSql);
2678 deleteOrgStatement.setInt(1, organizationToDelete.getOrgID());
2679 deleteOrgStatement.executeUpdate();
2680 }
catch (SQLException ex) {
2681 throw new CentralRepoException(
"Error executing query when attempting to delete organization by id.", ex);
2683 CentralRepoDbUtil.closeStatement(checkIfUsedStatement);
2684 CentralRepoDbUtil.closeStatement(deleteOrgStatement);
2685 CentralRepoDbUtil.closeResultSet(resultSet);
2686 CentralRepoDbUtil.closeConnection(conn);
2700 public int newReferenceSet(CentralRepoFileSet eamGlobalSet)
throws CentralRepoException {
2701 if (eamGlobalSet == null) {
2702 throw new CentralRepoException(
"EamGlobalSet is null");
2705 if (eamGlobalSet.getFileKnownStatus() == null) {
2706 throw new CentralRepoException(
"File known status on the EamGlobalSet is null");
2709 if (eamGlobalSet.getType() == null) {
2710 throw new CentralRepoException(
"Type on the EamGlobalSet is null");
2713 Connection conn = connect();
2715 PreparedStatement preparedStatement1 = null;
2716 PreparedStatement preparedStatement2 = null;
2717 ResultSet resultSet = null;
2718 String sql1 =
"INSERT INTO reference_sets(org_id, set_name, version, known_status, read_only, type, import_date) VALUES (?, ?, ?, ?, ?, ?, ?) "
2719 + getConflictClause();
2720 String sql2 =
"SELECT id FROM reference_sets WHERE org_id=? AND set_name=? AND version=? AND import_date=? LIMIT 1";
2723 preparedStatement1 = conn.prepareStatement(sql1);
2724 preparedStatement1.setInt(1, eamGlobalSet.getOrgID());
2725 preparedStatement1.setString(2, eamGlobalSet.getSetName());
2726 preparedStatement1.setString(3, eamGlobalSet.getVersion());
2727 preparedStatement1.setInt(4, eamGlobalSet.getFileKnownStatus().getFileKnownValue());
2728 preparedStatement1.setBoolean(5, eamGlobalSet.isReadOnly());
2729 preparedStatement1.setInt(6, eamGlobalSet.getType().getId());
2730 preparedStatement1.setString(7, eamGlobalSet.getImportDate().toString());
2732 preparedStatement1.executeUpdate();
2734 preparedStatement2 = conn.prepareStatement(sql2);
2735 preparedStatement2.setInt(1, eamGlobalSet.getOrgID());
2736 preparedStatement2.setString(2, eamGlobalSet.getSetName());
2737 preparedStatement2.setString(3, eamGlobalSet.getVersion());
2738 preparedStatement2.setString(4, eamGlobalSet.getImportDate().toString());
2740 resultSet = preparedStatement2.executeQuery();
2742 return resultSet.getInt(
"id");
2744 }
catch (SQLException ex) {
2745 throw new CentralRepoException(
"Error inserting new global set.", ex);
2747 CentralRepoDbUtil.closeStatement(preparedStatement1);
2748 CentralRepoDbUtil.closeStatement(preparedStatement2);
2749 CentralRepoDbUtil.closeResultSet(resultSet);
2750 CentralRepoDbUtil.closeConnection(conn);
2764 public CentralRepoFileSet getReferenceSetByID(
int referenceSetID)
throws CentralRepoException {
2765 Connection conn = connect();
2767 PreparedStatement preparedStatement1 = null;
2768 ResultSet resultSet = null;
2769 String sql1 =
"SELECT * FROM reference_sets WHERE id=?";
2772 preparedStatement1 = conn.prepareStatement(sql1);
2773 preparedStatement1.setInt(1, referenceSetID);
2774 resultSet = preparedStatement1.executeQuery();
2775 if (resultSet.next()) {
2776 return getEamGlobalSetFromResultSet(resultSet);
2781 }
catch (SQLException ex) {
2782 throw new CentralRepoException(
"Error getting reference set by id.", ex);
2784 CentralRepoDbUtil.closeStatement(preparedStatement1);
2785 CentralRepoDbUtil.closeResultSet(resultSet);
2786 CentralRepoDbUtil.closeConnection(conn);
2800 public List<CentralRepoFileSet> getAllReferenceSets(CorrelationAttributeInstance.Type correlationType) throws CentralRepoException {
2802 if (correlationType == null) {
2803 throw new CentralRepoException(
"Correlation type is null");
2806 List<CentralRepoFileSet> results =
new ArrayList<>();
2807 Connection conn = connect();
2809 PreparedStatement preparedStatement1 = null;
2810 ResultSet resultSet = null;
2811 String sql1 =
"SELECT * FROM reference_sets WHERE type=" + correlationType.getId();
2814 preparedStatement1 = conn.prepareStatement(sql1);
2815 resultSet = preparedStatement1.executeQuery();
2816 while (resultSet.next()) {
2817 results.add(getEamGlobalSetFromResultSet(resultSet));
2820 }
catch (SQLException ex) {
2821 throw new CentralRepoException(
"Error getting reference sets.", ex);
2823 CentralRepoDbUtil.closeStatement(preparedStatement1);
2824 CentralRepoDbUtil.closeResultSet(resultSet);
2825 CentralRepoDbUtil.closeConnection(conn);
2840 public void addReferenceInstance(CentralRepoFileInstance eamGlobalFileInstance, CorrelationAttributeInstance.Type correlationType) throws CentralRepoException {
2841 if (eamGlobalFileInstance.getKnownStatus() == null) {
2842 throw new CentralRepoException(
"Known status of EamGlobalFileInstance is null");
2844 if (correlationType == null) {
2845 throw new CentralRepoException(
"Correlation type is null");
2848 Connection conn = connect();
2850 PreparedStatement preparedStatement = null;
2852 String sql =
"INSERT INTO %s(reference_set_id, value, known_status, comment) VALUES (?, ?, ?, ?) "
2853 + getConflictClause();
2856 preparedStatement = conn.prepareStatement(String.format(sql, CentralRepoDbUtil.correlationTypeToReferenceTableName(correlationType)));
2857 preparedStatement.setInt(1, eamGlobalFileInstance.getGlobalSetID());
2858 preparedStatement.setString(2, eamGlobalFileInstance.getMD5Hash());
2859 preparedStatement.setByte(3, eamGlobalFileInstance.getKnownStatus().getFileKnownValue());
2860 preparedStatement.setString(4, eamGlobalFileInstance.getComment());
2861 preparedStatement.executeUpdate();
2862 }
catch (SQLException ex) {
2863 throw new CentralRepoException(
"Error inserting new reference instance into reference_ table.", ex);
2865 CentralRepoDbUtil.closeStatement(preparedStatement);
2866 CentralRepoDbUtil.closeConnection(conn);
2883 public boolean referenceSetExists(String referenceSetName, String version)
throws CentralRepoException {
2884 Connection conn = connect();
2886 PreparedStatement preparedStatement1 = null;
2887 ResultSet resultSet = null;
2888 String sql1 =
"SELECT * FROM reference_sets WHERE set_name=? AND version=?";
2891 preparedStatement1 = conn.prepareStatement(sql1);
2892 preparedStatement1.setString(1, referenceSetName);
2893 preparedStatement1.setString(2, version);
2894 resultSet = preparedStatement1.executeQuery();
2895 return (resultSet.next());
2897 }
catch (SQLException ex) {
2898 throw new CentralRepoException(
"Error testing whether reference set exists (name: " + referenceSetName
2899 +
" version: " + version, ex);
2901 CentralRepoDbUtil.closeStatement(preparedStatement1);
2902 CentralRepoDbUtil.closeResultSet(resultSet);
2903 CentralRepoDbUtil.closeConnection(conn);
2913 public void bulkInsertReferenceTypeEntries(Set<CentralRepoFileInstance> globalInstances, CorrelationAttributeInstance.Type contentType) throws CentralRepoException {
2914 if (contentType == null) {
2915 throw new CentralRepoException(
"Correlation type is null");
2917 if (globalInstances == null) {
2918 throw new CentralRepoException(
"Null set of EamGlobalFileInstance");
2921 Connection conn = connect();
2923 PreparedStatement bulkPs = null;
2925 conn.setAutoCommit(
false);
2928 String sql =
"INSERT INTO %s(reference_set_id, value, known_status, comment) VALUES (?, ?, ?, ?) "
2929 + getConflictClause();
2931 bulkPs = conn.prepareStatement(String.format(sql, CentralRepoDbUtil.correlationTypeToReferenceTableName(contentType)));
2933 for (CentralRepoFileInstance globalInstance : globalInstances) {
2934 if (globalInstance.getKnownStatus() == null) {
2935 throw new CentralRepoException(
"EamGlobalFileInstance with value " + globalInstance.getMD5Hash() +
" has null known status");
2938 bulkPs.setInt(1, globalInstance.getGlobalSetID());
2939 bulkPs.setString(2, globalInstance.getMD5Hash());
2940 bulkPs.setByte(3, globalInstance.getKnownStatus().getFileKnownValue());
2941 bulkPs.setString(4, globalInstance.getComment());
2945 bulkPs.executeBatch();
2947 }
catch (SQLException | CentralRepoException ex) {
2950 }
catch (SQLException ex2) {
2953 throw new CentralRepoException(
"Error inserting bulk artifacts.", ex);
2955 CentralRepoDbUtil.closeStatement(bulkPs);
2956 CentralRepoDbUtil.closeConnection(conn);
2971 public List<CentralRepoFileInstance> getReferenceInstancesByTypeValue(CorrelationAttributeInstance.Type aType, String aValue)
throws CentralRepoException, CorrelationAttributeNormalizationException {
2972 String normalizeValued = CorrelationAttributeNormalizer.normalize(aType, aValue);
2974 Connection conn = connect();
2976 List<CentralRepoFileInstance> globalFileInstances =
new ArrayList<>();
2977 PreparedStatement preparedStatement1 = null;
2978 ResultSet resultSet = null;
2979 String sql1 =
"SELECT * FROM %s WHERE value=?";
2982 preparedStatement1 = conn.prepareStatement(String.format(sql1, CentralRepoDbUtil.correlationTypeToReferenceTableName(aType)));
2983 preparedStatement1.setString(1, normalizeValued);
2984 resultSet = preparedStatement1.executeQuery();
2985 while (resultSet.next()) {
2986 globalFileInstances.add(getEamGlobalFileInstanceFromResultSet(resultSet));
2989 }
catch (SQLException ex) {
2990 throw new CentralRepoException(
"Error getting reference instances by type and value.", ex);
2992 CentralRepoDbUtil.closeStatement(preparedStatement1);
2993 CentralRepoDbUtil.closeResultSet(resultSet);
2994 CentralRepoDbUtil.closeConnection(conn);
2997 return globalFileInstances;
3010 public int newCorrelationType(CorrelationAttributeInstance.Type newType) throws CentralRepoException {
3011 if (newType == null) {
3012 throw new CentralRepoException(
"Correlation type is null");
3015 if (-1 == newType.getId()) {
3016 typeId = newCorrelationTypeNotKnownId(newType);
3018 typeId = newCorrelationTypeKnownId(newType);
3021 synchronized(typeCache) {
3022 typeCache.put(newType.getId(), newType);
3037 public int newCorrelationTypeNotKnownId(CorrelationAttributeInstance.Type newType) throws CentralRepoException {
3038 Connection conn = connect();
3040 PreparedStatement preparedStatement = null;
3041 PreparedStatement preparedStatementQuery = null;
3042 ResultSet resultSet = null;
3047 insertSql =
"INSERT INTO correlation_types(display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?) " + getConflictClause();
3049 querySql =
"SELECT * FROM correlation_types WHERE display_name=? AND db_table_name=?";
3052 preparedStatement = conn.prepareStatement(insertSql);
3054 preparedStatement.setString(1, newType.getDisplayName());
3055 preparedStatement.setString(2, newType.getDbTableName());
3056 preparedStatement.setInt(3, newType.isSupported() ? 1 : 0);
3057 preparedStatement.setInt(4, newType.isEnabled() ? 1 : 0);
3059 preparedStatement.executeUpdate();
3061 preparedStatementQuery = conn.prepareStatement(querySql);
3062 preparedStatementQuery.setString(1, newType.getDisplayName());
3063 preparedStatementQuery.setString(2, newType.getDbTableName());
3065 resultSet = preparedStatementQuery.executeQuery();
3066 if (resultSet.next()) {
3067 CorrelationAttributeInstance.Type correlationType = getCorrelationTypeFromResultSet(resultSet);
3068 typeId = correlationType.getId();
3070 }
catch (SQLException ex) {
3071 throw new CentralRepoException(
"Error inserting new correlation type.", ex);
3073 CentralRepoDbUtil.closeStatement(preparedStatement);
3074 CentralRepoDbUtil.closeStatement(preparedStatementQuery);
3075 CentralRepoDbUtil.closeResultSet(resultSet);
3076 CentralRepoDbUtil.closeConnection(conn);
3090 private int newCorrelationTypeKnownId(CorrelationAttributeInstance.Type newType) throws CentralRepoException {
3091 Connection conn = connect();
3093 PreparedStatement preparedStatement = null;
3094 PreparedStatement preparedStatementQuery = null;
3095 ResultSet resultSet = null;
3100 insertSql =
"INSERT INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?) " + getConflictClause();
3102 querySql =
"SELECT * FROM correlation_types WHERE display_name=? AND db_table_name=?";
3105 preparedStatement = conn.prepareStatement(insertSql);
3107 preparedStatement.setInt(1, newType.getId());
3108 preparedStatement.setString(2, newType.getDisplayName());
3109 preparedStatement.setString(3, newType.getDbTableName());
3110 preparedStatement.setInt(4, newType.isSupported() ? 1 : 0);
3111 preparedStatement.setInt(5, newType.isEnabled() ? 1 : 0);
3113 preparedStatement.executeUpdate();
3115 preparedStatementQuery = conn.prepareStatement(querySql);
3116 preparedStatementQuery.setString(1, newType.getDisplayName());
3117 preparedStatementQuery.setString(2, newType.getDbTableName());
3119 resultSet = preparedStatementQuery.executeQuery();
3120 if (resultSet.next()) {
3121 CorrelationAttributeInstance.Type correlationType = getCorrelationTypeFromResultSet(resultSet);
3122 typeId = correlationType.getId();
3124 }
catch (SQLException ex) {
3125 throw new CentralRepoException(
"Error inserting new correlation type.", ex);
3127 CentralRepoDbUtil.closeStatement(preparedStatement);
3128 CentralRepoDbUtil.closeStatement(preparedStatementQuery);
3129 CentralRepoDbUtil.closeResultSet(resultSet);
3130 CentralRepoDbUtil.closeConnection(conn);
3136 public List<CorrelationAttributeInstance.Type> getDefinedCorrelationTypes() throws CentralRepoException {
3138 synchronized (typeCache) {
3139 if (isCRTypeCacheInitialized ==
false) {
3140 getCorrelationTypesFromCr();
3142 return new ArrayList<>(typeCache.asMap().values());
3156 public List<CorrelationAttributeInstance.Type> getEnabledCorrelationTypes() throws CentralRepoException {
3157 Connection conn = connect();
3159 List<CorrelationAttributeInstance.Type> aTypes =
new ArrayList<>();
3160 PreparedStatement preparedStatement = null;
3161 ResultSet resultSet = null;
3162 String sql =
"SELECT * FROM correlation_types WHERE enabled=1";
3165 preparedStatement = conn.prepareStatement(sql);
3166 resultSet = preparedStatement.executeQuery();
3167 while (resultSet.next()) {
3168 aTypes.add(getCorrelationTypeFromResultSet(resultSet));
3172 }
catch (SQLException ex) {
3173 throw new CentralRepoException(
"Error getting enabled correlation types.", ex);
3175 CentralRepoDbUtil.closeStatement(preparedStatement);
3176 CentralRepoDbUtil.closeResultSet(resultSet);
3177 CentralRepoDbUtil.closeConnection(conn);
3191 public List<CorrelationAttributeInstance.Type> getSupportedCorrelationTypes() throws CentralRepoException {
3192 Connection conn = connect();
3194 List<CorrelationAttributeInstance.Type> aTypes =
new ArrayList<>();
3195 PreparedStatement preparedStatement = null;
3196 ResultSet resultSet = null;
3197 String sql =
"SELECT * FROM correlation_types WHERE supported=1";
3200 preparedStatement = conn.prepareStatement(sql);
3201 resultSet = preparedStatement.executeQuery();
3202 while (resultSet.next()) {
3203 aTypes.add(getCorrelationTypeFromResultSet(resultSet));
3207 }
catch (SQLException ex) {
3208 throw new CentralRepoException(
"Error getting supported correlation types.", ex);
3210 CentralRepoDbUtil.closeStatement(preparedStatement);
3211 CentralRepoDbUtil.closeResultSet(resultSet);
3212 CentralRepoDbUtil.closeConnection(conn);
3224 public void updateCorrelationType(CorrelationAttributeInstance.Type aType) throws CentralRepoException {
3225 Connection conn = connect();
3227 PreparedStatement preparedStatement = null;
3228 String sql =
"UPDATE correlation_types SET display_name=?, db_table_name=?, supported=?, enabled=? WHERE id=?";
3231 preparedStatement = conn.prepareStatement(sql);
3232 preparedStatement.setString(1, aType.getDisplayName());
3233 preparedStatement.setString(2, aType.getDbTableName());
3234 preparedStatement.setInt(3, aType.isSupported() ? 1 : 0);
3235 preparedStatement.setInt(4, aType.isEnabled() ? 1 : 0);
3236 preparedStatement.setInt(5, aType.getId());
3237 preparedStatement.executeUpdate();
3238 synchronized(typeCache) {
3239 typeCache.put(aType.getId(), aType);
3241 }
catch (SQLException ex) {
3242 throw new CentralRepoException(
"Error updating correlation type.", ex);
3244 CentralRepoDbUtil.closeStatement(preparedStatement);
3245 CentralRepoDbUtil.closeConnection(conn);
3260 public CorrelationAttributeInstance.Type getCorrelationTypeById(
int typeId)
throws CentralRepoException {
3262 synchronized(typeCache) {
3263 return typeCache.get(typeId, () -> getCorrelationTypeByIdFromCr(typeId));
3265 }
catch (CacheLoader.InvalidCacheLoadException ignored) {
3268 }
catch (ExecutionException ex) {
3269 throw new CentralRepoException(
"Error getting correlation type", ex);
3283 private CorrelationAttributeInstance.Type getCorrelationTypeByIdFromCr(
int typeId)
throws CentralRepoException {
3284 Connection conn = connect();
3286 CorrelationAttributeInstance.Type aType;
3287 PreparedStatement preparedStatement = null;
3288 ResultSet resultSet = null;
3289 String sql =
"SELECT * FROM correlation_types WHERE id=?";
3292 preparedStatement = conn.prepareStatement(sql);
3293 preparedStatement.setInt(1, typeId);
3294 resultSet = preparedStatement.executeQuery();
3295 if (resultSet.next()) {
3296 aType = getCorrelationTypeFromResultSet(resultSet);
3299 throw new CentralRepoException(
"Failed to find entry for correlation type ID = " + typeId);
3302 }
catch (SQLException ex) {
3303 throw new CentralRepoException(
"Error getting correlation type by id.", ex);
3305 CentralRepoDbUtil.closeStatement(preparedStatement);
3306 CentralRepoDbUtil.closeResultSet(resultSet);
3307 CentralRepoDbUtil.closeConnection(conn);
3316 private void getCorrelationTypesFromCr() throws CentralRepoException {
3319 synchronized(typeCache) {
3320 typeCache.invalidateAll();
3321 isCRTypeCacheInitialized =
false;
3324 String sql =
"SELECT * FROM correlation_types";
3325 try ( Connection conn = connect();
3326 PreparedStatement preparedStatement = conn.prepareStatement(sql);
3327 ResultSet resultSet = preparedStatement.executeQuery();) {
3329 synchronized(typeCache) {
3330 while (resultSet.next()) {
3331 CorrelationAttributeInstance.Type aType = getCorrelationTypeFromResultSet(resultSet);
3332 typeCache.put(aType.getId(), aType);
3334 isCRTypeCacheInitialized =
true;
3336 }
catch (SQLException ex) {
3337 throw new CentralRepoException(
"Error getting correlation types.", ex);
3351 private CorrelationCase getEamCaseFromResultSet(ResultSet resultSet)
throws SQLException {
3352 if (null == resultSet) {
3356 CentralRepoOrganization eamOrg = null;
3358 resultSet.getInt(
"org_id");
3359 if (!resultSet.wasNull()) {
3361 eamOrg =
new CentralRepoOrganization(resultSet.getInt(
"org_id"),
3362 resultSet.getString(
"org_name"),
3363 resultSet.getString(
"poc_name"),
3364 resultSet.getString(
"poc_email"),
3365 resultSet.getString(
"poc_phone"));
3368 CorrelationCase eamCase =
new CorrelationCase(resultSet.getInt(
"case_id"), resultSet.getString(
"case_uid"), eamOrg, resultSet.getString(
"case_name"),
3369 resultSet.getString(
"creation_date"), resultSet.getString(
"case_number"), resultSet.getString(
"examiner_name"),
3370 resultSet.getString(
"examiner_email"), resultSet.getString(
"examiner_phone"), resultSet.getString(
"notes"));
3375 private CorrelationDataSource getEamDataSourceFromResultSet(ResultSet resultSet)
throws SQLException {
3376 if (null == resultSet) {
3380 CorrelationDataSource eamDataSource =
new CorrelationDataSource(
3381 resultSet.getInt(
"case_id"),
3382 resultSet.getInt(
"id"),
3383 resultSet.getString(
"device_id"),
3384 resultSet.getString(
"name"),
3385 resultSet.getLong(
"datasource_obj_id"),
3386 resultSet.getString(
"md5"),
3387 resultSet.getString(
"sha1"),
3388 resultSet.getString(
"sha256")
3391 return eamDataSource;
3394 private CorrelationAttributeInstance.Type getCorrelationTypeFromResultSet(ResultSet resultSet)
throws CentralRepoException, SQLException {
3395 if (null == resultSet) {
3399 CorrelationAttributeInstance.Type eamArtifactType =
new CorrelationAttributeInstance.Type(
3400 resultSet.getInt(
"id"),
3401 resultSet.getString(
"display_name"),
3402 resultSet.getString(
"db_table_name"),
3403 resultSet.getBoolean(
"supported"),
3404 resultSet.getBoolean(
"enabled")
3407 return eamArtifactType;
3420 private CorrelationAttributeInstance getEamArtifactInstanceFromResultSet(ResultSet resultSet, CorrelationAttributeInstance.Type aType) throws SQLException, CentralRepoException, CorrelationAttributeNormalizationException {
3421 if (null == resultSet) {
3425 CentralRepoOrganization eamOrg =
new CentralRepoOrganization(resultSet.getInt(
"org_id"),
3426 resultSet.getString(
"org_name"),
3427 resultSet.getString(
"poc_name"),
3428 resultSet.getString(
"poc_email"),
3429 resultSet.getString(
"poc_phone"));
3431 return new CorrelationAttributeInstance(
3433 resultSet.getString(
"value"),
3434 resultSet.getInt(
"instance_id"),
3435 new CorrelationCase(resultSet.getInt(
"id"), resultSet.getString(
"case_uid"), eamOrg, resultSet.getString(
"case_name"),
3436 resultSet.getString(
"creation_date"), resultSet.getString(
"case_number"), resultSet.getString(
"examiner_name"),
3437 resultSet.getString(
"examiner_email"), resultSet.getString(
"examiner_phone"), resultSet.getString(
"notes")),
3438 new CorrelationDataSource(
3439 resultSet.getInt(
"id"), resultSet.getInt(
"data_source_id"), resultSet.getString(
"device_id"), resultSet.getString(
"name"),
3440 resultSet.getLong(
"datasource_obj_id"), resultSet.getString(
"md5"), resultSet.getString(
"sha1"), resultSet.getString(
"sha256")),
3441 resultSet.getString(
"file_path"),
3442 resultSet.getString(
"comment"),
3443 TskData.FileKnown.valueOf(resultSet.getByte(
"known_status")),
3444 resultSet.getLong(
"file_obj_id"));
3447 private CentralRepoOrganization getEamOrganizationFromResultSet(ResultSet resultSet)
throws SQLException {
3448 if (null == resultSet) {
3452 return new CentralRepoOrganization(
3453 resultSet.getInt(
"id"),
3454 resultSet.getString(
"org_name"),
3455 resultSet.getString(
"poc_name"),
3456 resultSet.getString(
"poc_email"),
3457 resultSet.getString(
"poc_phone")
3461 private CentralRepoFileSet getEamGlobalSetFromResultSet(ResultSet resultSet)
throws SQLException, CentralRepoException {
3462 if (null == resultSet) {
3466 return new CentralRepoFileSet(
3467 resultSet.getInt(
"id"),
3468 resultSet.getInt(
"org_id"),
3469 resultSet.getString(
"set_name"),
3470 resultSet.getString(
"version"),
3471 TskData.FileKnown.valueOf(resultSet.getByte(
"known_status")),
3472 resultSet.getBoolean(
"read_only"),
3473 CentralRepository.getInstance().getCorrelationTypeById(resultSet.getInt(
"type")),
3474 LocalDate.parse(resultSet.getString(
"import_date"))
3478 private CentralRepoFileInstance getEamGlobalFileInstanceFromResultSet(ResultSet resultSet)
throws SQLException, CentralRepoException, CorrelationAttributeNormalizationException {
3479 if (null == resultSet) {
3483 return new CentralRepoFileInstance(
3484 resultSet.getInt(
"id"),
3485 resultSet.getInt(
"reference_set_id"),
3486 resultSet.getString(
"value"),
3487 TskData.FileKnown.valueOf(resultSet.getByte(
"known_status")),
3488 resultSet.getString(
"comment")
3502 abstract boolean doesColumnExist(Connection conn, String tableName, String columnName)
throws SQLException;
3509 @Messages({
"AbstractSqlEamDb.upgradeSchema.incompatible=The selected Central Repository is not compatible with the current version of the application, please upgrade the application if you wish to use this Central Repository.",
3510 "# {0} - minorVersion",
3511 "AbstractSqlEamDb.badMinorSchema.message=Bad value for schema minor version ({0}) - database is corrupt.",
3512 "AbstractSqlEamDb.failedToReadMinorVersion.message=Failed to read schema minor version for Central Repository.",
3513 "# {0} - majorVersion",
3514 "AbstractSqlEamDb.badMajorSchema.message=Bad value for schema version ({0}) - database is corrupt.",
3515 "AbstractSqlEamDb.failedToReadMajorVersion.message=Failed to read schema version for Central Repository.",
3516 "# {0} - platformName",
3517 "AbstractSqlEamDb.cannotUpgrage.message=Currently selected database platform \"{0}\" can not be upgraded."})
3519 public void upgradeSchema() throws CentralRepoException, SQLException, IncompatibleCentralRepoException {
3521 ResultSet resultSet = null;
3522 Statement statement = null;
3523 PreparedStatement preparedStatement = null;
3524 Connection conn = null;
3525 CentralRepoPlatforms selectedPlatform = null;
3528 conn = connect(
false);
3529 conn.setAutoCommit(
false);
3530 statement = conn.createStatement();
3531 selectedPlatform = CentralRepoDbManager.getSavedDbChoice().getDbPlatform();
3532 int minorVersion = 0;
3533 String minorVersionStr = null;
3534 resultSet = statement.executeQuery(
"SELECT value FROM db_info WHERE name='" + RdbmsCentralRepo.SCHEMA_MINOR_VERSION_KEY +
"'");
3535 if (resultSet.next()) {
3536 minorVersionStr = resultSet.getString(
"value");
3538 minorVersion = Integer.parseInt(minorVersionStr);
3539 }
catch (NumberFormatException ex) {
3540 throw new CentralRepoException(
"Bad value for schema minor version (" + minorVersionStr +
") - database is corrupt", Bundle.AbstractSqlEamDb_badMinorSchema_message(minorVersionStr), ex);
3543 throw new CentralRepoException(
"Failed to read schema minor version from db_info table", Bundle.AbstractSqlEamDb_failedToReadMinorVersion_message());
3546 int majorVersion = 0;
3547 String majorVersionStr = null;
3548 resultSet = statement.executeQuery(
"SELECT value FROM db_info WHERE name='" + RdbmsCentralRepo.SCHEMA_MAJOR_VERSION_KEY +
"'");
3549 if (resultSet.next()) {
3550 majorVersionStr = resultSet.getString(
"value");
3552 majorVersion = Integer.parseInt(majorVersionStr);
3553 }
catch (NumberFormatException ex) {
3554 throw new CentralRepoException(
"Bad value for schema version (" + majorVersionStr +
") - database is corrupt", Bundle.AbstractSqlEamDb_badMajorSchema_message(majorVersionStr), ex);
3557 throw new CentralRepoException(
"Failed to read schema major version from db_info table", Bundle.AbstractSqlEamDb_failedToReadMajorVersion_message());
3568 CaseDbSchemaVersionNumber dbSchemaVersion =
new CaseDbSchemaVersionNumber(majorVersion, minorVersion);
3573 if (SOFTWARE_CR_DB_SCHEMA_VERSION.getMajor() < dbSchemaVersion.getMajor()) {
3574 throw new IncompatibleCentralRepoException(Bundle.AbstractSqlEamDb_upgradeSchema_incompatible());
3576 if (dbSchemaVersion.equals(SOFTWARE_CR_DB_SCHEMA_VERSION)) {
3577 logger.log(Level.INFO,
"Central Repository is up to date");
3580 if (dbSchemaVersion.compareTo(SOFTWARE_CR_DB_SCHEMA_VERSION) > 0) {
3581 logger.log(Level.INFO,
"Central Repository is of newer version than software creates");
3588 if (dbSchemaVersion.compareTo(
new CaseDbSchemaVersionNumber(1, 1)) < 0) {
3589 statement.execute(
"ALTER TABLE reference_sets ADD COLUMN known_status INTEGER;");
3590 statement.execute(
"ALTER TABLE reference_sets ADD COLUMN read_only BOOLEAN;");
3591 statement.execute(
"ALTER TABLE reference_sets ADD COLUMN type INTEGER;");
3596 CentralRepoDbUtil.insertDefaultOrganization(conn);
3602 if (dbSchemaVersion.compareTo(
new CaseDbSchemaVersionNumber(1, 2)) < 0) {
3603 final String addIntegerColumnTemplate =
"ALTER TABLE %s ADD COLUMN %s INTEGER;";
3605 final String addSsidTableTemplate = RdbmsCentralRepoFactory.getCreateArtifactInstancesTableTemplate(selectedPlatform);
3606 final String addCaseIdIndexTemplate = RdbmsCentralRepoFactory.getAddCaseIdIndexTemplate();
3607 final String addDataSourceIdIndexTemplate = RdbmsCentralRepoFactory.getAddDataSourceIdIndexTemplate();
3608 final String addValueIndexTemplate = RdbmsCentralRepoFactory.getAddValueIndexTemplate();
3609 final String addKnownStatusIndexTemplate = RdbmsCentralRepoFactory.getAddKnownStatusIndexTemplate();
3610 final String addObjectIdIndexTemplate = RdbmsCentralRepoFactory.getAddObjectIdIndexTemplate();
3612 final String addAttributeSql;
3614 switch (selectedPlatform) {
3616 addAttributeSql =
"INSERT INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?) " + getConflictClause();
3619 addAttributeSql =
"INSERT OR IGNORE INTO correlation_types(id, display_name, db_table_name, supported, enabled) VALUES (?, ?, ?, ?, ?)";
3622 throw new CentralRepoException(
"Currently selected database platform \"" + selectedPlatform.name() +
"\" can not be upgraded.", Bundle.AbstractSqlEamDb_cannotUpgrage_message(selectedPlatform.name()));
3625 final String dataSourcesTableName =
"data_sources";
3626 final String dataSourceObjectIdColumnName =
"datasource_obj_id";
3627 if (!doesColumnExist(conn, dataSourcesTableName, dataSourceObjectIdColumnName)) {
3628 statement.execute(String.format(addIntegerColumnTemplate, dataSourcesTableName, dataSourceObjectIdColumnName));
3630 final String dataSourceObjectIdIndexTemplate =
"CREATE INDEX IF NOT EXISTS datasource_object_id ON data_sources (%s)";
3631 statement.execute(String.format(dataSourceObjectIdIndexTemplate, dataSourceObjectIdColumnName));
3632 List<String> instaceTablesToAdd =
new ArrayList<>();
3634 final String wirelessNetworksDbTableName =
"wireless_networks";
3635 instaceTablesToAdd.add(wirelessNetworksDbTableName +
"_instances");
3636 final String macAddressDbTableName =
"mac_address";
3637 instaceTablesToAdd.add(macAddressDbTableName +
"_instances");
3638 final String imeiNumberDbTableName =
"imei_number";
3639 instaceTablesToAdd.add(imeiNumberDbTableName +
"_instances");
3640 final String iccidNumberDbTableName =
"iccid_number";
3641 instaceTablesToAdd.add(iccidNumberDbTableName +
"_instances");
3642 final String imsiNumberDbTableName =
"imsi_number";
3643 instaceTablesToAdd.add(imsiNumberDbTableName +
"_instances");
3646 preparedStatement = conn.prepareStatement(addAttributeSql);
3647 preparedStatement.setInt(1, CorrelationAttributeInstance.SSID_TYPE_ID);
3648 preparedStatement.setString(2, Bundle.CorrelationType_SSID_displayName());
3649 preparedStatement.setString(3, wirelessNetworksDbTableName);
3650 preparedStatement.setInt(4, 1);
3651 preparedStatement.setInt(5, 1);
3652 preparedStatement.execute();
3655 preparedStatement = conn.prepareStatement(addAttributeSql);
3656 preparedStatement.setInt(1, CorrelationAttributeInstance.MAC_TYPE_ID);
3657 preparedStatement.setString(2, Bundle.CorrelationType_MAC_displayName());
3658 preparedStatement.setString(3, macAddressDbTableName);
3659 preparedStatement.setInt(4, 1);
3660 preparedStatement.setInt(5, 1);
3661 preparedStatement.execute();
3664 preparedStatement = conn.prepareStatement(addAttributeSql);
3665 preparedStatement.setInt(1, CorrelationAttributeInstance.IMEI_TYPE_ID);
3666 preparedStatement.setString(2, Bundle.CorrelationType_IMEI_displayName());
3667 preparedStatement.setString(3, imeiNumberDbTableName);
3668 preparedStatement.setInt(4, 1);
3669 preparedStatement.setInt(5, 1);
3670 preparedStatement.execute();
3673 preparedStatement = conn.prepareStatement(addAttributeSql);
3674 preparedStatement.setInt(1, CorrelationAttributeInstance.IMSI_TYPE_ID);
3675 preparedStatement.setString(2, Bundle.CorrelationType_IMSI_displayName());
3676 preparedStatement.setString(3, imsiNumberDbTableName);
3677 preparedStatement.setInt(4, 1);
3678 preparedStatement.setInt(5, 1);
3679 preparedStatement.execute();
3682 preparedStatement = conn.prepareStatement(addAttributeSql);
3683 preparedStatement.setInt(1, CorrelationAttributeInstance.ICCID_TYPE_ID);
3684 preparedStatement.setString(2, Bundle.CorrelationType_ICCID_displayName());
3685 preparedStatement.setString(3, iccidNumberDbTableName);
3686 preparedStatement.setInt(4, 1);
3687 preparedStatement.setInt(5, 1);
3688 preparedStatement.execute();
3691 for (String tableName : instaceTablesToAdd) {
3692 statement.execute(String.format(addSsidTableTemplate, tableName, tableName));
3693 statement.execute(String.format(addCaseIdIndexTemplate, tableName, tableName));
3694 statement.execute(String.format(addDataSourceIdIndexTemplate, tableName, tableName));
3695 statement.execute(String.format(addValueIndexTemplate, tableName, tableName));
3696 statement.execute(String.format(addKnownStatusIndexTemplate, tableName, tableName));
3700 String instance_type_dbname;
3701 final String objectIdColumnName =
"file_obj_id";
3702 for (CorrelationAttributeInstance.Type type : CorrelationAttributeInstance.getDefaultCorrelationTypes()) {
3703 instance_type_dbname = CentralRepoDbUtil.correlationTypeToInstanceTableName(type);
3704 if (!doesColumnExist(conn, instance_type_dbname, objectIdColumnName)) {
3705 statement.execute(String.format(addIntegerColumnTemplate, instance_type_dbname, objectIdColumnName));
3707 statement.execute(String.format(addObjectIdIndexTemplate, instance_type_dbname, instance_type_dbname));
3713 if (!doesColumnExist(conn, dataSourcesTableName,
"md5")) {
3714 statement.execute(
"ALTER TABLE data_sources ADD COLUMN md5 TEXT DEFAULT NULL");
3716 if (!doesColumnExist(conn, dataSourcesTableName,
"sha1")) {
3717 statement.execute(
"ALTER TABLE data_sources ADD COLUMN sha1 TEXT DEFAULT NULL");
3719 if (!doesColumnExist(conn, dataSourcesTableName,
"sha256")) {
3720 statement.execute(
"ALTER TABLE data_sources ADD COLUMN sha256 TEXT DEFAULT NULL");
3731 String creationMajorVer;
3732 resultSet = statement.executeQuery(
"SELECT value FROM db_info WHERE name = '" + RdbmsCentralRepo.CREATION_SCHEMA_MAJOR_VERSION_KEY +
"'");
3733 if (resultSet.next()) {
3734 creationMajorVer = resultSet.getString(
"value");
3736 creationMajorVer =
"0";
3738 String creationMinorVer;
3739 resultSet = statement.executeQuery(
"SELECT value FROM db_info WHERE name = '" + RdbmsCentralRepo.CREATION_SCHEMA_MINOR_VERSION_KEY +
"'");
3740 if (resultSet.next()) {
3741 creationMinorVer = resultSet.getString(
"value");
3743 creationMinorVer =
"0";
3745 statement.execute(
"DROP TABLE db_info");
3746 if (selectedPlatform == CentralRepoPlatforms.POSTGRESQL) {
3747 statement.execute(
"CREATE TABLE db_info (id SERIAL, name TEXT UNIQUE NOT NULL, value TEXT NOT NULL)");
3749 statement.execute(
"CREATE TABLE db_info (id INTEGER PRIMARY KEY, name TEXT UNIQUE NOT NULL, value TEXT NOT NULL)");
3751 statement.execute(
"INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.SCHEMA_MAJOR_VERSION_KEY +
"','" + majorVersionStr +
"')");
3752 statement.execute(
"INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.SCHEMA_MINOR_VERSION_KEY +
"','" + minorVersionStr +
"')");
3753 statement.execute(
"INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.CREATION_SCHEMA_MAJOR_VERSION_KEY +
"','" + creationMajorVer +
"')");
3754 statement.execute(
"INSERT INTO db_info (name, value) VALUES ('" + RdbmsCentralRepo.CREATION_SCHEMA_MINOR_VERSION_KEY +
"','" + creationMinorVer +
"')");
3759 if (dbSchemaVersion.compareTo(
new CaseDbSchemaVersionNumber(1, 3)) < 0) {
3760 switch (selectedPlatform) {
3762 statement.execute(
"ALTER TABLE data_sources DROP CONSTRAINT datasource_unique");
3764 statement.execute(
"ALTER TABLE data_sources ADD CONSTRAINT datasource_unique UNIQUE (case_id, device_id, name, datasource_obj_id)");
3768 statement.execute(
"DROP INDEX IF EXISTS data_sources_name");
3769 statement.execute(
"DROP INDEX IF EXISTS data_sources_object_id");
3770 statement.execute(
"ALTER TABLE data_sources RENAME TO old_data_sources");
3772 statement.execute(
"CREATE TABLE IF NOT EXISTS data_sources (id integer primary key autoincrement NOT NULL,"
3773 +
"case_id integer NOT NULL,device_id text NOT NULL,name text NOT NULL,datasource_obj_id integer,"
3774 +
"md5 text DEFAULT NULL,sha1 text DEFAULT NULL,sha256 text DEFAULT NULL,"
3775 +
"foreign key (case_id) references cases(id) ON UPDATE SET NULL ON DELETE SET NULL,"
3776 +
"CONSTRAINT datasource_unique UNIQUE (case_id, device_id, name, datasource_obj_id))");
3777 statement.execute(RdbmsCentralRepoFactory.getAddDataSourcesNameIndexStatement());
3778 statement.execute(RdbmsCentralRepoFactory.getAddDataSourcesObjectIdIndexStatement());
3779 statement.execute(
"INSERT INTO data_sources SELECT * FROM old_data_sources");
3780 statement.execute(
"DROP TABLE old_data_sources");
3783 throw new CentralRepoException(
"Currently selected database platform \"" + selectedPlatform.name() +
"\" can not be upgraded.", Bundle.AbstractSqlEamDb_cannotUpgrage_message(selectedPlatform.name()));
3788 (
new CentralRepoDbUpgrader13To14()).upgradeSchema(dbSchemaVersion, conn);
3790 updateSchemaVersion(conn);
3792 logger.log(Level.INFO, String.format(
"Central Repository schema updated to version %s", SOFTWARE_CR_DB_SCHEMA_VERSION));
3793 }
catch (SQLException | CentralRepoException ex) {
3798 }
catch (SQLException ex2) {
3799 logger.log(Level.SEVERE, String.format(
"Central Repository rollback of failed schema update to %s failed", SOFTWARE_CR_DB_SCHEMA_VERSION), ex2);
3803 CentralRepoDbUtil.closeResultSet(resultSet);
3804 CentralRepoDbUtil.closeStatement(preparedStatement);
3805 CentralRepoDbUtil.closeStatement(statement);
3806 CentralRepoDbUtil.closeConnection(conn);
CentralRepoAccount getOrCreateAccount(CentralRepoAccount.CentralRepoAccountType crAccountType, String accountUniqueID)