From ff136f5c3bd7f8e65f3aa03bb901b4527759d93d Mon Sep 17 00:00:00 2001 From: adam-m Date: Fri, 10 Feb 2012 16:11:46 -0500 Subject: [PATCH] - added class ServiceDataEvent - services can notify listeners of new data while they are still processing, and send artifact type, and optionally IDs of all new artifacts (dir tree can refresh more efficiently) - keyword search now sending the new event --- .../autopsy/ingest/IngestImageThread.java | 4 +- .../autopsy/ingest/IngestManager.java | 101 +++++++++--------- .../autopsy/ingest/ServiceDataEvent.java | 71 ++++++++++++ .../KeywordSearchIngestService.java | 9 +- 4 files changed, 130 insertions(+), 55 deletions(-) create mode 100644 Ingest/src/org/sleuthkit/autopsy/ingest/ServiceDataEvent.java diff --git a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestImageThread.java b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestImageThread.java index e43b29aacf..1a87aea757 100644 --- a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestImageThread.java +++ b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestImageThread.java @@ -94,7 +94,7 @@ public class IngestImageThread extends SwingWorker { //notify services of completion if (!this.isCancelled()) { service.complete(); - IngestManager.firePropertyChange(IngestManager.SERVICE_COMPLETED_EVT, service.getName()); + IngestManager.fireServiceEvent(IngestManager.SERVICE_COMPLETED_EVT, service.getName()); } } catch (CancellationException e) { //task was cancelled @@ -117,6 +117,6 @@ public class IngestImageThread extends SwingWorker { private void handleInterruption() { service.stop(); - IngestManager.firePropertyChange(IngestManager.SERVICE_STOPPED_EVT, service.getName()); + IngestManager.fireServiceEvent(IngestManager.SERVICE_STOPPED_EVT, service.getName()); } } diff --git a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestManager.java b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestManager.java index c5e4bad3a5..528c2987f6 100755 --- a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestManager.java +++ b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestManager.java @@ -102,8 +102,12 @@ public class IngestManager { pcs.addPropertyChangeListener(l); } - public static synchronized void firePropertyChange(String property, String serviceName) { - pcs.firePropertyChange(property, serviceName, null); + public static synchronized void fireServiceEvent(String eventType, String serviceName) { + pcs.firePropertyChange(eventType, serviceName, null); + } + + public static synchronized void fireServiceDataEvent(ServiceDataEvent serviceDataEvent) { + pcs.firePropertyChange(SERVICE_HAS_DATA_EVT, serviceDataEvent, null); } /** @@ -112,19 +116,19 @@ public class IngestManager { * @param images images to execute services on */ void execute(final Collection services, final Collection images) { - logger.log(Level.INFO, "Will enqueue number of images: " + images.size() ); + logger.log(Level.INFO, "Will enqueue number of images: " + images.size()); /*if (!initialized) { - //one time initialization of services - - //image services are now initialized per instance - //for (IngestServiceImage s : imageServices) { - // s.init(this); - //} - - for (IngestServiceFsContent s : fsContentServices) { - s.init(this); - } - initialized = true; + //one time initialization of services + + //image services are now initialized per instance + //for (IngestServiceImage s : imageServices) { + // s.init(this); + //} + + for (IngestServiceFsContent s : fsContentServices) { + s.init(this); + } + initialized = true; }*/ tc.enableStartButton(false); @@ -146,7 +150,7 @@ public class IngestManager { void execute(final Collection services, final Image image) { Collection images = new ArrayList(); images.add(image); - logger.log(Level.INFO, "Will enqueue image: " + image.getName() ); + logger.log(Level.INFO, "Will enqueue image: " + image.getName()); execute(services, images); } @@ -162,7 +166,7 @@ public class IngestManager { private synchronized void startAll() { logger.log(Level.INFO, "Image queue: " + this.imageQueue.toString()); logger.log(Level.INFO, "File queue: " + this.fsContentQueue.toString()); - + //image ingesters // cycle through each image in the queue while (hasNextImage()) { @@ -170,38 +174,38 @@ public class IngestManager { // get next image and set of services final QueueUnit qu = this.getNextImage(); - - + + // check if each service for this image is already running //synchronized (this) { - for (IngestServiceImage quService : qu.services) { - boolean alreadyRunning = false; - for (IngestImageThread worker : imageIngesters) { - // ignore threads that are on different images - if (!worker.getImage().equals(qu.content)) { - continue; //check next worker - } - //same image, check service (by name, not id, since different instances) - if (worker.getService().getName().equals(quService.getName())) { - alreadyRunning = true; - logger.log(Level.INFO, "Image Ingester <" + qu.content + ", " + quService.getName() + "> is already running"); - break; - } + for (IngestServiceImage quService : qu.services) { + boolean alreadyRunning = false; + for (IngestImageThread worker : imageIngesters) { + // ignore threads that are on different images + if (!worker.getImage().equals(qu.content)) { + continue; //check next worker } - //checked all workers - if (alreadyRunning == false) { - logger.log(Level.INFO, "Starting new image Ingester <" + qu.content + ", " + quService.getName() + ">"); - IngestImageThread newImageWorker = new IngestImageThread(this, qu.content, quService); - - imageIngesters.add(newImageWorker); - - //image services are now initialized per instance - quService.init(managerProxy); - newImageWorker.execute(); - IngestManager.firePropertyChange(SERVICE_STARTED_EVT, quService.getName()); + //same image, check service (by name, not id, since different instances) + if (worker.getService().getName().equals(quService.getName())) { + alreadyRunning = true; + logger.log(Level.INFO, "Image Ingester <" + qu.content + ", " + quService.getName() + "> is already running"); + break; } } + //checked all workers + if (alreadyRunning == false) { + logger.log(Level.INFO, "Starting new image Ingester <" + qu.content + ", " + quService.getName() + ">"); + IngestImageThread newImageWorker = new IngestImageThread(this, qu.content, quService); + + imageIngesters.add(newImageWorker); + + //image services are now initialized per instance + quService.init(managerProxy); + newImageWorker.execute(); + IngestManager.fireServiceEvent(SERVICE_STARTED_EVT, quService.getName()); + } } + } //} @@ -268,7 +272,7 @@ public class IngestManager { } } - logger.log(Level.INFO, "stopped all"); + logger.log(Level.INFO, "stopped all"); } /** @@ -302,7 +306,7 @@ public class IngestManager { * IngestService should make an attempt not to publish the same message multiple times. * Viewer will attempt to identify duplicate messages and filter them out (slower) */ - synchronized void postMessage(final IngestMessage message) { + synchronized void postMessage(final IngestMessage message) { if (stats != null) { //record the error for stats, if stats are running @@ -750,8 +754,7 @@ public class IngestManager { Integer curServiceErrorI = errors.get(source); if (curServiceErrorI == null) { errors.put(source, 1); - } - else { + } else { errors.put(source, curServiceErrorI + 1); } } @@ -777,7 +780,7 @@ public class IngestManager { @Override public void run() { for (IngestServiceFsContent s : fsContentServices) { - IngestManager.firePropertyChange(SERVICE_STARTED_EVT, s.getName()); + IngestManager.fireServiceEvent(SERVICE_STARTED_EVT, s.getName()); } } }); @@ -835,7 +838,7 @@ public class IngestManager { if (!this.isCancelled()) { for (IngestServiceFsContent s : fsContentServices) { s.complete(); - IngestManager.firePropertyChange(SERVICE_COMPLETED_EVT, s.getName()); + IngestManager.fireServiceEvent(SERVICE_COMPLETED_EVT, s.getName()); } } @@ -868,7 +871,7 @@ public class IngestManager { private void handleInterruption() { for (IngestServiceFsContent s : fsContentServices) { s.stop(); - IngestManager.firePropertyChange(SERVICE_STOPPED_EVT, s.getName()); + IngestManager.fireServiceEvent(SERVICE_STOPPED_EVT, s.getName()); } //empty queues emptyFsContents(); diff --git a/Ingest/src/org/sleuthkit/autopsy/ingest/ServiceDataEvent.java b/Ingest/src/org/sleuthkit/autopsy/ingest/ServiceDataEvent.java new file mode 100644 index 0000000000..d3dd0601c2 --- /dev/null +++ b/Ingest/src/org/sleuthkit/autopsy/ingest/ServiceDataEvent.java @@ -0,0 +1,71 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2011 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.ingest; + +import java.util.Collection; +import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; + +/** + * representation of an event fired off by services when they have posted new data + * of specific type + * additionally, new artifact ids can be provided + */ +public class ServiceDataEvent { + + private String serviceName; + private ARTIFACT_TYPE artifactType; + private Collection artifactIDs; + + public ServiceDataEvent(String serviceName, ARTIFACT_TYPE artifactType) { + this.serviceName = serviceName; + this.artifactType = artifactType; + } + + public ServiceDataEvent(String serviceName, ARTIFACT_TYPE artifactType, Collection artifactIDs) { + this(serviceName, artifactType); + this.artifactIDs = artifactIDs; + } + + /** + * get new artifact IDs associated with the event + * @return Collection of artifact ids or null if not provided + */ + public Collection getArtifactIDs() { + return artifactIDs; + } + + /** + * get artifact type of the new artifacts associated with the event + * @return + */ + public ARTIFACT_TYPE getArtifactType() { + return artifactType; + } + + /** + * get service name that created the artifacts and fired the event + * @return + */ + public String getServiceName() { + return serviceName; + } + + + +} diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestService.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestService.java index af6939f119..cfef1ba748 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestService.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestService.java @@ -18,7 +18,6 @@ */ package org.sleuthkit.autopsy.keywordsearch; -import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.ArrayList; import java.util.Collection; @@ -40,6 +39,7 @@ import org.sleuthkit.autopsy.ingest.IngestManagerProxy; import org.sleuthkit.autopsy.ingest.IngestMessage; import org.sleuthkit.autopsy.ingest.IngestMessage.MessageType; import org.sleuthkit.autopsy.ingest.IngestServiceFsContent; +import org.sleuthkit.autopsy.ingest.ServiceDataEvent; import org.sleuthkit.autopsy.keywordsearch.Ingester.IngesterException; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; @@ -443,12 +443,14 @@ public final class KeywordSearchIngestService implements IngestServiceFsContent managerProxy.postMessage(IngestMessage.createMessage(++messageID, MessageType.INFO, instance, sb.toString())); //write results to BB + Collection newArtifacts = new ArrayList(); //new artifacts to report for (FsContent hitFile : newResults) { Collection attributes = new ArrayList(); if (query.isLiteral()) { BlackboardArtifact bba = null; try { bba = hitFile.newArtifact(ARTIFACT_TYPE.TSK_KEYWORD_HIT); + newArtifacts.add(bba.getArtifactID()); } catch (Exception e) { logger.log(Level.INFO, "Error adding bb artifact for keyword hit", e); continue; @@ -510,6 +512,7 @@ public final class KeywordSearchIngestService implements IngestServiceFsContent BlackboardArtifact bba = null; try { bba = hitFile.newArtifact(ARTIFACT_TYPE.TSK_KEYWORD_HIT); + newArtifacts.add(bba.getArtifactID()); } catch (Exception e) { logger.log(Level.INFO, "Error adding bb artifact for keyword hit", e); continue; @@ -546,9 +549,7 @@ public final class KeywordSearchIngestService implements IngestServiceFsContent } //for each file hit //update artifact browser - //TODO use has data evt - IngestManager.firePropertyChange(IngestManager.SERVICE_STARTED_EVT, MODULE_NAME); - IngestManager.firePropertyChange(IngestManager.SERVICE_HAS_DATA_EVT, MODULE_NAME); + IngestManager.fireServiceDataEvent(new ServiceDataEvent(MODULE_NAME, ARTIFACT_TYPE.TSK_KEYWORD_HIT, newArtifacts)); } progress.progress(queryStr, ++numSearched); }