19 package org.sleuthkit.autopsy.ingest;
 
   21 import java.util.ArrayList;
 
   22 import java.util.LinkedHashMap;
 
   23 import java.util.List;
 
   25 import java.util.regex.Matcher;
 
   26 import java.util.regex.Pattern;
 
   27 import java.util.stream.Stream;
 
   33 class IngestModuleTierBuilder {
 
   35     private static final String AUTOPSY_MODULE_PREFIX = 
"org.sleuthkit.autopsy";
 
   36     private static final Pattern JYTHON_MODULE_REGEX = Pattern.compile(
"org\\.python\\.proxies\\.(.+?)\\$(.+?)(\\$[0-9]*)?$");
 
   50     static List<IngestModuleTier> buildIngestModuleTiers(IngestJobSettings settings, IngestJobExecutor executor) 
throws InterruptedException {
 
   54         List<IngestModuleTemplate> enabledTemplates = settings.getEnabledIngestModuleTemplates();
 
   62         Map<String, IngestModuleTemplate> javaDataSourceModuleTemplates = 
new LinkedHashMap<>();
 
   63         Map<String, IngestModuleTemplate> jythonDataSourceModuleTemplates = 
new LinkedHashMap<>();
 
   64         Map<String, IngestModuleTemplate> javaFileModuleTemplates = 
new LinkedHashMap<>();
 
   65         Map<String, IngestModuleTemplate> jythonFileModuleTemplates = 
new LinkedHashMap<>();
 
   66         Map<String, IngestModuleTemplate> javaArtifactModuleTemplates = 
new LinkedHashMap<>();
 
   67         Map<String, IngestModuleTemplate> jythonArtifactModuleTemplates = 
new LinkedHashMap<>();
 
   68         Map<String, IngestModuleTemplate> javaResultModuleTemplates = 
new LinkedHashMap<>();
 
   69         Map<String, IngestModuleTemplate> jythonResultModuleTemplates = 
new LinkedHashMap<>();
 
   70         for (IngestModuleTemplate 
template : enabledTemplates) {
 
   71             if (
template.isDataSourceIngestModuleTemplate()) {
 
   72                 addModuleTemplateToSortingMap(javaDataSourceModuleTemplates, jythonDataSourceModuleTemplates, 
template);
 
   74             if (
template.isFileIngestModuleTemplate()) {
 
   75                 addModuleTemplateToSortingMap(javaFileModuleTemplates, jythonFileModuleTemplates, 
template);
 
   77             if (
template.isDataArtifactIngestModuleTemplate()) {
 
   78                 addModuleTemplateToSortingMap(javaArtifactModuleTemplates, jythonArtifactModuleTemplates, 
template);
 
   80             if (
template.isAnalysisResultIngestModuleTemplate()) {
 
   81                 addModuleTemplateToSortingMap(javaResultModuleTemplates, jythonResultModuleTemplates, 
template);
 
   92         IngestPipelinesConfiguration pipelineConfig = IngestPipelinesConfiguration.getInstance();
 
   93         List<IngestModuleTemplate> firstStageDataSourcePipelineTemplate = createIngestPipelineTemplate(javaDataSourceModuleTemplates, jythonDataSourceModuleTemplates, pipelineConfig.getStageOneDataSourceIngestPipelineConfig());
 
   94         List<IngestModuleTemplate> secondStageDataSourcePipelineTemplate = createIngestPipelineTemplate(javaDataSourceModuleTemplates, jythonDataSourceModuleTemplates, pipelineConfig.getStageTwoDataSourceIngestPipelineConfig());
 
   95         List<IngestModuleTemplate> filePipelineTemplate = createIngestPipelineTemplate(javaFileModuleTemplates, jythonFileModuleTemplates, pipelineConfig.getFileIngestPipelineConfig());
 
   96         List<IngestModuleTemplate> artifactPipelineTemplate = 
new ArrayList<>();
 
   97         List<IngestModuleTemplate> resultsPipelineTemplate = 
new ArrayList<>();
 
  107         addToIngestPipelineTemplate(firstStageDataSourcePipelineTemplate, javaDataSourceModuleTemplates, jythonDataSourceModuleTemplates);
 
  108         addToIngestPipelineTemplate(filePipelineTemplate, javaFileModuleTemplates, jythonFileModuleTemplates);
 
  109         addToIngestPipelineTemplate(artifactPipelineTemplate, javaArtifactModuleTemplates, jythonArtifactModuleTemplates);
 
  110         addToIngestPipelineTemplate(resultsPipelineTemplate, javaResultModuleTemplates, jythonResultModuleTemplates);
 
  116         List<IngestModuleTier> moduleTiers = 
new ArrayList<>();
 
  117         IngestModuleTier firstTier = 
new IngestModuleTier();
 
  118         int numberOfFileIngestThreads = IngestManager.getInstance().getNumberOfFileIngestThreads();
 
  119         List<FileIngestPipeline> fileIngestPipelines = 
new ArrayList<>();
 
  120         for (
int i = 0; i < numberOfFileIngestThreads; ++i) {
 
  121             fileIngestPipelines.add(
new FileIngestPipeline(executor, filePipelineTemplate));
 
  123         firstTier.setsFileIngestPipelines(fileIngestPipelines);
 
  124         firstTier.setDataSourceIngestPipeline(
new DataSourceIngestPipeline(executor, firstStageDataSourcePipelineTemplate));
 
  125         firstTier.setDataArtifactIngestPipeline(
new DataArtifactIngestPipeline(executor, artifactPipelineTemplate));
 
  126         firstTier.setAnalysisResultIngestPipeline(
new AnalysisResultIngestPipeline(executor, resultsPipelineTemplate));
 
  127         moduleTiers.add(firstTier);
 
  128         IngestModuleTier secondTier = 
new IngestModuleTier();
 
  129         secondTier.setDataSourceIngestPipeline(
new DataSourceIngestPipeline(executor, secondStageDataSourcePipelineTemplate));
 
  138         moduleTiers.add(secondTier);
 
  152     private static void addModuleTemplateToSortingMap(Map<String, IngestModuleTemplate> mapping, Map<String, IngestModuleTemplate> jythonMapping, IngestModuleTemplate 
template) {
 
  153         String className = 
template.getModuleFactory().getClass().getCanonicalName();
 
  154         String jythonName = getModuleNameFromJythonClassName(className);
 
  155         if (jythonName != null) {
 
  156             jythonMapping.put(jythonName, 
template);
 
  158             mapping.put(className, 
template);
 
  173     private static String getModuleNameFromJythonClassName(String className) {
 
  174         Matcher m = JYTHON_MODULE_REGEX.matcher(className);
 
  176             return String.format(
"%s.%s", m.group(1), m.group(2)); 
 
  197     private static List<IngestModuleTemplate> createIngestPipelineTemplate(Map<String, IngestModuleTemplate> javaIngestModuleTemplates, Map<String, IngestModuleTemplate> jythonIngestModuleTemplates, List<String> pipelineConfig) {
 
  198         List<IngestModuleTemplate> pipelineTemplate = 
new ArrayList<>();
 
  199         for (String moduleClassName : pipelineConfig) {
 
  200             if (javaIngestModuleTemplates.containsKey(moduleClassName)) {
 
  201                 pipelineTemplate.add(javaIngestModuleTemplates.remove(moduleClassName));
 
  202             } 
else if (jythonIngestModuleTemplates.containsKey(moduleClassName)) {
 
  203                 pipelineTemplate.add(jythonIngestModuleTemplates.remove(moduleClassName));
 
  206         return pipelineTemplate;
 
  220     private static void addToIngestPipelineTemplate(
final List<IngestModuleTemplate> sortedModules, 
final Map<String, IngestModuleTemplate> javaModules, 
final Map<String, IngestModuleTemplate> jythonModules) {
 
  221         final List<IngestModuleTemplate> autopsyModules = 
new ArrayList<>();
 
  222         final List<IngestModuleTemplate> thirdPartyModules = 
new ArrayList<>();
 
  223         Stream.concat(javaModules.entrySet().stream(), jythonModules.entrySet().stream()).forEach((templateEntry) -> {
 
  224             if (templateEntry.getKey().startsWith(AUTOPSY_MODULE_PREFIX)) {
 
  225                 autopsyModules.add(templateEntry.getValue());
 
  227                 thirdPartyModules.add(templateEntry.getValue());
 
  230         sortedModules.addAll(autopsyModules);
 
  231         sortedModules.addAll(thirdPartyModules);
 
  237     IngestModuleTierBuilder() {