19 package org.sleuthkit.autopsy.ingest;
21 import java.lang.reflect.InvocationTargetException;
22 import java.util.ArrayList;
23 import java.util.Date;
24 import java.util.HashSet;
25 import java.util.List;
26 import java.util.Optional;
28 import java.util.concurrent.CopyOnWriteArrayList;
29 import java.util.logging.Level;
30 import javax.annotation.concurrent.GuardedBy;
31 import javax.swing.JOptionPane;
32 import javax.swing.SwingUtilities;
33 import org.netbeans.api.progress.ProgressHandle;
34 import org.openide.util.Cancellable;
35 import org.openide.util.NbBundle;
36 import org.openide.util.NbBundle.Messages;
37 import org.openide.windows.WindowManager;
45 import org.
sleuthkit.datamodel.IngestJobInfo.IngestJobStatusType;
47 import org.
sleuthkit.datamodel.IngestModuleInfo.IngestModuleType;
61 final class IngestJobExecutor {
67 PIPELINES_SHUTTING_DOWN
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 {
191 jobState = IngestJobState.PIPELINES_STARTING_UP;
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<>();
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");
328 jobState = IngestJobState.ANALYZING;
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");
413 jobState = IngestJobState.ACCEPTING_STREAMED_CONTENT_AND_ANALYZING;
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) {
503 if (jobState.equals(IngestJobState.ACCEPTING_STREAMED_CONTENT_AND_ANALYZING)) {
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()) {
702 if (jobState.equals(IngestJobState.ACCEPTING_STREAMED_CONTENT_AND_ANALYZING)) {
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()) {
723 if (jobState.equals(IngestJobState.ACCEPTING_STREAMED_CONTENT_AND_ANALYZING) || jobState.equals(IngestJobState.ANALYZING)) {
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();
1098 void switchDataSourceIngestProgressBarToDeterminate(
int workUnitsToDo) {
1099 if (usingNetBeansGUI && !jobCancelled) {
1100 SwingUtilities.invokeLater(() -> {
1101 if (dataSourceIngestProgressBar != null) {
1102 dataSourceIngestProgressBar.switchToDeterminate(workUnitsToDo);
1125 void updateDataSourceIngestProgressBar(String newText,
int workUnitsDone) {
1126 if (usingNetBeansGUI && !jobCancelled) {
1127 SwingUtilities.invokeLater(() -> {
1128 if (dataSourceIngestProgressBar != null) {
1129 dataSourceIngestProgressBar.progress(newText, workUnitsDone);
1141 void updateDataSourceIngestProgressBarText(String newText) {
1142 if (usingNetBeansGUI && !jobCancelled) {
1143 SwingUtilities.invokeLater(() -> {
1144 if (dataSourceIngestProgressBar != null) {
1145 dataSourceIngestProgressBar.progress(newText);
1164 void updateDataSourceIngestProgressBar(
int workUnitsDone) {
1165 if (usingNetBeansGUI && !jobCancelled) {
1166 SwingUtilities.invokeLater(() -> {
1167 if (dataSourceIngestProgressBar != null) {
1168 dataSourceIngestProgressBar.progress(
"", workUnitsDone);
1185 private void startFileIngestProgressBar(
boolean useDeterminateMode) {
1186 if (usingNetBeansGUI) {
1187 SwingUtilities.invokeLater(() -> {
1188 fileIngestProgressBar = ProgressHandle.createHandle(NbBundle.getMessage(getClass(),
"IngestJob.progress.fileIngest.displayName", ingestJob.getDataSource().getName()),
new Cancellable() {
1190 public boolean cancel() {
1192 IngestJobExecutor.this.cancel(IngestJob.CancellationReason.USER_CANCELLED);
1197 if (useDeterminateMode) {
1198 fileIngestProgressBar.start((
int) estimatedFilesToProcess);
1200 fileIngestProgressBar.start();
1211 private void switchFileIngestProgressBarToDeterminate() {
1212 if (usingNetBeansGUI) {
1213 SwingUtilities.invokeLater(() -> {
1214 if (fileIngestProgressBar != null) {
1215 fileIngestProgressBar.switchToDeterminate((
int) estimatedFilesToProcess);
1228 private void updateFileProgressBarForFileTaskStarted(String fileName) {
1229 if (usingNetBeansGUI && !jobCancelled) {
1230 SwingUtilities.invokeLater(() -> {
1242 long processedFilesCapture = processedFiles;
1243 if (processedFilesCapture <= estimatedFilesToProcess) {
1244 fileIngestProgressBar.progress(fileName, (
int) processedFilesCapture);
1246 fileIngestProgressBar.progress(fileName, (
int) estimatedFilesToProcess);
1248 filesInProgress.add(fileName);
1261 private void updateFileProgressBarForFileTaskCompleted(String completedFileName) {
1262 if (usingNetBeansGUI && !jobCancelled) {
1263 SwingUtilities.invokeLater(() -> {
1264 filesInProgress.remove(completedFileName);
1269 if (filesInProgress.size() > 0) {
1270 fileIngestProgressBar.progress(filesInProgress.get(0));
1272 fileIngestProgressBar.progress(
"");
1284 private void startDataArtifactIngestProgressBar() {
1285 if (usingNetBeansGUI) {
1286 SwingUtilities.invokeLater(() -> {
1287 artifactIngestProgressBar = ProgressHandle.createHandle(NbBundle.getMessage(
this.getClass(),
"IngestJob.progress.dataArtifactIngest.displayName", ingestJob.getDataSource().getName()),
new Cancellable() {
1289 public boolean cancel() {
1291 IngestJobExecutor.this.cancel(IngestJob.CancellationReason.USER_CANCELLED);
1296 artifactIngestProgressBar.start();
1297 artifactIngestProgressBar.switchToIndeterminate();
1308 @NbBundle.Messages({
1309 "# {0} - data source name",
1310 "IngestJob_progress_analysisResultIngest_displayName=Analyzing analysis results from {0}"
1312 private void startAnalysisResultIngestProgressBar() {
1313 if (usingNetBeansGUI) {
1314 SwingUtilities.invokeLater(() -> {
1315 resultIngestProgressBar = ProgressHandle.createHandle(Bundle.IngestJob_progress_analysisResultIngest_displayName(ingestJob.getDataSource().getName()),
new Cancellable() {
1317 public boolean cancel() {
1319 IngestJobExecutor.this.cancel(IngestJob.CancellationReason.USER_CANCELLED);
1324 resultIngestProgressBar.start();
1325 resultIngestProgressBar.switchToIndeterminate();
1334 private void displayCancellingProgressMessages() {
1335 if (usingNetBeansGUI) {
1336 SwingUtilities.invokeLater(() -> {
1337 if (dataSourceIngestProgressBar != null) {
1338 dataSourceIngestProgressBar.setDisplayName(NbBundle.getMessage(getClass(),
"IngestJob.progress.dataSourceIngest.initialDisplayName", ingestJob.getDataSource().getName()));
1339 dataSourceIngestProgressBar.progress(NbBundle.getMessage(getClass(),
"IngestJob.progress.cancelling"));
1341 if (fileIngestProgressBar != null) {
1342 fileIngestProgressBar.setDisplayName(NbBundle.getMessage(getClass(),
"IngestJob.progress.fileIngest.displayName", ingestJob.getDataSource().getName()));
1343 fileIngestProgressBar.progress(NbBundle.getMessage(getClass(),
"IngestJob.progress.cancelling"));
1345 if (artifactIngestProgressBar != null) {
1346 artifactIngestProgressBar.setDisplayName(NbBundle.getMessage(getClass(),
"IngestJob.progress.dataArtifactIngest.displayName", ingestJob.getDataSource().getName()));
1347 artifactIngestProgressBar.progress(NbBundle.getMessage(getClass(),
"IngestJob.progress.cancelling"));
1349 if (resultIngestProgressBar != null) {
1350 resultIngestProgressBar.setDisplayName(Bundle.IngestJob_progress_analysisResultIngest_displayName(ingestJob.getDataSource().getName()));
1351 resultIngestProgressBar.progress(NbBundle.getMessage(getClass(),
"IngestJob.progress.cancelling"));
1360 private void finishAllProgressBars() {
1361 if (usingNetBeansGUI) {
1362 SwingUtilities.invokeLater(() -> {
1363 if (dataSourceIngestProgressBar != null) {
1364 dataSourceIngestProgressBar.finish();
1365 dataSourceIngestProgressBar = null;
1368 if (fileIngestProgressBar != null) {
1369 fileIngestProgressBar.finish();
1370 fileIngestProgressBar = null;
1373 if (artifactIngestProgressBar != null) {
1374 artifactIngestProgressBar.finish();
1375 artifactIngestProgressBar = null;
1378 if (resultIngestProgressBar != null) {
1379 resultIngestProgressBar.finish();
1380 resultIngestProgressBar = null;
1392 private void logInfoMessage(String message) {
1393 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()));
1404 private void logErrorMessage(Level level, String message, Throwable throwable) {
1405 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);
1415 private void logErrorMessage(Level level, String message) {
1416 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()));
1424 private void logIngestModuleErrors(List<IngestModuleError> errors) {
1425 for (IngestModuleError error : errors) {
1426 logErrorMessage(Level.SEVERE, String.format(
"%s experienced an error during analysis", error.getModuleDisplayName()), error.getThrowable());
1436 private void logIngestModuleErrors(List<IngestModuleError> errors, AbstractFile file) {
1437 for (IngestModuleError error : errors) {
1438 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());
1447 Optional<List<FileIngestPipeline>> getCurrentFileIngestPipelines() {
1449 int currentModuleTierIndex = moduleTierIndex;
1450 if (currentModuleTierIndex < ingestModuleTiers.size()) {
1451 return Optional.of(ingestModuleTiers.get(currentModuleTierIndex).getFileIngestPipelines());
1453 return Optional.empty();
1461 Optional<DataSourceIngestPipeline> getCurrentDataSourceIngestPipelines() {
1463 int currentModuleTierIndex = moduleTierIndex;
1464 if (currentModuleTierIndex < ingestModuleTiers.size()) {
1465 return ingestModuleTiers.get(currentModuleTierIndex).getDataSourceIngestPipeline();
1467 return Optional.empty();
1481 "IngestJobExecutor_progress_snapshot_currentTier_shutDown_modifier=shut down",
1482 "# {0} - tier number",
1483 "# {1} - job state modifer",
1484 "IngestJobExecutor_progress_snapshot_currentTier=Tier {0} {1}"
1486 IngestJobProgressSnapshot getIngestJobProgressSnapshot(
boolean includeIngestTasksSnapshot) {
1492 boolean fileIngestRunning =
false;
1493 Date fileIngestStartTime = null;
1494 Optional<List<FileIngestPipeline>> fileIngestPipelines = getCurrentFileIngestPipelines();
1495 if (!fileIngestPipelines.isPresent()) {
1497 fileIngestPipelines = Optional.of(ingestModuleTiers.get(0).getFileIngestPipelines());
1499 for (FileIngestPipeline pipeline : fileIngestPipelines.get()) {
1500 if (pipeline.isRunning()) {
1501 fileIngestRunning =
true;
1503 Date pipelineStartTime = pipeline.getStartTime();
1504 if (pipelineStartTime != null && (fileIngestStartTime == null || pipelineStartTime.before(fileIngestStartTime))) {
1505 fileIngestStartTime = pipelineStartTime;
1509 long processedFilesCount = 0;
1510 long estimatedFilesToProcessCount = 0;
1511 long snapShotTime =
new Date().getTime();
1512 IngestTasksScheduler.IngestTasksSnapshot tasksSnapshot = null;
1513 if (includeIngestTasksSnapshot) {
1514 processedFilesCount = processedFiles;
1515 estimatedFilesToProcessCount = estimatedFilesToProcess;
1516 snapShotTime =
new Date().getTime();
1517 tasksSnapshot = taskScheduler.getTasksSnapshotForJob(getIngestJobId());
1519 return new IngestJobProgressSnapshot(
1520 ingestJob.getDataSource().getName(),
1523 Bundle.IngestJobExecutor_progress_snapshot_currentTier(moduleTierIndex, jobState.equals(IngestJobState.PIPELINES_SHUTTING_DOWN) ? Bundle.IngestJobExecutor_progress_snapshot_currentTier_shutDown_modifier() :
""),
1524 getCurrentDataSourceIngestModule(),
1526 fileIngestStartTime,
1529 cancelledDataSourceIngestModules,
1530 processedFilesCount,
1531 estimatedFilesToProcessCount,
1542 void registerPausedIngestThread(Thread thread) {
1543 synchronized (threadRegistrationLock) {
1544 pausedIngestThreads.add(thread);
1554 void unregisterPausedIngestThread(Thread thread) {
1555 synchronized (threadRegistrationLock) {
1556 pausedIngestThreads.remove(thread);
ACCEPTING_STREAMED_CONTENT_AND_ANALYZING
static boolean runningWithGUI
List< IngestModuleTemplate > getEnabledIngestModuleTemplates()
String getExecutionContext()
boolean getProcessUnallocatedSpace()
synchronized static Logger getLogger(String name)