19package org.sleuthkit.autopsy.ingest;
21import java.lang.reflect.InvocationTargetException;
22import java.util.ArrayList;
24import java.util.HashSet;
26import java.util.Optional;
28import java.util.concurrent.CopyOnWriteArrayList;
29import java.util.logging.Level;
30import javax.annotation.concurrent.GuardedBy;
31import javax.swing.JOptionPane;
32import javax.swing.SwingUtilities;
33import org.netbeans.api.progress.ProgressHandle;
34import org.openide.util.Cancellable;
35import org.openide.util.NbBundle;
36import org.openide.util.NbBundle.Messages;
37import org.openide.windows.WindowManager;
38import org.sleuthkit.autopsy.casemodule.Case;
39import org.sleuthkit.autopsy.core.RuntimeProperties;
40import org.sleuthkit.autopsy.coreutils.Logger;
41import org.sleuthkit.autopsy.coreutils.NetworkUtils;
42import org.sleuthkit.autopsy.coreutils.ThreadConfined;
43import org.sleuthkit.datamodel.AbstractFile;
44import org.sleuthkit.datamodel.IngestJobInfo;
45import org.sleuthkit.datamodel.IngestJobInfo.IngestJobStatusType;
46import org.sleuthkit.datamodel.IngestModuleInfo;
47import org.sleuthkit.datamodel.IngestModuleInfo.IngestModuleType;
48import org.sleuthkit.datamodel.SleuthkitCase;
49import org.sleuthkit.datamodel.TskCoreException;
50import org.sleuthkit.autopsy.modules.interestingitems.FilesSet;
51import org.sleuthkit.autopsy.python.FactoryClassNameNormalizer;
52import org.sleuthkit.datamodel.AnalysisResult;
53import org.sleuthkit.datamodel.DataArtifact;
54import org.sleuthkit.datamodel.DataSource;
61final class IngestJobExecutor {
71 private final long createTime;
72 private final boolean usingNetBeansGUI;
73 private final IngestTasksScheduler taskScheduler = IngestTasksScheduler.getInstance();
74 private final Object threadRegistrationLock =
new Object();
75 @GuardedBy(
"threadRegistrationLock")
76 private final Set<Thread> pausedIngestThreads = new HashSet<>();
77 private final List<String> cancelledDataSourceIngestModules = new CopyOnWriteArrayList<>();
78 private final Object tierTransitionLock = new Object();
79 private final List<IngestModuleTier> ingestModuleTiers = new ArrayList<>();
80 private volatile
int moduleTierIndex = 0;
82 private volatile
long estimatedFilesToProcess = 0;
83 private volatile
long processedFiles = 0;
84 private volatile
boolean currentDataSourceIngestModuleCancelled = false;
85 private volatile
boolean jobCancelled = false;
86 private volatile
IngestJob.CancellationReason cancellationReason =
IngestJob.CancellationReason.NOT_CANCELLED;
87 private volatile IngestJobInfo casDbingestJobInfo;
89 private ProgressHandle dataSourceIngestProgressBar;
91 private final List<String> filesInProgress = new ArrayList<>();
93 private ProgressHandle fileIngestProgressBar;
95 private ProgressHandle artifactIngestProgressBar;
97 private ProgressHandle resultIngestProgressBar;
111 IngestJobExecutor(
IngestJob ingestJob) throws InterruptedException {
112 this.ingestJob = ingestJob;
113 createTime =
new Date().getTime();
131 long getIngestJobId() {
132 return ingestJob.
getId();
141 String getExecutionContext() {
151 DataSource getDataSource() {
152 return ingestJob.getDataSource();
161 boolean shouldProcessUnallocatedSpace() {
171 FilesSet getFileIngestFilter() {
190 List<IngestModuleError> startUp() throws InterruptedException {
192 ingestModuleTiers.addAll(IngestModuleTierBuilder.buildIngestModuleTiers(ingestJob.getSettings(),
this));
193 List<IngestModuleError> errors = startUpIngestModulePipelines();
194 if (errors.isEmpty()) {
195 recordIngestJobStartUpInfo();
202 if (ingestJob.getIngestMode() == IngestJob.Mode.STREAMING) {
203 startStreamingModeAnalysis();
205 startBatchModeAnalysis();
216 private List<IngestModuleError> startUpIngestModulePipelines() {
217 List<IngestModuleError> errors =
new ArrayList<>();
218 for (IngestModuleTier moduleTier : ingestModuleTiers) {
219 Optional<DataSourceIngestPipeline> dataSourcePipeline = moduleTier.getDataSourceIngestPipeline();
220 if (dataSourcePipeline.isPresent()) {
221 errors.addAll(startUpIngestModulePipeline(dataSourcePipeline.get()));
224 for (FileIngestPipeline pipeline : moduleTier.getFileIngestPipelines()) {
225 List<IngestModuleError> filePipelineErrors = startUpIngestModulePipeline(pipeline);
226 if (!filePipelineErrors.isEmpty()) {
232 errors.addAll(filePipelineErrors);
237 Optional<DataArtifactIngestPipeline> dataArtifactPipeline = moduleTier.getDataArtifactIngestPipeline();
238 if (dataArtifactPipeline.isPresent()) {
239 errors.addAll(startUpIngestModulePipeline(dataArtifactPipeline.get()));
242 Optional<AnalysisResultIngestPipeline> analysisResultPipeline = moduleTier.getAnalysisResultIngestPipeline();
243 if (analysisResultPipeline.isPresent()) {
244 errors.addAll(startUpIngestModulePipeline(analysisResultPipeline.get()));
258 private List<IngestModuleError> startUpIngestModulePipeline(IngestPipeline<?> pipeline) {
259 List<IngestModuleError> startUpErrors = pipeline.startUp();
260 if (!startUpErrors.isEmpty()) {
261 List<IngestModuleError> shutDownErrors = pipeline.shutDown();
262 if (!shutDownErrors.isEmpty()) {
263 logIngestModuleErrors(shutDownErrors);
266 return startUpErrors;
274 private void recordIngestJobStartUpInfo() {
276 SleuthkitCase caseDb = Case.getCurrentCase().getSleuthkitCase();
277 List<IngestModuleInfo> ingestModuleInfoList =
new ArrayList<>();
278 for (IngestModuleTemplate module : ingestJob.getSettings().getEnabledIngestModuleTemplates()) {
279 IngestModuleType moduleType = getIngestModuleTemplateType(module);
280 IngestModuleInfo moduleInfo = caseDb.addIngestModule(module.getModuleName(), FactoryClassNameNormalizer.normalize(module.getModuleFactory().getClass().getCanonicalName()), moduleType, module.getModuleFactory().getModuleVersionNumber());
281 ingestModuleInfoList.add(moduleInfo);
283 casDbingestJobInfo = caseDb.addIngestJob(ingestJob.getDataSource(), NetworkUtils.getLocalHostName(), ingestModuleInfoList,
new Date(this.createTime),
new Date(0), IngestJobStatusType.STARTED,
"");
284 }
catch (TskCoreException ex) {
285 logErrorMessage(Level.SEVERE,
"Failed to add ingest job info to case database", ex);
297 private static IngestModuleType getIngestModuleTemplateType(IngestModuleTemplate moduleTemplate) {
298 IngestModuleType type =
null;
299 if (moduleTemplate.isDataSourceIngestModuleTemplate()) {
300 type = IngestModuleType.DATA_SOURCE_LEVEL;
302 if (moduleTemplate.isFileIngestModuleTemplate()) {
304 type = IngestModuleType.FILE_LEVEL;
306 type = IngestModuleType.MULTIPLE;
309 if (moduleTemplate.isDataArtifactIngestModuleTemplate()) {
311 type = IngestModuleType.DATA_ARTIFACT;
313 type = IngestModuleType.MULTIPLE;
325 private void startBatchModeAnalysis() {
326 synchronized (tierTransitionLock) {
327 logInfoMessage(
"Starting ingest job in file batch mode");
329 IngestModuleTier currentTier = ingestModuleTiers.get(moduleTierIndex);
331 if (currentTier.hasDataSourceIngestModules()) {
332 startDataSourceIngestProgressBar();
333 taskScheduler.scheduleDataSourceIngestTask(
this);
336 if (currentTier.hasFileIngestModules()) {
337 estimateFilesToProcess();
338 startFileIngestProgressBar(
true);
339 taskScheduler.scheduleFileIngestTasks(
this, ingestJob.getFiles());
342 if (currentTier.hasDataArtifactIngestModules()) {
347 startDataArtifactIngestProgressBar();
348 taskScheduler.scheduleDataArtifactIngestTasks(
this);
351 if (currentTier.hasAnalysisResultIngestModules()) {
356 startAnalysisResultIngestProgressBar();
357 taskScheduler.scheduleAnalysisResultIngestTasks(
this);
369 checkForTierCompleted(moduleTierIndex);
376 private void estimateFilesToProcess() {
377 estimatedFilesToProcess = 0;
379 if (ingestModuleTiers.get(moduleTierIndex).hasFileIngestModules()) {
386 List<AbstractFile> files = ingestJob.getFiles();
387 if (files.isEmpty()) {
392 estimatedFilesToProcess = ingestJob.getDataSource().accept(
new GetFilesCountVisitor());
398 estimatedFilesToProcess = files.size();
410 private void startStreamingModeAnalysis() {
411 synchronized (tierTransitionLock) {
412 logInfoMessage(
"Starting ingest job in file streaming mode");
414 IngestModuleTier currentTier = ingestModuleTiers.get(moduleTierIndex);
416 if (currentTier.hasFileIngestModules()) {
424 startFileIngestProgressBar(
false);
427 if (currentTier.hasDataArtifactIngestModules()) {
438 startDataArtifactIngestProgressBar();
439 taskScheduler.scheduleDataArtifactIngestTasks(
this);
442 if (currentTier.hasAnalysisResultIngestModules()) {
454 startAnalysisResultIngestProgressBar();
455 taskScheduler.scheduleAnalysisResultIngestTasks(
this);
465 void addStreamedDataSource() {
466 synchronized (tierTransitionLock) {
467 logInfoMessage(
"Data source received in streaming mode ingest job");
468 jobState = IngestJobExecutor.IngestJobState.ANALYZING;
469 IngestModuleTier currentTier = ingestModuleTiers.get(moduleTierIndex);
471 if (currentTier.hasFileIngestModules()) {
472 estimateFilesToProcess();
473 switchFileIngestProgressBarToDeterminate();
478 if (currentTier.hasDataSourceIngestModules()) {
479 taskScheduler.scheduleDataSourceIngestTask(
this);
480 startDataSourceIngestProgressBar();
491 checkForTierCompleted(moduleTierIndex);
501 private void checkForTierCompleted(
int currentTier) {
502 synchronized (tierTransitionLock) {
506 if (currentTier < moduleTierIndex) {
511 if (taskScheduler.currentTasksAreCompleted(getIngestJobId())) {
513 shutDownCurrentTier();
515 if (moduleTierIndex < ingestModuleTiers.size()) {
516 startAnalysisForCurrentTier();
521 }
while (taskScheduler.currentTasksAreCompleted(getIngestJobId()));
530 private void startAnalysisForCurrentTier() {
531 logInfoMessage(String.format(
"Scheduling ingest tasks for tier %s of ingest job", moduleTierIndex));
532 jobState = IngestJobExecutor.IngestJobState.ANALYZING;
533 IngestModuleTier currentTier = ingestModuleTiers.get(moduleTierIndex);
535 if (currentTier.hasDataSourceIngestModules()) {
536 startDataSourceIngestProgressBar();
537 taskScheduler.scheduleDataSourceIngestTask(
this);
540 if (currentTier.hasFileIngestModules()) {
541 estimateFilesToProcess();
542 startFileIngestProgressBar(
true);
543 taskScheduler.scheduleFileIngestTasks(
this, ingestJob.getFiles());
546 if (currentTier.hasDataArtifactIngestModules()) {
547 startDataArtifactIngestProgressBar();
550 if (currentTier.hasAnalysisResultIngestModules()) {
551 startDataArtifactIngestProgressBar();
562 void execute(DataSourceIngestTask task) {
564 if (!isCancelled()) {
565 Optional<DataSourceIngestPipeline> pipeline = ingestModuleTiers.get(moduleTierIndex).getDataSourceIngestPipeline();
566 if (pipeline.isPresent()) {
567 List<IngestModuleError> errors =
new ArrayList<>();
568 errors.addAll(pipeline.get().performTask(task));
569 if (!errors.isEmpty()) {
570 logIngestModuleErrors(errors);
577 int currentTier = moduleTierIndex;
578 taskScheduler.notifyTaskCompleted(task);
579 checkForTierCompleted(currentTier);
590 void execute(FileIngestTask task) {
592 if (!isCancelled()) {
593 FileIngestPipeline pipeline = ingestModuleTiers.get(moduleTierIndex).takeFileIngestPipeline();
594 if (!pipeline.isEmpty()) {
602 file = task.getFile();
603 }
catch (TskCoreException ex) {
604 List<IngestModuleError> errors =
new ArrayList<>();
605 errors.add(
new IngestModuleError(
"Ingest Pipeline", ex));
606 logIngestModuleErrors(errors);
607 ingestModuleTiers.get(moduleTierIndex).returnFileIngestPipeleine(pipeline);
615 final String fileName = file.getName();
617 updateFileProgressBarForFileTaskStarted(fileName);
618 List<IngestModuleError> errors =
new ArrayList<>();
619 errors.addAll(pipeline.performTask(task));
620 if (!errors.isEmpty()) {
621 logIngestModuleErrors(errors, file);
623 updateFileProgressBarForFileTaskCompleted(fileName);
625 ingestModuleTiers.get(moduleTierIndex).returnFileIngestPipeleine(pipeline);
627 }
catch (InterruptedException ex) {
628 logger.log(Level.SEVERE, String.format(
"File ingest thread interrupted during execution of file ingest job (file object ID = %d, thread ID = %d)", task.getFileId(), task.getThreadId()), ex);
629 Thread.currentThread().interrupt();
633 int currentTier = moduleTierIndex;
634 taskScheduler.notifyTaskCompleted(task);
635 checkForTierCompleted(currentTier);
646 void execute(DataArtifactIngestTask task) {
648 if (!isCancelled()) {
649 Optional<DataArtifactIngestPipeline> pipeline = ingestModuleTiers.get(moduleTierIndex).getDataArtifactIngestPipeline();
650 if (pipeline.isPresent()) {
651 List<IngestModuleError> errors =
new ArrayList<>();
652 errors.addAll(pipeline.get().performTask(task));
653 if (!errors.isEmpty()) {
654 logIngestModuleErrors(errors);
661 int currentTier = moduleTierIndex;
662 taskScheduler.notifyTaskCompleted(task);
663 checkForTierCompleted(currentTier);
674 void execute(AnalysisResultIngestTask task) {
676 if (!isCancelled()) {
677 Optional<AnalysisResultIngestPipeline> pipeline = ingestModuleTiers.get(moduleTierIndex).getAnalysisResultIngestPipeline();
678 if (pipeline.isPresent()) {
679 List<IngestModuleError> errors =
new ArrayList<>();
680 errors.addAll(pipeline.get().performTask(task));
681 if (!errors.isEmpty()) {
682 logIngestModuleErrors(errors);
689 int currentTier = moduleTierIndex;
690 taskScheduler.notifyTaskCompleted(task);
691 checkForTierCompleted(currentTier);
700 void addStreamedFiles(List<Long> fileObjIds) {
701 if (!isCancelled() && ingestModuleTiers.get(moduleTierIndex).hasFileIngestModules()) {
703 taskScheduler.scheduleStreamedFileIngestTasks(
this, fileObjIds);
705 logErrorMessage(Level.SEVERE,
"Adding streaming files to job during stage " + jobState.toString() +
" not supported");
721 void addFiles(List<AbstractFile> files) {
722 if (!isCancelled() && ingestModuleTiers.get(moduleTierIndex).hasFileIngestModules()) {
724 taskScheduler.scheduleHighPriorityFileIngestTasks(
this, files);
726 logErrorMessage(Level.SEVERE,
"Adding files to job during stage " + jobState.toString() +
" not supported");
741 void addDataArtifacts(List<DataArtifact> artifacts) {
742 if (!isCancelled() && ingestModuleTiers.get(moduleTierIndex).hasDataArtifactIngestModules()) {
744 case ACCEPTING_STREAMED_CONTENT_AND_ANALYZING:
746 taskScheduler.scheduleDataArtifactIngestTasks(
this, artifacts);
748 case PIPELINES_SHUTTING_DOWN:
766 logErrorMessage(Level.SEVERE,
"Attempt to add data artifacts to job during stage " + jobState.toString() +
" not supported");
782 void addAnalysisResults(List<AnalysisResult> results) {
783 if (!isCancelled() && ingestModuleTiers.get(moduleTierIndex).hasAnalysisResultIngestModules()) {
785 case ACCEPTING_STREAMED_CONTENT_AND_ANALYZING:
787 taskScheduler.scheduleAnalysisResultIngestTasks(
this, results);
789 case PIPELINES_SHUTTING_DOWN:
805 logErrorMessage(Level.SEVERE,
"Attempt to add analysis results to job during stage " + jobState.toString() +
" not supported");
813 private void shutDownCurrentTier() {
816 if (moduleTierIndex >= ingestModuleTiers.size()) {
817 logErrorMessage(Level.SEVERE,
"shutDownCurrentTier called with out-of-bounds moduleTierIndex (" + moduleTierIndex +
")");
820 logInfoMessage(String.format(
"Finished all ingest tasks for tier %s of ingest job", moduleTierIndex));
821 jobState = IngestJobExecutor.IngestJobState.PIPELINES_SHUTTING_DOWN;
822 IngestModuleTier moduleTier = ingestModuleTiers.get(moduleTierIndex);
824 Optional<DataSourceIngestPipeline> dataSourcePipeline = moduleTier.getDataSourceIngestPipeline();
825 if (dataSourcePipeline.isPresent()) {
826 shutDownIngestModulePipeline(dataSourcePipeline.get());
829 for (FileIngestPipeline pipeline : moduleTier.getFileIngestPipelines()) {
830 shutDownIngestModulePipeline(pipeline);
833 Optional<DataArtifactIngestPipeline> dataArtifactPipeline = moduleTier.getDataArtifactIngestPipeline();
834 if (dataArtifactPipeline.isPresent()) {
835 shutDownIngestModulePipeline(dataArtifactPipeline.get());
838 Optional<AnalysisResultIngestPipeline> analysisResultPipeline = moduleTier.getAnalysisResultIngestPipeline();
839 if (analysisResultPipeline.isPresent()) {
840 shutDownIngestModulePipeline(analysisResultPipeline.get());
843 finishAllProgressBars();
851 private <T extends IngestTask>
void shutDownIngestModulePipeline(IngestPipeline<T> pipeline) {
852 if (pipeline.isRunning()) {
853 List<IngestModuleError> errors =
new ArrayList<>();
854 errors.addAll(pipeline.shutDown());
855 if (!errors.isEmpty()) {
856 logIngestModuleErrors(errors);
864 private void shutDown() {
865 logInfoMessage(
"Finished all ingest tasks for ingest job");
867 if (casDbingestJobInfo !=
null) {
869 casDbingestJobInfo.setIngestJobStatus(IngestJobStatusType.CANCELLED);
871 casDbingestJobInfo.setIngestJobStatus(IngestJobStatusType.COMPLETED);
873 casDbingestJobInfo.setEndDateTime(
new Date());
875 }
catch (TskCoreException ex) {
876 logErrorMessage(Level.WARNING,
"Failed to set job end date in case database", ex);
879 ingestJob.notifyIngestPipelinesShutDown();
887 DataSourceIngestPipeline.DataSourcePipelineModule getCurrentDataSourceIngestModule() {
888 Optional<DataSourceIngestPipeline> pipeline = getCurrentDataSourceIngestPipelines();
889 if (pipeline.isPresent()) {
890 return (DataSourceIngestPipeline.DataSourcePipelineModule) pipeline.get().getCurrentlyRunningModule();
909 void cancelCurrentDataSourceIngestModule() {
910 currentDataSourceIngestModuleCancelled =
true;
929 boolean currentDataSourceIngestModuleIsCancelled() {
930 return currentDataSourceIngestModuleCancelled;
950 void currentDataSourceIngestModuleCancellationCompleted(String moduleDisplayName) {
951 currentDataSourceIngestModuleCancelled =
false;
952 cancelledDataSourceIngestModules.add(moduleDisplayName);
953 if (usingNetBeansGUI && !jobCancelled) {
957 SwingUtilities.invokeAndWait(() -> {
966 dataSourceIngestProgressBar.finish();
967 dataSourceIngestProgressBar =
null;
968 startDataSourceIngestProgressBar();
970 }
catch (InvocationTargetException | InterruptedException ex) {
971 logger.log(Level.WARNING,
"Cancellation worker cancelled.", ex);
986 void cancel(IngestJob.CancellationReason reason) {
988 cancellationReason = reason;
989 displayCancellingProgressMessages();
990 taskScheduler.cancelPendingFileTasksForIngestJob(getIngestJobId());
991 synchronized (threadRegistrationLock) {
992 for (Thread thread : pausedIngestThreads) {
995 pausedIngestThreads.clear();
997 checkForTierCompleted(moduleTierIndex);
1007 boolean isCancelled() {
1008 return jobCancelled;
1016 IngestJob.CancellationReason getCancellationReason() {
1017 return cancellationReason;
1027 private void startDataSourceIngestProgressBar() {
1028 if (usingNetBeansGUI) {
1029 SwingUtilities.invokeLater(() -> {
1030 dataSourceIngestProgressBar = ProgressHandle.createHandle(NbBundle.getMessage(
this.getClass(),
"IngestJob.progress.dataSourceIngest.initialDisplayName", ingestJob.getDataSource().getName()),
new Cancellable() {
1032 public boolean cancel() {
1041 DataSourceIngestCancellationPanel panel =
new DataSourceIngestCancellationPanel();
1042 String dialogTitle = NbBundle.getMessage(IngestJobExecutor.this.getClass(),
"IngestJob.cancellationDialog.title");
1043 JOptionPane.showConfirmDialog(WindowManager.getDefault().getMainWindow(), panel, dialogTitle, JOptionPane.OK_OPTION, JOptionPane.PLAIN_MESSAGE);
1044 if (panel.cancelAllDataSourceIngestModules()) {
1046 IngestJobExecutor.this.cancel(IngestJob.CancellationReason.USER_CANCELLED);
1050 IngestJobExecutor.this.cancelCurrentDataSourceIngestModule();
1056 dataSourceIngestProgressBar.start();
1057 dataSourceIngestProgressBar.switchToIndeterminate();
1068 void changeDataSourceIngestProgressBarTitle(String title) {
1069 if (usingNetBeansGUI && !jobCancelled) {
1070 SwingUtilities.invokeLater(() -> {
1071 if (dataSourceIngestProgressBar !=
null) {
1072 dataSourceIngestProgressBar.setDisplayName(title);
1082 void switchDataSourceIngestProgressBarToIndeterminate() {
1083 if (usingNetBeansGUI && !jobCancelled) {
1084 SwingUtilities.invokeLater(() -> {
1085 if (dataSourceIngestProgressBar !=
null) {
1086 dataSourceIngestProgressBar.switchToIndeterminate();
1087 dataSourceIngestProgressBar.progress(
"");
1099 void switchDataSourceIngestProgressBarToDeterminate(
int workUnitsToDo) {
1100 if (usingNetBeansGUI && !jobCancelled) {
1101 SwingUtilities.invokeLater(() -> {
1102 if (dataSourceIngestProgressBar !=
null) {
1103 dataSourceIngestProgressBar.switchToDeterminate(workUnitsToDo);
1126 void updateDataSourceIngestProgressBar(String newText,
int workUnitsDone) {
1127 if (usingNetBeansGUI && !jobCancelled) {
1128 SwingUtilities.invokeLater(() -> {
1129 if (dataSourceIngestProgressBar !=
null) {
1130 dataSourceIngestProgressBar.progress(newText, workUnitsDone);
1142 void updateDataSourceIngestProgressBarText(String newText) {
1143 if (usingNetBeansGUI && !jobCancelled) {
1144 SwingUtilities.invokeLater(() -> {
1145 if (dataSourceIngestProgressBar !=
null) {
1146 dataSourceIngestProgressBar.progress(newText);
1165 void updateDataSourceIngestProgressBar(
int workUnitsDone) {
1166 if (usingNetBeansGUI && !jobCancelled) {
1167 SwingUtilities.invokeLater(() -> {
1168 if (dataSourceIngestProgressBar !=
null) {
1169 dataSourceIngestProgressBar.progress(
"", workUnitsDone);
1186 private void startFileIngestProgressBar(
boolean useDeterminateMode) {
1187 if (usingNetBeansGUI) {
1188 SwingUtilities.invokeLater(() -> {
1189 fileIngestProgressBar = ProgressHandle.createHandle(NbBundle.getMessage(getClass(),
"IngestJob.progress.fileIngest.displayName", ingestJob.getDataSource().getName()),
new Cancellable() {
1191 public boolean cancel() {
1193 IngestJobExecutor.this.cancel(IngestJob.CancellationReason.USER_CANCELLED);
1198 if (useDeterminateMode) {
1199 fileIngestProgressBar.start((
int) estimatedFilesToProcess);
1201 fileIngestProgressBar.start();
1212 private void switchFileIngestProgressBarToDeterminate() {
1213 if (usingNetBeansGUI) {
1214 SwingUtilities.invokeLater(() -> {
1215 if (fileIngestProgressBar !=
null) {
1216 fileIngestProgressBar.switchToDeterminate((
int) estimatedFilesToProcess);
1229 private void updateFileProgressBarForFileTaskStarted(String fileName) {
1230 if (usingNetBeansGUI && !jobCancelled) {
1231 SwingUtilities.invokeLater(() -> {
1243 long processedFilesCapture = processedFiles;
1244 if (processedFilesCapture <= estimatedFilesToProcess) {
1245 fileIngestProgressBar.progress(fileName, (
int) processedFilesCapture);
1247 fileIngestProgressBar.progress(fileName, (
int) estimatedFilesToProcess);
1249 filesInProgress.add(fileName);
1262 private void updateFileProgressBarForFileTaskCompleted(String completedFileName) {
1263 if (usingNetBeansGUI && !jobCancelled) {
1264 SwingUtilities.invokeLater(() -> {
1265 filesInProgress.remove(completedFileName);
1270 if (filesInProgress.size() > 0) {
1271 fileIngestProgressBar.progress(filesInProgress.get(0));
1273 fileIngestProgressBar.progress(
"");
1285 private void startDataArtifactIngestProgressBar() {
1286 if (usingNetBeansGUI) {
1287 SwingUtilities.invokeLater(() -> {
1288 artifactIngestProgressBar = ProgressHandle.createHandle(NbBundle.getMessage(
this.getClass(),
"IngestJob.progress.dataArtifactIngest.displayName", ingestJob.getDataSource().getName()),
new Cancellable() {
1290 public boolean cancel() {
1292 IngestJobExecutor.this.cancel(IngestJob.CancellationReason.USER_CANCELLED);
1297 artifactIngestProgressBar.start();
1298 artifactIngestProgressBar.switchToIndeterminate();
1309 @NbBundle.Messages({
1310 "# {0} - data source name",
1311 "IngestJob_progress_analysisResultIngest_displayName=Analyzing analysis results from {0}"
1313 private void startAnalysisResultIngestProgressBar() {
1314 if (usingNetBeansGUI) {
1315 SwingUtilities.invokeLater(() -> {
1316 resultIngestProgressBar = ProgressHandle.createHandle(Bundle.IngestJob_progress_analysisResultIngest_displayName(ingestJob.getDataSource().getName()),
new Cancellable() {
1318 public boolean cancel() {
1320 IngestJobExecutor.this.cancel(IngestJob.CancellationReason.USER_CANCELLED);
1325 resultIngestProgressBar.start();
1326 resultIngestProgressBar.switchToIndeterminate();
1335 private void displayCancellingProgressMessages() {
1336 if (usingNetBeansGUI) {
1337 SwingUtilities.invokeLater(() -> {
1338 if (dataSourceIngestProgressBar !=
null) {
1339 dataSourceIngestProgressBar.setDisplayName(NbBundle.getMessage(getClass(),
"IngestJob.progress.dataSourceIngest.initialDisplayName", ingestJob.getDataSource().getName()));
1340 dataSourceIngestProgressBar.progress(NbBundle.getMessage(getClass(),
"IngestJob.progress.cancelling"));
1342 if (fileIngestProgressBar !=
null) {
1343 fileIngestProgressBar.setDisplayName(NbBundle.getMessage(getClass(),
"IngestJob.progress.fileIngest.displayName", ingestJob.getDataSource().getName()));
1344 fileIngestProgressBar.progress(NbBundle.getMessage(getClass(),
"IngestJob.progress.cancelling"));
1346 if (artifactIngestProgressBar !=
null) {
1347 artifactIngestProgressBar.setDisplayName(NbBundle.getMessage(getClass(),
"IngestJob.progress.dataArtifactIngest.displayName", ingestJob.getDataSource().getName()));
1348 artifactIngestProgressBar.progress(NbBundle.getMessage(getClass(),
"IngestJob.progress.cancelling"));
1350 if (resultIngestProgressBar !=
null) {
1351 resultIngestProgressBar.setDisplayName(Bundle.IngestJob_progress_analysisResultIngest_displayName(ingestJob.getDataSource().getName()));
1352 resultIngestProgressBar.progress(NbBundle.getMessage(getClass(),
"IngestJob.progress.cancelling"));
1361 private void finishAllProgressBars() {
1362 if (usingNetBeansGUI) {
1363 SwingUtilities.invokeLater(() -> {
1364 if (dataSourceIngestProgressBar !=
null) {
1365 dataSourceIngestProgressBar.finish();
1366 dataSourceIngestProgressBar =
null;
1369 if (fileIngestProgressBar !=
null) {
1370 fileIngestProgressBar.finish();
1371 fileIngestProgressBar =
null;
1374 if (artifactIngestProgressBar !=
null) {
1375 artifactIngestProgressBar.finish();
1376 artifactIngestProgressBar =
null;
1379 if (resultIngestProgressBar !=
null) {
1380 resultIngestProgressBar.finish();
1381 resultIngestProgressBar =
null;
1393 private void logInfoMessage(String message) {
1394 logger.log(Level.INFO, String.format(
"%s (data source = %s, data source object ID = %d, job ID = %d)", message, ingestJob.getDataSource().getName(), ingestJob.getDataSource().getId(), getIngestJobId()));
1405 private void logErrorMessage(Level level, String message, Throwable throwable) {
1406 logger.log(level, String.format(
"%s (data source = %s, data source object ID = %d, ingest job ID = %d)", message, ingestJob.getDataSource().getName(), ingestJob.getDataSource().getId(), getIngestJobId()), throwable);
1416 private void logErrorMessage(Level level, String message) {
1417 logger.log(level, String.format(
"%s (data source = %s, data source object ID= %d, ingest job ID %d)", message, ingestJob.getDataSource().getName(), ingestJob.getDataSource().getId(), getIngestJobId()));
1425 private void logIngestModuleErrors(List<IngestModuleError> errors) {
1426 for (IngestModuleError error : errors) {
1427 logErrorMessage(Level.SEVERE, String.format(
"%s experienced an error during analysis", error.getModuleDisplayName()), error.getThrowable());
1437 private void logIngestModuleErrors(List<IngestModuleError> errors, AbstractFile file) {
1438 for (IngestModuleError error : errors) {
1439 logErrorMessage(Level.SEVERE, String.format(
"%s experienced an error during analysis while processing file %s (object ID = %d)", error.getModuleDisplayName(), file.getName(), file.getId()), error.getThrowable());
1448 Optional<List<FileIngestPipeline>> getCurrentFileIngestPipelines() {
1450 int currentModuleTierIndex = moduleTierIndex;
1451 if (currentModuleTierIndex < ingestModuleTiers.size()) {
1452 return Optional.of(ingestModuleTiers.get(currentModuleTierIndex).getFileIngestPipelines());
1454 return Optional.empty();
1462 Optional<DataSourceIngestPipeline> getCurrentDataSourceIngestPipelines() {
1464 int currentModuleTierIndex = moduleTierIndex;
1465 if (currentModuleTierIndex < ingestModuleTiers.size()) {
1466 return ingestModuleTiers.get(currentModuleTierIndex).getDataSourceIngestPipeline();
1468 return Optional.empty();
1482 "IngestJobExecutor_progress_snapshot_currentTier_shutDown_modifier=shut down",
1483 "# {0} - tier number",
1484 "# {1} - job state modifer",
1485 "IngestJobExecutor_progress_snapshot_currentTier=Tier {0} {1}"
1487 IngestJobProgressSnapshot getIngestJobProgressSnapshot(
boolean includeIngestTasksSnapshot) {
1493 boolean fileIngestRunning =
false;
1494 Date fileIngestStartTime =
null;
1495 Optional<List<FileIngestPipeline>> fileIngestPipelines = getCurrentFileIngestPipelines();
1496 if (!fileIngestPipelines.isPresent()) {
1498 fileIngestPipelines = Optional.of(ingestModuleTiers.get(0).getFileIngestPipelines());
1500 for (FileIngestPipeline pipeline : fileIngestPipelines.get()) {
1501 if (pipeline.isRunning()) {
1502 fileIngestRunning =
true;
1504 Date pipelineStartTime = pipeline.getStartTime();
1505 if (pipelineStartTime !=
null && (fileIngestStartTime ==
null || pipelineStartTime.before(fileIngestStartTime))) {
1506 fileIngestStartTime = pipelineStartTime;
1510 long processedFilesCount = 0;
1511 long estimatedFilesToProcessCount = 0;
1512 long snapShotTime =
new Date().getTime();
1513 IngestTasksScheduler.IngestTasksSnapshot tasksSnapshot =
null;
1514 if (includeIngestTasksSnapshot) {
1515 processedFilesCount = processedFiles;
1516 estimatedFilesToProcessCount = estimatedFilesToProcess;
1517 snapShotTime =
new Date().getTime();
1518 tasksSnapshot = taskScheduler.getTasksSnapshotForJob(getIngestJobId());
1520 return new IngestJobProgressSnapshot(
1521 ingestJob.getDataSource().getName(),
1524 Bundle.IngestJobExecutor_progress_snapshot_currentTier(moduleTierIndex, jobState.equals(
IngestJobState.
PIPELINES_SHUTTING_DOWN) ? Bundle.IngestJobExecutor_progress_snapshot_currentTier_shutDown_modifier() :
""),
1525 getCurrentDataSourceIngestModule(),
1527 fileIngestStartTime,
1530 cancelledDataSourceIngestModules,
1531 processedFilesCount,
1532 estimatedFilesToProcessCount,
1543 void registerPausedIngestThread(Thread thread) {
1544 synchronized (threadRegistrationLock) {
1545 pausedIngestThreads.add(thread);
1555 void unregisterPausedIngestThread(Thread thread) {
1556 synchronized (threadRegistrationLock) {
1557 pausedIngestThreads.remove(thread);
static boolean runningWithGUI
synchronized static Logger getLogger(String name)
String getExecutionContext()
boolean getProcessUnallocatedSpace()
ACCEPTING_STREAMED_CONTENT_AND_ANALYZING