mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-13 00:16:16 +00:00
Modified cvt account cache to be more efficent
This commit is contained in:
parent
692b4604fa
commit
d028db66dd
@ -22,9 +22,13 @@ import com.google.common.cache.CacheBuilder;
|
|||||||
import com.google.common.cache.CacheLoader;
|
import com.google.common.cache.CacheLoader;
|
||||||
import com.google.common.cache.LoadingCache;
|
import com.google.common.cache.LoadingCache;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
@ -36,22 +40,23 @@ import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
|
|||||||
import org.sleuthkit.datamodel.Account;
|
import org.sleuthkit.datamodel.Account;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
|
import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A singleton cache of the Contact artifacts for accounts. This list of
|
* A singleton cache of the Contact artifacts for accounts. The map of account
|
||||||
* TSK_CONTACT artifacts for a given Account retrieved on first access and
|
* unique ids to list of contact artifacts is stored in a LoadingCache which
|
||||||
* evicted from the ache after 10 minutes.
|
* expires after 10 of non-use.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
final class ContactCache {
|
final class ContactCache {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(ContactCache.class.getName());
|
private static final Logger logger = Logger.getLogger(ContactCache.class.getName());
|
||||||
|
|
||||||
private final LoadingCache<Account, List<BlackboardArtifact>> accountMap;
|
|
||||||
|
|
||||||
private static ContactCache instance;
|
private static ContactCache instance;
|
||||||
|
|
||||||
|
private final LoadingCache<String, Map<String, List<BlackboardArtifact>>> accountMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the list of Contacts for the given Account.
|
* Returns the list of Contacts for the given Account.
|
||||||
*
|
*
|
||||||
@ -63,7 +68,7 @@ final class ContactCache {
|
|||||||
* @throws ExecutionException
|
* @throws ExecutionException
|
||||||
*/
|
*/
|
||||||
static synchronized List<BlackboardArtifact> getContacts(Account account) throws ExecutionException {
|
static synchronized List<BlackboardArtifact> getContacts(Account account) throws ExecutionException {
|
||||||
return getInstance().accountMap.get(account);
|
return getInstance().accountMap.get("realMap").get(account.getTypeSpecificID());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -77,18 +82,17 @@ final class ContactCache {
|
|||||||
* Construct a new instance.
|
* Construct a new instance.
|
||||||
*/
|
*/
|
||||||
private ContactCache() {
|
private ContactCache() {
|
||||||
accountMap = CacheBuilder.newBuilder().expireAfterAccess(10, TimeUnit.MINUTES).build(
|
|
||||||
new CacheLoader<Account, List<BlackboardArtifact>>() {
|
|
||||||
@Override
|
|
||||||
public List<BlackboardArtifact> load(Account key) {
|
|
||||||
try {
|
|
||||||
List<BlackboardArtifact> contactList = Case.getCurrentCase().getSleuthkitCase().getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT);
|
|
||||||
return findContactForAccount(contactList, key);
|
|
||||||
|
|
||||||
} catch (TskCoreException ex) {
|
accountMap = CacheBuilder.newBuilder().expireAfterAccess(10, TimeUnit.MINUTES).build(
|
||||||
logger.log(Level.WARNING, String.format("Failed to load contacts for account %d", key.getAccountID()), ex);
|
new CacheLoader<String, Map<String, List<BlackboardArtifact>>>() {
|
||||||
|
@Override
|
||||||
|
public Map<String, List<BlackboardArtifact>> load(String key) {
|
||||||
|
try {
|
||||||
|
return buildMap();
|
||||||
|
} catch (SQLException | TskCoreException ex) {
|
||||||
|
logger.log(Level.WARNING, "Failed to build account to contact map", ex);
|
||||||
}
|
}
|
||||||
return new ArrayList<>();
|
return new HashMap<>(); // Return an empty map if there is an exception to avoid NPE and continual trying.
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -118,22 +122,42 @@ final class ContactCache {
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the map of account IDs to contacts that reference them.
|
||||||
|
*
|
||||||
|
* @return A map of account IDs to contact artifacts.
|
||||||
|
*
|
||||||
|
* @throws TskCoreException
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
private Map<String, List<BlackboardArtifact>> buildMap() throws TskCoreException, SQLException {
|
||||||
|
Map<String, List<BlackboardArtifact>> acctMap = new HashMap<>();
|
||||||
|
List<String> accountIdList = getAccountList();
|
||||||
|
List<BlackboardArtifact> contactList = Case.getCurrentCase().getSleuthkitCase().getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT);
|
||||||
|
|
||||||
|
for(String id: accountIdList) {
|
||||||
|
acctMap.put(id, findContactForAccount(contactList, id));
|
||||||
|
}
|
||||||
|
|
||||||
|
return acctMap;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of TSK_CONTACT artifacts that reference the given account.
|
* Returns a list of TSK_CONTACT artifacts that reference the given account.
|
||||||
*
|
*
|
||||||
* @param allContactList List of existing TSK_CONTACT artifacts.
|
* @param allContactList List of existing TSK_CONTACT artifacts.
|
||||||
* @param account Account reference.
|
* @param account String account unique id.
|
||||||
*
|
*
|
||||||
* @return A list of TSK_CONTACT artifact that reference the given account
|
* @return A list of TSK_CONTACT artifact that reference the given account
|
||||||
* or empty list of none were found.
|
* or empty list of none were found.
|
||||||
*
|
*
|
||||||
* @throws TskCoreException
|
* @throws TskCoreException
|
||||||
*/
|
*/
|
||||||
private List<BlackboardArtifact> findContactForAccount(List<BlackboardArtifact> allContactList, Account account) throws TskCoreException {
|
private List<BlackboardArtifact> findContactForAccount(List<BlackboardArtifact> allContactList, String accountId) throws TskCoreException {
|
||||||
List<BlackboardArtifact> accountContacts = new ArrayList<>();
|
List<BlackboardArtifact> accountContacts = new ArrayList<>();
|
||||||
|
|
||||||
for (BlackboardArtifact contact : allContactList) {
|
for (BlackboardArtifact contact : allContactList) {
|
||||||
if (isAccountInAttributeList(contact.getAttributes(), account)) {
|
if (isAccountRelatedToArtifact(contact, accountId)) {
|
||||||
accountContacts.add(contact);
|
accountContacts.add(contact);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -146,13 +170,14 @@ final class ContactCache {
|
|||||||
* given account.
|
* given account.
|
||||||
*
|
*
|
||||||
* @param contactAttributes List of attributes.
|
* @param contactAttributes List of attributes.
|
||||||
* @param account Account object.
|
* @param account String account uniqueID.
|
||||||
*
|
*
|
||||||
* @return True if one of the attributes in the list reference the account.
|
* @return True if one of the attributes in the list reference the account.
|
||||||
*/
|
*/
|
||||||
private boolean isAccountInAttributeList(List<BlackboardAttribute> contactAttributes, Account account) {
|
private boolean isAccountRelatedToArtifact(BlackboardArtifact artifact, String accountId) throws TskCoreException {
|
||||||
|
List<BlackboardAttribute> contactAttributes = artifact.getAttributes();
|
||||||
for (BlackboardAttribute attribute : contactAttributes) {
|
for (BlackboardAttribute attribute : contactAttributes) {
|
||||||
if (isAccountInAttribute(attribute, account)) {
|
if (isAccountInAttribute(attribute, accountId)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -167,14 +192,35 @@ final class ContactCache {
|
|||||||
*
|
*
|
||||||
* @return True if the attribute references the account.
|
* @return True if the attribute references the account.
|
||||||
*/
|
*/
|
||||||
private boolean isAccountInAttribute(BlackboardAttribute attribute, Account account) {
|
private boolean isAccountInAttribute(BlackboardAttribute attribute, String accountId) {
|
||||||
|
|
||||||
String typeName = attribute.getAttributeType().getTypeName();
|
String typeName = attribute.getAttributeType().getTypeName();
|
||||||
return (typeName.startsWith("TSK_EMAIL")
|
return (typeName.startsWith("TSK_EMAIL")
|
||||||
|| typeName.startsWith("TSK_PHONE")
|
|| typeName.startsWith("TSK_PHONE")
|
||||||
|| typeName.startsWith("TSK_NAME")
|
|| typeName.startsWith("TSK_NAME")
|
||||||
|| typeName.startsWith("TSK_ID"))
|
|| typeName.startsWith("TSK_ID"))
|
||||||
&& attribute.getValueString().equals(account.getTypeSpecificID());
|
&& attribute.getValueString().equals(accountId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a list of all accounts unique IDs from the db.
|
||||||
|
*
|
||||||
|
* @return A list of unique account ids or empty list if no accounts were found.
|
||||||
|
*
|
||||||
|
* @throws TskCoreException
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
private List<String> getAccountList() throws TskCoreException, SQLException {
|
||||||
|
List<String> uniqueIdList = new ArrayList<>();
|
||||||
|
|
||||||
|
CaseDbQuery caseDbQuery = Case.getCurrentCase().getSleuthkitCase().executeQuery("SELECT account_unique_indenifier FROM accounts");
|
||||||
|
ResultSet resultSet = caseDbQuery.getResultSet();
|
||||||
|
|
||||||
|
while(resultSet.next()) {
|
||||||
|
uniqueIdList.add(resultSet.getString(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
return uniqueIdList;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user