Merge remote-tracking branch 'upstream/develop' into 3245_updateSchema

This commit is contained in:
Ann Priestman 2017-12-01 16:22:33 -05:00
commit 1bb1b65408
17 changed files with 209 additions and 157 deletions

View File

@ -89,7 +89,7 @@ class AddLocalFilesTask implements Runnable {
progress.setIndeterminate(true); progress.setIndeterminate(true);
FileManager fileManager = Case.getCurrentCase().getServices().getFileManager(); FileManager fileManager = Case.getCurrentCase().getServices().getFileManager();
LocalFilesDataSource newDataSource = fileManager.addLocalFilesDataSource(deviceId, rootVirtualDirectoryName, "", localFilePaths, new ProgressUpdater()); LocalFilesDataSource newDataSource = fileManager.addLocalFilesDataSource(deviceId, rootVirtualDirectoryName, "", localFilePaths, new ProgressUpdater());
newDataSources.add(newDataSource.getRootDirectory()); newDataSources.add(newDataSource);
} catch (TskDataException | TskCoreException ex) { } catch (TskDataException | TskCoreException ex) {
errors.add(ex.getMessage()); errors.add(ex.getMessage());
LOGGER.log(Level.SEVERE, String.format("Failed to add datasource: %s", ex.getMessage()), ex); LOGGER.log(Level.SEVERE, String.format("Failed to add datasource: %s", ex.getMessage()), ex);

View File

@ -78,10 +78,9 @@ final class CasePropertiesPanel extends javax.swing.JPanel {
try { try {
EamDb dbManager = EamDb.getInstance(); EamDb dbManager = EamDb.getInstance();
if (dbManager != null) { if (dbManager != null) {
CorrelationCase correlationCase = dbManager.getCaseByUUID(Case.getCurrentCase().getName()); CorrelationCase correlationCase = dbManager.getCase(Case.getCurrentCase());
if (null == correlationCase) { if (null == correlationCase) {
dbManager.newCase(Case.getCurrentCase()); correlationCase = dbManager.newCase(Case.getCurrentCase());
correlationCase = dbManager.getCaseByUUID(Case.getCurrentCase().getName());
} }
currentOrg = correlationCase.getOrg(); currentOrg = correlationCase.getOrg();
} }

View File

@ -91,7 +91,7 @@ final class NewCaseWizardAction extends CallableSystemAction {
if (EamDb.isEnabled()) { //if the eam is enabled we need to save the case organization information now if (EamDb.isEnabled()) { //if the eam is enabled we need to save the case organization information now
EamDb dbManager = EamDb.getInstance(); EamDb dbManager = EamDb.getInstance();
if (dbManager != null) { if (dbManager != null) {
CorrelationCase cRCase = dbManager.getCaseByUUID(Case.getCurrentCase().getName()); CorrelationCase cRCase = dbManager.getCase(Case.getCurrentCase());
if (cRCase == null) { if (cRCase == null) {
cRCase = dbManager.newCase(Case.getCurrentCase()); cRCase = dbManager.newCase(Case.getCurrentCase());
} }

View File

@ -89,7 +89,7 @@ final class OptionalCasePropertiesPanel extends javax.swing.JPanel {
if (currentCase != null) { if (currentCase != null) {
try { try {
EamDb dbManager = EamDb.getInstance(); EamDb dbManager = EamDb.getInstance();
selectedOrg = dbManager.getCaseByUUID(currentCase.getName()).getOrg(); selectedOrg = dbManager.getCase(currentCase).getOrg();
} catch (EamDbException ex) { } catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Unable to get Organization associated with the case from Central Repo", ex); LOGGER.log(Level.SEVERE, "Unable to get Organization associated with the case from Central Repo", ex);
} }
@ -561,7 +561,7 @@ final class OptionalCasePropertiesPanel extends javax.swing.JPanel {
if (EamDb.isEnabled()) { if (EamDb.isEnabled()) {
try { try {
EamDb dbManager = EamDb.getInstance(); EamDb dbManager = EamDb.getInstance();
CorrelationCase correlationCase = dbManager.getCaseByUUID(Case.getCurrentCase().getName()); CorrelationCase correlationCase = dbManager.getCase(Case.getCurrentCase());
if (caseDisplayNameTextField.isVisible()) { if (caseDisplayNameTextField.isVisible()) {
correlationCase.setDisplayName(caseDisplayNameTextField.getText()); correlationCase.setDisplayName(caseDisplayNameTextField.getText());
} }

View File

@ -47,7 +47,6 @@ import org.sleuthkit.datamodel.LocalFilesDataSource;
import org.sleuthkit.datamodel.TskDataException; import org.sleuthkit.datamodel.TskDataException;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.AbstractContent;
import org.sleuthkit.datamodel.CarvingResult; import org.sleuthkit.datamodel.CarvingResult;
import org.sleuthkit.datamodel.TskData; import org.sleuthkit.datamodel.TskData;
@ -409,10 +408,9 @@ public class FileManager implements Closeable {
*/ */
trans = caseDb.beginTransaction(); trans = caseDb.beginTransaction();
LocalFilesDataSource dataSource = caseDb.addLocalFilesDataSource(deviceId, rootDirectoryName, timeZone, trans); LocalFilesDataSource dataSource = caseDb.addLocalFilesDataSource(deviceId, rootDirectoryName, timeZone, trans);
VirtualDirectory rootDirectory = dataSource.getRootDirectory();
List<AbstractFile> filesAdded = new ArrayList<>(); List<AbstractFile> filesAdded = new ArrayList<>();
for (java.io.File localFile : localFiles) { for (java.io.File localFile : localFiles) {
AbstractFile fileAdded = addLocalFile(trans, rootDirectory, localFile, TskData.EncodingType.NONE, progressUpdater); AbstractFile fileAdded = addLocalFile(trans, dataSource, localFile, TskData.EncodingType.NONE, progressUpdater);
if (null != fileAdded) { if (null != fileAdded) {
filesAdded.add(fileAdded); filesAdded.add(fileAdded);
} else { } else {

View File

@ -177,7 +177,7 @@ public class DataContentViewerOtherCases extends javax.swing.JPanel implements D
} }
caseDisplayName = eamCasePartial.getDisplayName(); caseDisplayName = eamCasePartial.getDisplayName();
// query case details // query case details
CorrelationCase eamCase = dbManager.getCaseByUUID(eamCasePartial.getCaseUUID()); CorrelationCase eamCase = dbManager.getCase(Case.getCurrentCase());
if (eamCase == null) { if (eamCase == null) {
JOptionPane.showConfirmDialog(showCaseDetailsMenuItem, JOptionPane.showConfirmDialog(showCaseDetailsMenuItem,
Bundle.DataContentViewerOtherCases_caseDetailsDialog_noDetails(), Bundle.DataContentViewerOtherCases_caseDetailsDialog_noDetails(),

View File

@ -173,9 +173,10 @@ public abstract class AbstractSqlEamDb implements EamDb {
* Expects the Organization for this case to already exist in the database. * Expects the Organization for this case to already exist in the database.
* *
* @param eamCase The case to add * @param eamCase The case to add
* @returns New Case class with populated database ID
*/ */
@Override @Override
public void newCase(CorrelationCase eamCase) throws EamDbException { public CorrelationCase newCase(CorrelationCase eamCase) throws EamDbException {
Connection conn = connect(); Connection conn = connect();
PreparedStatement preparedStatement = null; PreparedStatement preparedStatement = null;
@ -228,6 +229,9 @@ public abstract class AbstractSqlEamDb implements EamDb {
EamDbUtil.closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
EamDbUtil.closeConnection(conn); EamDbUtil.closeConnection(conn);
} }
// get a new version with the updated ID
return getCaseByUUID(eamCase.getCaseUUID());
} }
/** /**
@ -252,10 +256,15 @@ public abstract class AbstractSqlEamDb implements EamDb {
autopsyCase.getExaminerEmail(), autopsyCase.getExaminerEmail(),
autopsyCase.getExaminerPhone(), autopsyCase.getExaminerPhone(),
autopsyCase.getCaseNotes()); autopsyCase.getCaseNotes());
newCase(curCeCase); return newCase(curCeCase);
return curCeCase;
} }
@Override
public CorrelationCase getCase(Case autopsyCase) throws EamDbException {
return getCaseByUUID(autopsyCase.getName());
}
/** /**
* Updates an existing Case in the database * Updates an existing Case in the database
* *
@ -435,7 +444,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
* @return The data source * @return The data source
*/ */
@Override @Override
public CorrelationDataSource getDataSourceDetails(CorrelationCase correlationCase, String dataSourceDeviceId) throws EamDbException { public CorrelationDataSource getDataSource(CorrelationCase correlationCase, String dataSourceDeviceId) throws EamDbException {
Connection conn = connect(); Connection conn = connect();
CorrelationDataSource eamDataSourceResult = null; CorrelationDataSource eamDataSourceResult = null;
@ -453,7 +462,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
eamDataSourceResult = getEamDataSourceFromResultSet(resultSet); eamDataSourceResult = getEamDataSourceFromResultSet(resultSet);
} }
} catch (SQLException ex) { } catch (SQLException ex) {
throw new EamDbException("Error getting case details.", ex); // NON-NLS throw new EamDbException("Error getting data source.", ex); // NON-NLS
} finally { } finally {
EamDbUtil.closePreparedStatement(preparedStatement); EamDbUtil.closePreparedStatement(preparedStatement);
EamDbUtil.closeResultSet(resultSet); EamDbUtil.closeResultSet(resultSet);
@ -1060,12 +1069,12 @@ public abstract class AbstractSqlEamDb implements EamDb {
// We could improve effiency by keeping a list of all datasources and cases // We could improve effiency by keeping a list of all datasources and cases
// in the database, but we don't expect the user to be tagging large numbers // in the database, but we don't expect the user to be tagging large numbers
// of items (that didn't have the CE ingest module run on them) at once. // of items (that didn't have the CE ingest module run on them) at once.
CorrelationCase correlationCase = getCaseByUUID(eamInstance.getCorrelationCase().getCaseUUID()); CorrelationCase correlationCaseWithId = getCaseByUUID(eamInstance.getCorrelationCase().getCaseUUID());
if (null == correlationCase) { if (null == correlationCaseWithId) {
newCase(eamInstance.getCorrelationCase()); correlationCaseWithId = newCase(eamInstance.getCorrelationCase());
correlationCase = getCaseByUUID(eamInstance.getCorrelationCase().getCaseUUID());
} }
if (null == getDataSourceDetails(correlationCase, eamInstance.getCorrelationDataSource().getDeviceID())) {
if (null == getDataSource(correlationCaseWithId, eamInstance.getCorrelationDataSource().getDeviceID())) {
newDataSource(eamInstance.getCorrelationDataSource()); newDataSource(eamInstance.getCorrelationDataSource());
} }
eamArtifact.getInstances().get(0).setKnownStatus(knownStatus); eamArtifact.getInstances().get(0).setKnownStatus(knownStatus);
@ -2149,7 +2158,7 @@ public abstract class AbstractSqlEamDb implements EamDb {
return null; return null;
} }
CorrelationAttributeInstance eamArtifactInstance = new CorrelationAttributeInstance( CorrelationAttributeInstance eamArtifactInstance = new CorrelationAttributeInstance(
new CorrelationCase(resultSet.getString("case_uid"), resultSet.getString("case_name")), new CorrelationCase(resultSet.getInt("case_id"), resultSet.getString("case_uid"), resultSet.getString("case_name")),
new CorrelationDataSource(-1, resultSet.getInt("case_id"), resultSet.getString("device_id"), resultSet.getString("name")), new CorrelationDataSource(-1, resultSet.getInt("case_id"), resultSet.getString("device_id"), resultSet.getString("name")),
resultSet.getString("file_path"), resultSet.getString("file_path"),
resultSet.getString("comment"), resultSet.getString("comment"),

View File

@ -50,15 +50,11 @@ public class CorrelationCase implements Serializable {
* @param caseUUID Globally unique identifier * @param caseUUID Globally unique identifier
* @param displayName * @param displayName
*/ */
public CorrelationCase(String caseUUID, String displayName) {
this(-1, caseUUID, null, displayName, DATE_FORMAT.format(new Date()), null, null, null, null, null);
}
CorrelationCase(int ID, String caseUUID, String displayName) { CorrelationCase(int ID, String caseUUID, String displayName) {
this(ID, caseUUID, null, displayName, DATE_FORMAT.format(new Date()), null, null, null, null, null); this(ID, caseUUID, null, displayName, DATE_FORMAT.format(new Date()), null, null, null, null, null);
} }
public CorrelationCase(int ID, CorrelationCase(int ID,
String caseUUID, String caseUUID,
EamOrganization org, EamOrganization org,
String displayName, String displayName,

View File

@ -96,10 +96,9 @@ public class EamArtifactUtil {
} }
// make an instance for the BB source file // make an instance for the BB source file
CorrelationCase correlationCase = EamDb.getInstance().getCaseByUUID(Case.getCurrentCase().getName()); CorrelationCase correlationCase = EamDb.getInstance().getCase(Case.getCurrentCase());
if (null == correlationCase) { if (null == correlationCase) {
EamDb.getInstance().newCase(Case.getCurrentCase()); correlationCase = EamDb.getInstance().newCase(Case.getCurrentCase());
correlationCase = EamDb.getInstance().getCaseByUUID(Case.getCurrentCase().getName());
} }
CorrelationAttributeInstance eamInstance = new CorrelationAttributeInstance( CorrelationAttributeInstance eamInstance = new CorrelationAttributeInstance(
correlationCase, correlationCase,
@ -250,10 +249,9 @@ public class EamArtifactUtil {
try { try {
CorrelationAttribute.Type filesType = EamDb.getInstance().getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID); CorrelationAttribute.Type filesType = EamDb.getInstance().getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID);
eamArtifact = new CorrelationAttribute(filesType, af.getMd5Hash()); eamArtifact = new CorrelationAttribute(filesType, af.getMd5Hash());
CorrelationCase correlationCase = EamDb.getInstance().getCaseByUUID(Case.getCurrentCase().getName()); CorrelationCase correlationCase = EamDb.getInstance().getCase(Case.getCurrentCase());
if (null == correlationCase) { if (null == correlationCase) {
EamDb.getInstance().newCase(Case.getCurrentCase()); correlationCase = EamDb.getInstance().newCase(Case.getCurrentCase());
correlationCase = EamDb.getInstance().getCaseByUUID(Case.getCurrentCase().getName());
} }
CorrelationAttributeInstance cei = new CorrelationAttributeInstance( CorrelationAttributeInstance cei = new CorrelationAttributeInstance(
correlationCase, correlationCase,

View File

@ -136,7 +136,7 @@ public interface EamDb {
* *
* @param eamCase The case to add * @param eamCase The case to add
*/ */
void newCase(CorrelationCase eamCase) throws EamDbException; CorrelationCase newCase(CorrelationCase eamCase) throws EamDbException;
/** /**
* Creates new Case in the database from the given case * Creates new Case in the database from the given case
@ -145,6 +145,8 @@ public interface EamDb {
*/ */
CorrelationCase newCase(Case autopsyCase) throws EamDbException; CorrelationCase newCase(Case autopsyCase) throws EamDbException;
/** /**
* Updates an existing Case in the database * Updates an existing Case in the database
* *
@ -152,6 +154,15 @@ public interface EamDb {
*/ */
void updateCase(CorrelationCase eamCase) throws EamDbException; void updateCase(CorrelationCase eamCase) throws EamDbException;
/**
* Retrieves Central Repo case based on an Autopsy Case
*
* @param autopsyCase Autopsy case to find corresponding CR case for
* @return CR Case
* @throws EamDbException
*/
CorrelationCase getCase(Case autopsyCase) throws EamDbException;
/** /**
* Retrieves Case details based on Case UUID * Retrieves Case details based on Case UUID
* *
@ -184,7 +195,7 @@ public interface EamDb {
* *
* @return The data source * @return The data source
*/ */
CorrelationDataSource getDataSourceDetails(CorrelationCase correlationCase, String dataSourceDeviceId) throws EamDbException; CorrelationDataSource getDataSource(CorrelationCase correlationCase, String dataSourceDeviceId) throws EamDbException;
/** /**
* Retrieves data sources that are in DB * Retrieves data sources that are in DB

View File

@ -149,16 +149,14 @@ public class SqliteEamDb extends AbstractSqlEamDb {
* *
*/ */
private void setupConnectionPool() throws EamDbException { private void setupConnectionPool() throws EamDbException {
if (dbSettings.dbFileExists() == false) {
throw new EamDbException("Central repository database missing");
}
connectionPool = new BasicDataSource(); connectionPool = new BasicDataSource();
connectionPool.setDriverClassName(dbSettings.getDriver()); connectionPool.setDriverClassName(dbSettings.getDriver());
connectionPool.setUrl(dbSettings.getConnectionURL());
StringBuilder connectionURL = new StringBuilder();
connectionURL.append(dbSettings.getJDBCBaseURI());
connectionURL.append(dbSettings.getDbDirectory());
connectionURL.append(File.separator);
connectionURL.append(dbSettings.getDbName());
connectionPool.setUrl(connectionURL.toString());
// tweak pool configuration // tweak pool configuration
connectionPool.setInitialSize(50); connectionPool.setInitialSize(50);
@ -279,10 +277,10 @@ public class SqliteEamDb extends AbstractSqlEamDb {
* @param eamCase The case to add * @param eamCase The case to add
*/ */
@Override @Override
public void newCase(CorrelationCase eamCase) throws EamDbException { public CorrelationCase newCase(CorrelationCase eamCase) throws EamDbException {
try{ try{
acquireExclusiveLock(); acquireExclusiveLock();
super.newCase(eamCase); return super.newCase(eamCase);
} finally { } finally {
releaseExclusiveLock(); releaseExclusiveLock();
} }
@ -359,10 +357,10 @@ public class SqliteEamDb extends AbstractSqlEamDb {
* @return The data source * @return The data source
*/ */
@Override @Override
public CorrelationDataSource getDataSourceDetails(CorrelationCase correlationCase, String dataSourceDeviceId) throws EamDbException { public CorrelationDataSource getDataSource(CorrelationCase correlationCase, String dataSourceDeviceId) throws EamDbException {
try{ try{
acquireSharedLock(); acquireSharedLock();
return super.getDataSourceDetails(correlationCase, dataSourceDeviceId); return super.getDataSource(correlationCase, dataSourceDeviceId);
} finally { } finally {
releaseSharedLock(); releaseSharedLock();
} }

View File

@ -430,12 +430,11 @@ final class CaseEventListener implements PropertyChangeListener {
try { try {
String deviceId = Case.getCurrentCase().getSleuthkitCase().getDataSource(newDataSource.getId()).getDeviceId(); String deviceId = Case.getCurrentCase().getSleuthkitCase().getDataSource(newDataSource.getId()).getDeviceId();
CorrelationCase correlationCase = dbManager.getCaseByUUID(Case.getCurrentCase().getName()); CorrelationCase correlationCase = dbManager.getCase(Case.getCurrentCase());
if (null == correlationCase) { if (null == correlationCase) {
dbManager.newCase(Case.getCurrentCase()); correlationCase = dbManager.newCase(Case.getCurrentCase());
correlationCase = dbManager.getCaseByUUID(Case.getCurrentCase().getName());
} }
if (null == dbManager.getDataSourceDetails(correlationCase, deviceId)) { if (null == dbManager.getDataSource(correlationCase, deviceId)) {
dbManager.newDataSource(CorrelationDataSource.fromTSKDataSource(correlationCase, newDataSource)); dbManager.newDataSource(CorrelationDataSource.fromTSKDataSource(correlationCase, newDataSource));
} }
} catch (EamDbException ex) { } catch (EamDbException ex) {
@ -466,18 +465,6 @@ final class CaseEventListener implements PropertyChangeListener {
Case curCase = (Case) event.getNewValue(); Case curCase = (Case) event.getNewValue();
IngestEventsListener.resetCeModuleInstanceCount(); IngestEventsListener.resetCeModuleInstanceCount();
CorrelationCase curCeCase = new CorrelationCase(
-1,
curCase.getName(), // unique case ID
EamOrganization.getDefault(),
curCase.getDisplayName(),
curCase.getCreatedDate(),
curCase.getNumber(),
curCase.getExaminer(),
curCase.getExaminerEmail(),
curCase.getExaminerPhone(),
curCase.getCaseNotes());
if (!EamDb.isEnabled()) { if (!EamDb.isEnabled()) {
return; return;
} }
@ -485,10 +472,8 @@ final class CaseEventListener implements PropertyChangeListener {
try { try {
// NOTE: Cannot determine if the opened case is a new case or a reopened case, // NOTE: Cannot determine if the opened case is a new case or a reopened case,
// so check for existing name in DB and insert if missing. // so check for existing name in DB and insert if missing.
CorrelationCase existingCase = dbManager.getCaseByUUID(curCeCase.getCaseUUID()); if (dbManager.getCase(curCase) == null) {
dbManager.newCase(curCase);
if (null == existingCase) {
dbManager.newCase(curCeCase);
} }
} catch (EamDbException ex) { } catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Error connecting to Central Repository database.", ex); //NON-NLS LOGGER.log(Level.SEVERE, "Error connecting to Central Repository database.", ex); //NON-NLS

View File

@ -201,47 +201,36 @@ class IngestModule implements FileIngestModule {
} }
jobId = context.getJobId(); jobId = context.getJobId();
EamDb dbManager; EamDb centralRepoDb;
try { try {
dbManager = EamDb.getInstance(); centralRepoDb = EamDb.getInstance();
} catch (EamDbException ex) { } catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Error connecting to central repository database.", ex); // NON-NLS LOGGER.log(Level.SEVERE, "Error connecting to central repository database.", ex); // NON-NLS
throw new IngestModuleException("Error connecting to central repository database.", ex); // NON-NLS throw new IngestModuleException("Error connecting to central repository database.", ex); // NON-NLS
} }
try { try {
filesType = dbManager.getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID); filesType = centralRepoDb.getCorrelationTypeById(CorrelationAttribute.FILES_TYPE_ID);
} catch (EamDbException ex) { } catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Error getting correlation type FILES in ingest module start up.", ex); // NON-NLS LOGGER.log(Level.SEVERE, "Error getting correlation type FILES in ingest module start up.", ex); // NON-NLS
throw new IngestModuleException("Error getting correlation type FILES in ingest module start up.", ex); // NON-NLS throw new IngestModuleException("Error getting correlation type FILES in ingest module start up.", ex); // NON-NLS
} }
Case curCase = Case.getCurrentCase(); Case autopsyCase = Case.getCurrentCase();
try { try {
eamCase = dbManager.getCaseByUUID(curCase.getName()); eamCase = centralRepoDb.getCase(autopsyCase);
} catch (EamDbException ex) { } catch (EamDbException ex) {
throw new IngestModuleException("Unable to get case from central repository database ", ex); throw new IngestModuleException("Unable to get case from central repository database ", ex);
} }
if (eamCase == null) { if (eamCase == null) {
// ensure we have this case defined in the EAM DB // ensure we have this case defined in the EAM DB
CorrelationCase curCeCase = new CorrelationCase(
-1,
curCase.getName(), // unique case ID
EamOrganization.getDefault(),
curCase.getDisplayName(),
curCase.getCreatedDate(),
curCase.getNumber(),
curCase.getExaminer(),
curCase.getExaminerEmail(),
curCase.getExaminerPhone(),
curCase.getCaseNotes());
try { try {
dbManager.newCase(curCeCase); eamCase = centralRepoDb.newCase(autopsyCase);
eamCase = dbManager.getCaseByUUID(curCase.getName());
} catch (EamDbException ex) { } catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Error creating new case in ingest module start up.", ex); // NON-NLS LOGGER.log(Level.SEVERE, "Error creating new case in ingest module start up.", ex); // NON-NLS
throw new IngestModuleException("Error creating new case in ingest module start up.", ex); // NON-NLS throw new IngestModuleException("Error creating new case in ingest module start up.", ex); // NON-NLS
} }
} }
try { try {
eamDataSource = CorrelationDataSource.fromTSKDataSource(eamCase, context.getDataSource()); eamDataSource = CorrelationDataSource.fromTSKDataSource(eamCase, context.getDataSource());
} catch (EamDbException ex) { } catch (EamDbException ex) {
@ -255,12 +244,12 @@ class IngestModule implements FileIngestModule {
== 1) { == 1) {
// ensure we have this data source in the EAM DB // ensure we have this data source in the EAM DB
try { try {
if (null == dbManager.getDataSourceDetails(eamCase, eamDataSource.getDeviceID())) { if (null == centralRepoDb.getDataSource(eamCase, eamDataSource.getDeviceID())) {
dbManager.newDataSource(eamDataSource); centralRepoDb.newDataSource(eamDataSource);
} }
} catch (EamDbException ex) { } catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Error creating new data source in ingest module start up.", ex); // NON-NLS LOGGER.log(Level.SEVERE, "Error adding data source to Central Repository.", ex); // NON-NLS
throw new IngestModuleException("Error creating new data source in ingest module start up.", ex); // NON-NLS throw new IngestModuleException("Error adding data source to Central Repository.", ex); // NON-NLS
} }
} }

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2017 Basis Technology Corp. * Copyright 2017 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -31,6 +31,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
final class AutoIngestMetricsCollector { final class AutoIngestMetricsCollector {
private static final Logger LOGGER = Logger.getLogger(AutoIngestMetricsCollector.class.getName()); private static final Logger LOGGER = Logger.getLogger(AutoIngestMetricsCollector.class.getName());
private static final int MINIMUM_SUPPORTED_JOB_NODE_VERSION = 1;
private CoordinationService coordinationService; private CoordinationService coordinationService;
/** /**
@ -59,7 +60,7 @@ final class AutoIngestMetricsCollector {
for (String node : nodeList) { for (String node : nodeList) {
try { try {
AutoIngestJobNodeData nodeData = new AutoIngestJobNodeData(coordinationService.getNodeData(CoordinationService.CategoryNode.MANIFESTS, node)); AutoIngestJobNodeData nodeData = new AutoIngestJobNodeData(coordinationService.getNodeData(CoordinationService.CategoryNode.MANIFESTS, node));
if (nodeData.getVersion() < 1) { if (nodeData.getVersion() < MINIMUM_SUPPORTED_JOB_NODE_VERSION) {
/* /*
* Ignore version '0' nodes that have not been * Ignore version '0' nodes that have not been
* "upgraded" since they don't carry enough data. * "upgraded" since they don't carry enough data.
@ -78,7 +79,7 @@ final class AutoIngestMetricsCollector {
*/ */
break; break;
case COMPLETED: case COMPLETED:
newMetricsSnapshot.addCompletedJobDate(job.getCompletedDate()); newMetricsSnapshot.addCompletedJobMetric(job.getCompletedDate(), job.getDataSourceSize());
break; break;
default: default:
LOGGER.log(Level.SEVERE, "Unknown AutoIngestJobData.ProcessingStatus"); LOGGER.log(Level.SEVERE, "Unknown AutoIngestJobData.ProcessingStatus");
@ -106,24 +107,63 @@ final class AutoIngestMetricsCollector {
*/ */
static final class MetricsSnapshot { static final class MetricsSnapshot {
private final List<Long> completedJobDates = new ArrayList<>(); private final List<JobMetric> completedJobMetrics = new ArrayList<>();
/** /**
* Gets a list of completed job dates, formatted in milliseconds. * Gets a list of completed job metrics.
* *
* @return The completed job dates, formatted in milliseconds. * @return The completed job metrics.
*/ */
List<Long> getCompletedJobDates() { List<JobMetric> getCompletedJobMetrics() {
return new ArrayList<>(completedJobDates); return new ArrayList<>(completedJobMetrics);
} }
/** /**
* Adds a new date to the list of completed job dates. * Adds a new metric to the list of completed job metrics.
* *
* @param date The date to be added. * @param completedDate The completed job date.
* @param dataSourceSize The data source size.
*/ */
void addCompletedJobDate(java.util.Date date) { void addCompletedJobMetric(java.util.Date completedDate, long dataSourceSize) {
completedJobDates.add(date.getTime()); completedJobMetrics.add(new JobMetric(completedDate, dataSourceSize));
}
}
/**
* A single job metric for an auto ingest cluster.
*/
static final class JobMetric {
private final long completedDate;
private final long dataSourceSize;
/**
* Instantiates a job metric.
*
* @param completedDate The job completion date.
* @param dataSourceSize The data source size.
*/
JobMetric(java.util.Date completedDate, long dataSourceSize) {
this.completedDate = completedDate.getTime();
this.dataSourceSize = dataSourceSize;
}
/**
* Gets the job completion date, formatted in milliseconds.
*
* @return The job completion date.
*/
long getCompletedDate() {
return completedDate;
}
/**
* Gets the data source size.
*
* @return The data source size.
*/
long getDataSourceSize() {
return dataSourceSize;
} }
} }

View File

@ -30,10 +30,14 @@
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="jScrollPane1" alignment="0" max="32767" attributes="0"/> <Component id="jScrollPane1" alignment="0" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<Component id="metricsButton" min="-2" max="-2" attributes="0"/> <Component id="startingDataLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="datePicker" min="-2" max="-2" attributes="0"/> <Component id="datePicker" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="33" max="32767" attributes="0"/> <EmptySpace pref="7" max="32767" attributes="0"/>
<Component id="metricsButton" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="1" attributes="0">
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
<Component id="closeButton" min="-2" pref="70" max="-2" attributes="0"/> <Component id="closeButton" min="-2" pref="70" max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
@ -43,17 +47,17 @@
</DimensionLayout> </DimensionLayout>
<DimensionLayout dim="1"> <DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0"> <Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="metricsButton" min="-2" max="-2" attributes="0"/>
<Component id="datePicker" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="startingDataLabel" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="jScrollPane1" min="-2" pref="128" max="-2" attributes="0"/> <Component id="jScrollPane1" min="-2" pref="128" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/> <EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Component id="closeButton" min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="closeButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="metricsButton" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="datePicker" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/> <EmptySpace max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
@ -109,5 +113,12 @@
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new DatePicker();"/> <AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new DatePicker();"/>
</AuxValues> </AuxValues>
</Component> </Component>
<Component class="javax.swing.JLabel" name="startingDataLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/autoingest/Bundle.properties" key="AutoIngestMetricsDialog.startingDataLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</SubComponents> </SubComponents>
</Form> </Form>

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2011-2017 Basis Technology Corp. * Copyright 2017 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -25,14 +25,18 @@ import java.awt.Window;
import java.sql.Date; import java.sql.Date;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.time.ZoneOffset; import java.time.ZoneOffset;
import java.util.List;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages; import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.experimental.autoingest.AutoIngestMetricsCollector.JobMetric;
/** /**
* Displays auto ingest metrics for a cluster. * Displays auto ingest metrics for a cluster.
*/ */
final class AutoIngestMetricsDialog extends javax.swing.JDialog { final class AutoIngestMetricsDialog extends javax.swing.JDialog {
private static final int GIGABYTE_SIZE = 1073741824;
private final AutoIngestMetricsCollector autoIngestMetricsCollector; private final AutoIngestMetricsCollector autoIngestMetricsCollector;
/** /**
@ -42,7 +46,7 @@ final class AutoIngestMetricsDialog extends javax.swing.JDialog {
*/ */
@Messages({ @Messages({
"AutoIngestMetricsDialog.title.text=Auto Ingest Cluster Metrics", "AutoIngestMetricsDialog.title.text=Auto Ingest Cluster Metrics",
"AutoIngestMetricsDialog.initReportText=Select a date below and click the 'Get Metrics Since...' button to generate\na metrics report." "AutoIngestMetricsDialog.initReportText=Select a date above and click the 'Generate Metrics Report' button to generate\na metrics report."
}) })
AutoIngestMetricsDialog(Container parent) throws AutoIngestMetricsDialogException { AutoIngestMetricsDialog(Container parent) throws AutoIngestMetricsDialogException {
super((Window) parent, NbBundle.getMessage(AutoIngestMetricsDialog.class, "AutoIngestMetricsDialog.title.text"), ModalityType.MODELESS); super((Window) parent, NbBundle.getMessage(AutoIngestMetricsDialog.class, "AutoIngestMetricsDialog.title.text"), ModalityType.MODELESS);
@ -63,26 +67,31 @@ final class AutoIngestMetricsDialog extends javax.swing.JDialog {
* Update the metrics shown in the report text area. * Update the metrics shown in the report text area.
*/ */
private void updateMetrics() { private void updateMetrics() {
if(datePicker.getDate() == null) { if (datePicker.getDate() == null) {
return; return;
} }
AutoIngestMetricsCollector.MetricsSnapshot metricsSnapshot = autoIngestMetricsCollector.queryCoordinationServiceForMetrics(); AutoIngestMetricsCollector.MetricsSnapshot metricsSnapshot = autoIngestMetricsCollector.queryCoordinationServiceForMetrics();
Object[] completedJobDates = metricsSnapshot.getCompletedJobDates().toArray(); List<JobMetric> completedJobMetrics = metricsSnapshot.getCompletedJobMetrics();
int count = 0; int jobsCompleted = 0;
long dataSourceSizeTotal = 0;
long pickedDate = datePicker.getDate().atStartOfDay().toEpochSecond(ZoneOffset.UTC) * 1000; long pickedDate = datePicker.getDate().atStartOfDay().toEpochSecond(ZoneOffset.UTC) * 1000;
for(int i = completedJobDates.length - 1; i >= 0; i--) {
if((Long)completedJobDates[i] >= pickedDate) { for (JobMetric jobMetric : completedJobMetrics) {
count++; if (jobMetric.getCompletedDate() >= pickedDate) {
jobsCompleted++;
dataSourceSizeTotal += jobMetric.getDataSourceSize();
} }
} }
SimpleDateFormat dateFormatter = new SimpleDateFormat("MMM d, yyyy"); SimpleDateFormat dateFormatter = new SimpleDateFormat("MMM d, yyyy");
reportTextArea.setText(String.format( reportTextArea.setText(String.format(
"Since %s:\n" + "Since %s:\n"
"\tNumber of Jobs Completed: %d\n", + "Number of Jobs Completed: %d\n"
+ "Total Size of Data Sources: %.1f GB\n",
dateFormatter.format(Date.valueOf(datePicker.getDate())), dateFormatter.format(Date.valueOf(datePicker.getDate())),
count jobsCompleted,
(double) dataSourceSizeTotal / GIGABYTE_SIZE
)); ));
} }
@ -131,6 +140,7 @@ final class AutoIngestMetricsDialog extends javax.swing.JDialog {
reportTextArea = new javax.swing.JTextArea(); reportTextArea = new javax.swing.JTextArea();
metricsButton = new javax.swing.JButton(); metricsButton = new javax.swing.JButton();
datePicker = new DatePicker(); datePicker = new DatePicker();
startingDataLabel = new javax.swing.JLabel();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
setAlwaysOnTop(true); setAlwaysOnTop(true);
@ -158,6 +168,8 @@ final class AutoIngestMetricsDialog extends javax.swing.JDialog {
datePicker.setToolTipText(org.openide.util.NbBundle.getMessage(AutoIngestMetricsDialog.class, "AutoIngestMetricsDialog.datePicker.toolTipText")); // NOI18N datePicker.setToolTipText(org.openide.util.NbBundle.getMessage(AutoIngestMetricsDialog.class, "AutoIngestMetricsDialog.datePicker.toolTipText")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(startingDataLabel, org.openide.util.NbBundle.getMessage(AutoIngestMetricsDialog.class, "AutoIngestMetricsDialog.startingDataLabel.text")); // NOI18N
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout); getContentPane().setLayout(layout);
layout.setHorizontalGroup( layout.setHorizontalGroup(
@ -167,24 +179,28 @@ final class AutoIngestMetricsDialog extends javax.swing.JDialog {
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1) .addComponent(jScrollPane1)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addComponent(metricsButton) .addComponent(startingDataLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(datePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(datePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 33, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 7, Short.MAX_VALUE)
.addComponent(metricsButton))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(0, 0, Short.MAX_VALUE)
.addComponent(closeButton, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE))) .addComponent(closeButton, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addContainerGap()) .addContainerGap())
); );
layout.setVerticalGroup( layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addContainerGap() .addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(metricsButton)
.addComponent(datePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(startingDataLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 128, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 128, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(closeButton)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(closeButton)
.addComponent(metricsButton))
.addComponent(datePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
); );
@ -208,5 +224,6 @@ final class AutoIngestMetricsDialog extends javax.swing.JDialog {
private javax.swing.JScrollPane jScrollPane1; private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JButton metricsButton; private javax.swing.JButton metricsButton;
private javax.swing.JTextArea reportTextArea; private javax.swing.JTextArea reportTextArea;
private javax.swing.JLabel startingDataLabel;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
} }

View File

@ -228,10 +228,11 @@ AutoIngestDashboard.prioritizeCaseButton.toolTipText=Move all images associated
AutoIngestDashboard.prioritizeCaseButton.text=Prioritize &Case AutoIngestDashboard.prioritizeCaseButton.text=Prioritize &Case
AutoIngestMetricsDialog.reportTextArea.text= AutoIngestMetricsDialog.reportTextArea.text=
AutoIngestDashboard.clusterMetricsButton.text=Cluster Metrics AutoIngestDashboard.clusterMetricsButton.text=Cluster Metrics
AutoIngestMetricsDialog.metricsButton.text=Get Metrics Since... AutoIngestMetricsDialog.metricsButton.text=Generate Metrics Report
AutoIngestMetricsDialog.closeButton.text=Close AutoIngestMetricsDialog.closeButton.text=Close
AutoIngestMetricsDialog.datePicker.toolTipText=Choose a date AutoIngestMetricsDialog.datePicker.toolTipText=Choose a date
ArchiveFilePanel.pathLabel.text=Browse for an archive file: ArchiveFilePanel.pathLabel.text=Browse for an archive file:
ArchiveFilePanel.browseButton.text=Browse ArchiveFilePanel.browseButton.text=Browse
ArchiveFilePanel.pathTextField.text= ArchiveFilePanel.pathTextField.text=
ArchiveFilePanel.errorLabel.text=Error Label ArchiveFilePanel.errorLabel.text=Error Label
AutoIngestMetricsDialog.startingDataLabel.text=Starting Date: