1
0
mirror of https://github.com/elisspace/autopsy.git synced 2026-09-06 02:24:30 +00:00

Merge pull request #1197 from esaunders/remote_solr

Remote solr
This commit is contained in:
Richard Cordovano
2015-04-16 10:02:23 -04:00
11 changed files with 450 additions and 283 deletions

View File

@@ -141,20 +141,20 @@ public class Case implements SleuthkitCase.ErrorObserver {
SINGLE_USER_CASE("Single-user case"),
MULTI_USER_CASE("Multi-user case");
private final String caseName;
private final String caseType;
private CaseType(String s) {
caseName = s;
caseType = s;
}
public boolean equalsName(String otherName) {
return (otherName == null) ? false : caseName.equals(otherName);
public boolean equalsName(String otherType) {
return (otherType == null) ? false : caseType.equals(otherType);
}
public static CaseType fromString(String text) {
if (text != null) {
public static CaseType fromString(String typeName) {
if (typeName != null) {
for (CaseType c : CaseType.values()) {
if (text.equalsIgnoreCase(c.caseName)) {
if (typeName.equalsIgnoreCase(c.caseType)) {
return c;
}
}
@@ -164,7 +164,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
@Override
public String toString() {
return caseName;
return caseType;
}
};
@@ -176,6 +176,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
private final SleuthkitCase db;
// Track the current case (only set with changeCase() method)
private static Case currentCase = null;
private CaseType caseType;
private final Services services;
private static final Logger logger = Logger.getLogger(Case.class.getName());
static final String CASE_EXTENSION = "aut"; //NON-NLS
@@ -189,12 +190,13 @@ public class Case implements SleuthkitCase.ErrorObserver {
/**
* Constructor for the Case class
*/
private Case(String name, String number, String examiner, String configFilePath, XMLCaseManagement xmlcm, SleuthkitCase db) {
private Case(String name, String number, String examiner, String configFilePath, XMLCaseManagement xmlcm, SleuthkitCase db, CaseType type) {
this.name = name;
this.number = number;
this.examiner = examiner;
this.configFilePath = configFilePath;
this.xmlcm = xmlcm;
this.caseType = type;
this.db = db;
this.services = new Services(db);
// messenger = new Messenger(this.name);
@@ -344,16 +346,20 @@ public class Case implements SleuthkitCase.ErrorObserver {
XMLCaseManagement xmlcm = new XMLCaseManagement();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmmss");
Date date = new Date();
String indexName = caseName + "_" + dateFormat.format(date);
String dbName = null;
// figure out the database name
// figure out the database name and index name for text extraction
if (caseType == CaseType.SINGLE_USER_CASE) {
dbName = caseDir + File.separator + "autopsy.db"; //NON-NLS
} else if (caseType == CaseType.MULTI_USER_CASE) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmmss");
dbName = caseName + "_" + dateFormat.format(new Date());
dbName = caseName + "_" + dateFormat.format(date);
}
xmlcm.create(caseDir, caseName, examiner, caseNumber, caseType, dbName); // create a new XML config file
xmlcm.create(caseDir, caseName, examiner, caseNumber, caseType, dbName, indexName); // create a new XML config file
xmlcm.writeFile();
SleuthkitCase db = null;
@@ -373,7 +379,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
* Two-stage initialization to avoid leaking reference to "this" in
* constructor.
*/
Case newCase = new Case(caseName, caseNumber, examiner, configFilePath, xmlcm, db);
Case newCase = new Case(caseName, caseNumber, examiner, configFilePath, xmlcm, db, caseType);
newCase.init();
// newCase.messenger.start();
@@ -403,7 +409,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
SleuthkitCase db;
if (caseType == CaseType.SINGLE_USER_CASE) {
// if the caseName is "", case / config file can't be opened
// if the caseType is "", case / config file can't be opened
if (caseName.equals("")) {
throw new CaseActionException(NbBundle.getMessage(Case.class, "Case.open.exception.blankCase.msg"));
}
@@ -434,7 +440,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
* Two-stage initialization to avoid leaking reference to "this" in
* constructor.
*/
Case openedCase = new Case(caseName, caseNumber, examiner, configFilePath, xmlcm, db);
Case openedCase = new Case(caseName, caseNumber, examiner, configFilePath, xmlcm, db, caseType);
openedCase.init();
// openedCase.messenger.start();
@@ -789,6 +795,14 @@ public class Case implements SleuthkitCase.ErrorObserver {
}
}
/**
* Get the case type.
* @return
*/
public CaseType getCaseType() {
return this.caseType;
}
/**
* Gets the full path to the temp directory of this case
*
@@ -854,6 +868,19 @@ public class Case implements SleuthkitCase.ErrorObserver {
}
}
/**
* Get the name of the index where extracted text is stored for the case.
*
* @return Index name.
*/
public String getTextIndexName() {
if (xmlcm == null) {
return "";
} else {
return xmlcm.getTextIndexName();
}
}
/**
* Get absolute module output directory path where modules should save their
* permanent data The directory is a subdirectory of this case dir.

View File

@@ -16,6 +16,8 @@
<xs:element name="DatabaseName" type="String" nillable="false"/>
<xs:element name="TextIndexName" type="String" nillable="true"/>
<xs:attribute name="Relative" type="xs:boolean"/>
<xs:element name="CreatedDate" >
@@ -99,6 +101,7 @@
<xs:sequence minOccurs="0" maxOccurs="1">
<xs:element ref="CaseType"/>
<xs:element ref="DatabaseName"/>
<xs:element ref="TextIndexName"/>
</xs:sequence>
</xs:sequence>
</xs:complexType>

View File

@@ -60,6 +60,7 @@ import org.xml.sax.SAXException;
final static String SCHEMA_VERSION_NAME = "SchemaVersion"; //NON-NLS
final static String AUTOPSY_CRVERSION_NAME = "AutopsyCreatedVersion"; //NON-NLS
final static String AUTOPSY_MVERSION_NAME = "AutopsySavedVersion"; //NON-NLS
final static String CASE_TEXT_INDEX_NAME = "TextIndexName"; //NON-NLS
// folders inside case directory
final static String LOG_FOLDER_NAME = "LogFolder"; //NON-NLS
final static String LOG_FOLDER_RELPATH = "Log"; //NON-NLS
@@ -88,6 +89,7 @@ import org.xml.sax.SAXException;
private String autopsySavedVersion;
private CaseType caseType; // The type of case: local or shared
private String dbName; // The name of the database
private String textIndexName; // The name of the index where extracted text is stored.
// for error handling
private JPanel caller;
@@ -247,6 +249,34 @@ import org.xml.sax.SAXException;
}
/**
* Sets the text index name internally (on local variable in this class)
*
* @param textIndexName the new name for the index where extracted text
* is stored for the case.
*/
private void setTextIndexName(String textIndexName) {
this.textIndexName= textIndexName; // change this to change the xml file if needed
}
/**
* Gets the name of the index where extracted text is stored.
*
* @return the index name
*/
public String getTextIndexName() {
if (doc == null) {
return "";
} else {
if (getCaseElement().getElementsByTagName(CASE_TEXT_INDEX_NAME).getLength() > 0) {
Element nameElement = (Element) getCaseElement().getElementsByTagName(CASE_TEXT_INDEX_NAME).item(0);
return nameElement.getTextContent();
} else {
return ""; /// couldn't find one, so return a blank index name
}
}
}
/**
* Sets the examiner name internally (on local variable in this class)
*
* @param givenExaminer the new examiner
@@ -503,8 +533,9 @@ import org.xml.sax.SAXException;
* @param caseNumber case number (optional), can be empty
* @param dbName the name of the database. Could be a local path, could be
* a Postgre db name.
* @param textIndexName The name of the index where extracted text is stored.
*/
protected void create(String dirPath, String caseName, String examiner, String caseNumber, CaseType caseType, String dbName) throws CaseActionException {
protected void create(String dirPath, String caseName, String examiner, String caseNumber, CaseType caseType, String dbName, String textIndexName) throws CaseActionException {
clear(); // clear the previous data
// set the case Name and Directory and the parent directory
@@ -514,6 +545,7 @@ import org.xml.sax.SAXException;
setNumber(caseNumber);
setCaseType(caseType);
setDatabaseName(dbName);
setTextIndexName(textIndexName);
DocumentBuilder docBuilder;
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
@@ -593,6 +625,10 @@ import org.xml.sax.SAXException;
dbNameElement.appendChild(doc.createTextNode(dbName));
caseElement.appendChild(dbNameElement);
Element indexNameElement = doc.createElement(CASE_TEXT_INDEX_NAME); // <TextIndexName> ... </TextIndexName>
indexNameElement.appendChild(doc.createTextNode(textIndexName));
caseElement.appendChild(indexNameElement);
// write more code if needed ...
}
@@ -761,5 +797,6 @@ import org.xml.sax.SAXException;
examiner = "";
caseType = CaseType.SINGLE_USER_CASE;
dbName = "";
textIndexName = "";
}
}

View File

@@ -45,6 +45,8 @@ public final class UserPreferences {
public static final String EXTERNAL_DATABASE_PASSWORD = "ExternalDatabasePassword"; //NON-NLS
public static final String EXTERNAL_DATABASE_TYPE = "ExternalDatabaseType"; //NON-NLS
public static final String NEW_CASE_TYPE = "NewCaseType"; //NON-NLS
public static final String INDEXING_SERVER_HOST = "IndexingServerHost"; //NON-NLS
public static final String INDEXING_SERVER_PORT = "IndexingServerPort"; //NON-NLS
private static final String MESSAGE_SERVICE_PASSWORD = "MessageServicePassword"; //NON-NLS
private static final String MESSAGE_SERVICE_USER = "MessageServiceUser"; //NON-NLS
private static final String MESSAGE_SERVICE_HOST = "MessageServiceHost"; //NON-NLS
@@ -132,6 +134,22 @@ public final class UserPreferences {
public static void setNewCaseType(int value) {
preferences.putInt(NEW_CASE_TYPE, value);
}
public static String getIndexingServerHost() {
return preferences.get(INDEXING_SERVER_HOST, "");
}
public static void setIndexingServerHost(String hostName) {
preferences.put(INDEXING_SERVER_HOST, hostName);
}
public static String getIndexingServerPort() {
return preferences.get(INDEXING_SERVER_PORT, "");
}
public static void setIndexingServerPort(int port) {
preferences.putInt(INDEXING_SERVER_PORT, port);
}
/**
* Persists message service connection info.

View File

@@ -165,6 +165,7 @@ MultiUserSettingsPanel.lbDatabaseSettings.text=Database Settings
MultiUserSettingsPanel.validationErrMsg.incomplete=Fill in all values
MultiUserSettingsPanel.validationErrMsg.invalidDatabasePort=Invalid database port number
MultiUserSettingsPanel.validationErrMsg.invalidMessageServicePort=Invalid message service port number
MultiUserSettingsPanel.validationErrMsg.invalidIndexingServerPort=Invalid Solr server port number
MultiUserSettingsPanel.validationErrMsg.invalidMessgeServiceURI=Message service host and/or port not valid
MultiUserSettingsPanel.msgHostTextField.text=
MultiUserSettingsPanel.msgHostTextField.toolTipText=Hostname or IP Address
@@ -174,3 +175,7 @@ MultiUserSettingsPanel.msgPasswordField.toolTipText=Password
MultiUserSettingsPanel.msgPasswordField.text=
MultiUserSettingsPanel.msgPortTextField.toolTipText=Hostname or IP Address
MultiUserSettingsPanel.msgPortTextField.text=
MultiUserSettingsPanel.tbIndexingServerHost.text=localhost
MultiUserSettingsPanel.tbIndexingServerPort.text=23232
MultiUserSettingsPanel.tbIndexingServerHost.toolTipText=Hostname or IP Address
MultiUserSettingsPanel.tbIndexingServerPort.toolTipText=Port Number

View File

@@ -16,7 +16,7 @@
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="pnOverallPanel" pref="511" max="32767" attributes="0"/>
<Component id="pnOverallPanel" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
@@ -55,7 +55,7 @@
<Component id="cbEnableMultiUser" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="lbOops" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace pref="6" max="32767" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="pnDatabaseSettings" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="pnSolrSettings" min="-2" max="-2" attributes="0"/>
@@ -126,6 +126,9 @@
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="MultiUserSettingsPanel.tbHostnameOrIp.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="tbHostnameOrIpActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JTextField" name="tbPortNumber">
<Properties>
@@ -191,10 +194,17 @@
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="lbSolrSettings" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
<Component id="tbIndexingServerHost" alignment="1" max="32767" attributes="0"/>
<Component id="tbIndexingServerPort" alignment="1" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="lbSolrSettings" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@@ -203,7 +213,11 @@
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="lbSolrSettings" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="75" max="32767" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="tbIndexingServerHost" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="tbIndexingServerPort" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="45" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@@ -219,6 +233,38 @@
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="tbIndexingServerHost">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Tahoma" size="12" style="0"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="MultiUserSettingsPanel.tbIndexingServerHost.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="MultiUserSettingsPanel.tbIndexingServerHost.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="tbIndexingServerHostActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JTextField" name="tbIndexingServerPort">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Tahoma" size="12" style="0"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="MultiUserSettingsPanel.tbIndexingServerPort.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="MultiUserSettingsPanel.tbIndexingServerPort.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="tbIndexingServerPortActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JLabel" name="lbOops">

View File

@@ -27,6 +27,7 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
private static final String INCOMPLETE_SETTINGS_MSG = NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.validationErrMsg.incomplete");
private static final String INVALID_DB_PORT_MSG = NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.validationErrMsg.invalidDatabasePort");
private static final String INVALID_MESSAGE_SERVICE_PORT_MSG = NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.validationErrMsg.invalidMessageServicePort");
private static final String INVALID_INDEXING_SERVER_PORT_MSG = NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.validationErrMsg.invalidIndexingServerPort");
private final MultiUserSettingsPanelController controller;
private final Collection<JTextField> textBoxes = new ArrayList<>();
private final TextBoxChangedListener textBoxChangedListener;
@@ -51,6 +52,8 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
textPrompts.add(new TextPrompt(PORT_PROMPT, msgPortTextField));
textPrompts.add(new TextPrompt(USER_NAME_PROMPT, msgUserNameTextField));
textPrompts.add(new TextPrompt(PASSWORD_PROMPT, msgPasswordField));
textPrompts.add(new TextPrompt(HOST_NAME_OR_IP_PROMPT, tbIndexingServerHost));
textPrompts.add(new TextPrompt(PORT_PROMPT, tbIndexingServerPort));
configureTextPrompts(textPrompts);
/// Register for notifications when the text boxes get updated.
@@ -63,6 +66,8 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
textBoxes.add(msgPortTextField);
textBoxes.add(msgUserNameTextField);
textBoxes.add(msgPasswordField);
textBoxes.add(tbIndexingServerHost);
textBoxes.add(tbIndexingServerPort);
addDocumentListeners(textBoxes, textBoxChangedListener);
enableMultiUserComponents(textBoxes, cbEnableMultiUser.isSelected());
@@ -112,6 +117,8 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
lbDatabaseSettings = new javax.swing.JLabel();
pnSolrSettings = new javax.swing.JPanel();
lbSolrSettings = new javax.swing.JLabel();
tbIndexingServerHost = new javax.swing.JTextField();
tbIndexingServerPort = new javax.swing.JTextField();
lbOops = new javax.swing.JLabel();
pnMessagingSettings = new javax.swing.JPanel();
lbMessagingSettings = new javax.swing.JLabel();
@@ -126,6 +133,11 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
tbHostnameOrIp.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
tbHostnameOrIp.setText(org.openide.util.NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.tbHostnameOrIp.text")); // NOI18N
tbHostnameOrIp.setToolTipText(org.openide.util.NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.tbHostnameOrIp.toolTipText")); // NOI18N
tbHostnameOrIp.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
tbHostnameOrIpActionPerformed(evt);
}
});
tbPortNumber.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
tbPortNumber.setText(org.openide.util.NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.tbPortNumber.text")); // NOI18N
@@ -180,21 +192,48 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
lbSolrSettings.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbSolrSettings, org.openide.util.NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.lbSolrSettings.text")); // NOI18N
tbIndexingServerHost.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
tbIndexingServerHost.setText(org.openide.util.NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.tbIndexingServerHost.text")); // NOI18N
tbIndexingServerHost.setToolTipText(org.openide.util.NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.tbIndexingServerHost.toolTipText")); // NOI18N
tbIndexingServerHost.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
tbIndexingServerHostActionPerformed(evt);
}
});
tbIndexingServerPort.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
tbIndexingServerPort.setText(org.openide.util.NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.tbIndexingServerPort.text")); // NOI18N
tbIndexingServerPort.setToolTipText(org.openide.util.NbBundle.getMessage(MultiUserSettingsPanel.class, "MultiUserSettingsPanel.tbIndexingServerPort.toolTipText")); // NOI18N
tbIndexingServerPort.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
tbIndexingServerPortActionPerformed(evt);
}
});
javax.swing.GroupLayout pnSolrSettingsLayout = new javax.swing.GroupLayout(pnSolrSettings);
pnSolrSettings.setLayout(pnSolrSettingsLayout);
pnSolrSettingsLayout.setHorizontalGroup(
pnSolrSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnSolrSettingsLayout.createSequentialGroup()
.addContainerGap()
.addComponent(lbSolrSettings)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addGroup(pnSolrSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnSolrSettingsLayout.createSequentialGroup()
.addComponent(lbSolrSettings)
.addGap(0, 0, Short.MAX_VALUE))
.addComponent(tbIndexingServerHost, javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(tbIndexingServerPort, javax.swing.GroupLayout.Alignment.TRAILING))
.addContainerGap())
);
pnSolrSettingsLayout.setVerticalGroup(
pnSolrSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnSolrSettingsLayout.createSequentialGroup()
.addContainerGap()
.addComponent(lbSolrSettings)
.addContainerGap(75, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(tbIndexingServerHost, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(tbIndexingServerPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(45, 45, 45))
);
lbOops.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N
@@ -285,7 +324,7 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
.addGroup(pnOverallPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(cbEnableMultiUser)
.addComponent(lbOops))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 6, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(pnDatabaseSettings, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(pnSolrSettings, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
@@ -298,7 +337,7 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(pnOverallPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 511, Short.MAX_VALUE)
.addComponent(pnOverallPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@@ -325,6 +364,18 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
controller.changed();
}//GEN-LAST:event_cbEnableMultiUserItemStateChanged
private void tbHostnameOrIpActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_tbHostnameOrIpActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_tbHostnameOrIpActionPerformed
private void tbIndexingServerHostActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_tbIndexingServerHostActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_tbIndexingServerHostActionPerformed
private void tbIndexingServerPortActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_tbIndexingServerPortActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_tbIndexingServerPortActionPerformed
void load() {
CaseDbConnectionInfo dbInfo = UserPreferences.getDatabaseConnectionInfo();
tbHostnameOrIp.setText(dbInfo.getHost());
@@ -338,6 +389,15 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
msgUserNameTextField.setText(msgServiceInfo.getUserName());
msgPasswordField.setText(msgServiceInfo.getPassword());
String indexingServerHost = UserPreferences.getIndexingServerHost();
if (!indexingServerHost.isEmpty()) {
tbIndexingServerHost.setText(indexingServerHost);
}
String indexingServerPort = UserPreferences.getIndexingServerPort();
if (portNumberIsValid(indexingServerPort)) {
tbIndexingServerPort.setText(indexingServerPort);
}
if (dbInfo.getDbType() == DbType.UNKNOWN) {
cbEnableMultiUser.setSelected(false);
} else {
@@ -381,6 +441,10 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
msgHostTextField.getText(),
msgPortTextField.getText());
UserPreferences.setMessageServiceConnectionInfo(msgServiceInfo);
UserPreferences.setIndexingServerHost(tbIndexingServerHost.getText());
UserPreferences.setIndexingServerPort(Integer.parseInt(tbIndexingServerPort.getText()));
}
/**
@@ -391,7 +455,7 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
boolean valid() {
lbOops.setText("");
if (cbEnableMultiUser.isSelected()) {
return settingsAreComplete() && databaseSettingsAreValid() && messageServiceSettingsAreValid();
return settingsAreComplete() && databaseSettingsAreValid() && indexingServerSettingsAreValid() && messageServiceSettingsAreValid();
} else {
return true;
}
@@ -444,6 +508,20 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
return true;
}
/**
* Tests whether or not the indexing server settings are valid.
*
* @return True or false.
*/
boolean indexingServerSettingsAreValid() {
if (!portNumberIsValid(tbIndexingServerPort.getText())) {
lbOops.setText(INVALID_INDEXING_SERVER_PORT_MSG);
return false;
}
return true;
}
/**
* Determines whether or not a port number is within the range of valid port
* numbers.
@@ -478,6 +556,8 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
private javax.swing.JPanel pnOverallPanel;
private javax.swing.JPanel pnSolrSettings;
private javax.swing.JTextField tbHostnameOrIp;
private javax.swing.JTextField tbIndexingServerHost;
private javax.swing.JTextField tbIndexingServerPort;
private javax.swing.JPasswordField tbPassword;
private javax.swing.JTextField tbPortNumber;
private javax.swing.JTextField tbUsername;
@@ -503,6 +583,6 @@ public final class MultiUserSettingsPanel extends javax.swing.JPanel {
public void removeUpdate(DocumentEvent e) {
controller.changed();
}
}
}
}

View File

@@ -169,58 +169,14 @@
<runtime-relative-path>ext/bcmail-jdk15-1.45.jar</runtime-relative-path>
<binary-origin>release/modules/ext/bcmail-jdk15-1.45.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/bcprov-jdk15-1.45.jar</runtime-relative-path>
<binary-origin>release/modules/ext/bcprov-jdk15-1.45.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/commons-logging-api-1.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-logging-api-1.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/commons-logging-1.1.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-logging-1.1.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/commons-compress-1.5.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-compress-1.5.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/commons-lang-2.4.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-lang-2.4.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/commons-lang-2.4-javadoc.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-lang-2.4-javadoc.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/commons-lang-2.4-sources.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-lang-2.4-sources.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/tika-parsers-1.5.jar</runtime-relative-path>
<binary-origin>release/modules/ext/tika-parsers-1.5.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/tika-core-1.5.jar</runtime-relative-path>
<binary-origin>release/modules/ext/tika-core-1.5.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/metadata-extractor-2.7.2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/metadata-extractor-2.7.2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/xmpcore-5.1.2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/xmpcore-5.1.2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jericho-html-3.3.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jericho-html-3.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jericho-html-3.3-sources.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jericho-html-3.3-sources.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/org.osgi.compendium-4.0.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/org.osgi.compendium-4.0.0.jar</binary-origin>
@@ -234,33 +190,57 @@
<binary-origin>release/modules/ext/xmlbeans-2.3.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/asm-all-3.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/asm-all-3.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/poi-3.10-beta2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/poi-3.10-beta2.jar</binary-origin>
<runtime-relative-path>ext/jempbox-1.8.4.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jempbox-1.8.4.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/poi-ooxml-3.10-beta2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/poi-ooxml-3.10-beta2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/poi-ooxml-schemas-3.10-beta2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/poi-ooxml-schemas-3.10-beta2.jar</binary-origin>
<runtime-relative-path>ext/commons-logging-api-1.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-logging-api-1.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/poi-scratchpad-3.10-beta2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/poi-scratchpad-3.10-beta2.jar</binary-origin>
<runtime-relative-path>ext/asm-all-3.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/asm-all-3.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/solr-solrj-4.9.1-javadoc.jar</runtime-relative-path>
<binary-origin>release/modules/ext/solr-solrj-4.9.1-javadoc.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/poi-3.10-beta2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/poi-3.10-beta2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/icu4j-3.8.jar</runtime-relative-path>
<binary-origin>release/modules/ext/icu4j-3.8.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/fontbox-1.8.4.jar</runtime-relative-path>
<binary-origin>release/modules/ext/fontbox-1.8.4.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/xmpcore-5.1.2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/xmpcore-5.1.2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/metadata-extractor-2.7.2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/metadata-extractor-2.7.2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/tagsoup-1.2.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/tagsoup-1.2.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/commons-compress-1.5.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-compress-1.5.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/commons-lang-2.4-javadoc.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-lang-2.4-javadoc.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/org.osgi.core-4.0.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/org.osgi.core-4.0.0.jar</binary-origin>
@@ -269,14 +249,6 @@
<runtime-relative-path>ext/httpclient-4.3.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/httpclient-4.3.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/httpcore-4.3.jar</runtime-relative-path>
<binary-origin>release/modules/ext/httpcore-4.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/httpmime-4.3.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/httpmime-4.3.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/isoparser-1.0-RC-1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/isoparser-1.0-RC-1.jar</binary-origin>
@@ -285,6 +257,14 @@
<runtime-relative-path>ext/log4j-1.2.17.jar</runtime-relative-path>
<binary-origin>release/modules/ext/log4j-1.2.17.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/commons-lang-2.4-sources.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-lang-2.4-sources.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/tika-core-1.5.jar</runtime-relative-path>
<binary-origin>release/modules/ext/tika-core-1.5.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jericho-html-3.3-javadoc.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jericho-html-3.3-javadoc.jar</binary-origin>
@@ -302,12 +282,12 @@
<binary-origin>release/modules/ext/solr-solrj-4.9.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/solr-solrj-4.9.1-javadoc.jar</runtime-relative-path>
<binary-origin>release/modules/ext/solr-solrj-4.9.1-javadoc.jar</binary-origin>
<runtime-relative-path>ext/poi-scratchpad-3.10-beta2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/poi-scratchpad-3.10-beta2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/solr-solrj-4.9.1-sources.jar</runtime-relative-path>
<binary-origin>release/modules/ext/solr-solrj-4.9.1-sources.jar</binary-origin>
<runtime-relative-path>ext/commons-logging-1.1.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-logging-1.1.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/netcdf-4.2-min.jar</runtime-relative-path>
@@ -317,6 +297,18 @@
<runtime-relative-path>ext/vorbis-java-core-0.1-tests.jar</runtime-relative-path>
<binary-origin>release/modules/ext/vorbis-java-core-0.1-tests.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/commons-io-2.3.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-io-2.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jericho-html-3.3-sources.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jericho-html-3.3-sources.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/solr-solrj-4.9.1-sources.jar</runtime-relative-path>
<binary-origin>release/modules/ext/solr-solrj-4.9.1-sources.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/juniversalchardet-1.0.3.jar</runtime-relative-path>
<binary-origin>release/modules/ext/juniversalchardet-1.0.3.jar</binary-origin>
@@ -333,10 +325,22 @@
<runtime-relative-path>ext/apache-mime4j-core-0.7.2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/apache-mime4j-core-0.7.2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/httpmime-4.3.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/httpmime-4.3.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/qdox-1.12.jar</runtime-relative-path>
<binary-origin>release/modules/ext/qdox-1.12.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/httpcore-4.3.jar</runtime-relative-path>
<binary-origin>release/modules/ext/httpcore-4.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/commons-lang-2.4.jar</runtime-relative-path>
<binary-origin>release/modules/ext/commons-lang-2.4.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/rome-0.9.jar</runtime-relative-path>
<binary-origin>release/modules/ext/rome-0.9.jar</binary-origin>
@@ -353,18 +357,14 @@
<runtime-relative-path>ext/jdom-1.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jdom-1.0.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/poi-ooxml-schemas-3.10-beta2.jar</runtime-relative-path>
<binary-origin>release/modules/ext/poi-ooxml-schemas-3.10-beta2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/pdfbox-1.8.4.jar</runtime-relative-path>
<binary-origin>release/modules/ext/pdfbox-1.8.4.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/fontbox-1.8.4.jar</runtime-relative-path>
<binary-origin>release/modules/ext/fontbox-1.8.4.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/jempbox-1.8.4.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jempbox-1.8.4.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/wstx-asl-3.2.7.jar</runtime-relative-path>
<binary-origin>release/modules/ext/wstx-asl-3.2.7.jar</binary-origin>
@@ -377,6 +377,10 @@
<runtime-relative-path>ext/dom4j-1.6.1.jar</runtime-relative-path>
<binary-origin>release/modules/ext/dom4j-1.6.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/bcprov-jdk15-1.45.jar</runtime-relative-path>
<binary-origin>release/modules/ext/bcprov-jdk15-1.45.jar</binary-origin>
</class-path-extension>
</data>
</configuration>
</project>

View File

@@ -17,17 +17,29 @@
-->
<!--
All (relative) paths are relative to the installation path
persistent: Save changes made via the API to this file
sharedLib: path to a lib directory that will be shared across all cores
-->
<solr persistent="false">
This is an example of a simple "solr.xml" file for configuring one or
more Solr Cores, as well as allowing Cores to be added, removed, and
reloaded via HTTP requests.
More information about options available in this configuration file,
and Solr Core administration can be found online:
http://wiki.apache.org/solr/CoreAdmin
-->
<solr>
<solrcloud>
<str name="host">${host:}</str>
<int name="hostPort">${jetty.port:8983}</int>
<str name="hostContext">${hostContext:solr}</str>
<int name="zkClientTimeout">${zkClientTimeout:30000}</int>
<bool name="genericCoreNodeNames">${genericCoreNodeNames:true}</bool>
</solrcloud>
<shardHandlerFactory name="shardHandlerFactory"
class="HttpShardHandlerFactory">
<int name="socketTimeout">${socketTimeout:0}</int>
<int name="connTimeout">${connTimeout:0}</int>
</shardHandlerFactory>
<!--
adminPath: RequestHandler path to manage cores.
If 'null' (or absent), cores will not be manageable via request handler
-->
<cores adminPath="/admin/cores" shareSchema="true">
</cores>
</solr>

View File

@@ -38,7 +38,6 @@ import org.sleuthkit.autopsy.coreutils.Version;
class Installer extends ModuleInstall {
private static final Logger logger = Logger.getLogger(Installer.class.getName());
private final static int SERVER_START_RETRIES = 5;
@Override
public void restored() {
@@ -48,138 +47,19 @@ class Installer extends ModuleInstall {
Case.addPropertyChangeListener(new KeywordSearch.CaseChangeListener());
final Server server = KeywordSearch.getServer();
int retries = SERVER_START_RETRIES;
//TODO revise this logic, handle other server types, move some logic to Server class
try {
//check if running from previous application instance and try to shut down
logger.log(Level.INFO, "Checking if server is running"); //NON-NLS
if (server.isRunning()) {
//TODO this could hang if other type of server is running
logger.log(Level.WARNING, "Already a server running on " + server.getCurrentSolrServerPort() //NON-NLS
+ " port, maybe leftover from a previous run. Trying to shut it down."); //NON-NLS
//stop gracefully
server.stop();
logger.log(Level.INFO, "Re-checking if server is running"); //NON-NLS
if (server.isRunning()) {
int serverPort = server.getCurrentSolrServerPort();
int serverStopPort = server.getCurrentSolrStopPort();
logger.log(Level.SEVERE, "There's already a server running on " //NON-NLS
+ serverPort + " port that can't be shutdown."); //NON-NLS
if (!Server.isPortAvailable(serverPort)) {
reportPortError(serverPort);
} else if (!Server.isPortAvailable(serverStopPort)) {
reportStopPortError(serverStopPort);
} else {
//some other reason
reportInitError();
}
//in this case give up
} else {
logger.log(Level.INFO, "Old Solr server shutdown successfully."); //NON-NLS
//make sure there really isn't a hang Solr process, in case isRunning() reported false
server.killSolr();
}
}
} catch (KeywordSearchModuleException e) {
logger.log(Level.SEVERE, "Starting server failed, will try to kill. ", e); //NON-NLS
server.killSolr();
server.start();
} catch (SolrServerNoPortException ex) {
logger.log(Level.SEVERE, "Failed to start Keyword Search server: ", ex); //NON-NLS
if (ex.getPortNumber() == server.getCurrentSolrServerPort())
reportPortError(ex.getPortNumber());
else
reportStopPortError(ex.getPortNumber());
}
try {
//Ensure no other process is still bound to that port, even if we think solr is not running
//Try to bind to the port 4 times at 1 second intervals.
//TODO move some of this logic to Server class
for (int i = 0; i <= 3; i++) {
logger.log(Level.INFO, "Checking if port available."); //NON-NLS
if (Server.isPortAvailable(server.getCurrentSolrServerPort())) {
logger.log(Level.INFO, "Port available, trying to start server."); //NON-NLS
server.start();
break;
} else if (i == 3) {
logger.log(Level.INFO, "No port available, done retrying."); //NON-NLS
reportPortError(server.getCurrentSolrServerPort());
retries = 0;
break;
} else {
try {
Thread.sleep(1000);
} catch (InterruptedException iex) {
logger.log(Level.WARNING, "Timer interrupted"); //NON-NLS
}
}
}
} catch (SolrServerNoPortException npe) {
logger.log(Level.SEVERE, "Starting server failed due to no port available. ", npe); //NON-NLS
//try to kill it
} catch (KeywordSearchModuleException e) {
logger.log(Level.SEVERE, "Starting server failed. ", e); //NON-NLS
}
//retry if needed
//TODO this loop may be now redundant
while (retries-- > 0) {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
logger.log(Level.WARNING, "Timer interrupted."); //NON-NLS
}
try {
logger.log(Level.INFO, "Ensuring the server is running, retries remaining: " + retries); //NON-NLS
if (!server.isRunning()) {
logger.log(Level.WARNING, "Server still not running"); //NON-NLS
try {
logger.log(Level.WARNING, "Trying to start the server. "); //NON-NLS
server.start();
} catch (SolrServerNoPortException npe) {
logger.log(Level.SEVERE, "Starting server failed due to no port available. ", npe); //NON-NLS
}
} else {
logger.log(Level.INFO, "Server appears now running. "); //NON-NLS
break;
}
} catch (KeywordSearchModuleException ex) {
logger.log(Level.SEVERE, "Starting server failed. ", ex); //NON-NLS
//retry if has retries
}
} //end of retry while loop
//last check if still not running to report errors
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
logger.log(Level.WARNING, "Timer interrupted."); //NON-NLS
}
try {
logger.log(Level.INFO, "Last check if server is running. "); //NON-NLS
if (!server.isRunning()) {
logger.log(Level.SEVERE, "Server is still not running. "); //NON-NLS
//check if port is taken or some other reason
int serverPort = server.getCurrentSolrServerPort();
int serverStopPort = server.getCurrentSolrStopPort();
if (!Server.isPortAvailable(serverPort)) {
reportPortError(serverPort);
} else if (!Server.isPortAvailable(serverStopPort)) {
reportStopPortError(serverStopPort);
} else {
//some other reason
reportInitError();
}
}
} catch (KeywordSearchModuleException ex) {
logger.log(Level.SEVERE, "Starting server failed. ", ex); //NON-NLS
reportInitError();
}
catch (KeywordSearchModuleException ex) {
logger.log(Level.SEVERE, "Failed to start Keyword Search server: ", ex); //NON-NLS
reportInitError(ex.getMessage());
}
}
@Override
@@ -218,13 +98,10 @@ class Installer extends ModuleInstall {
});
}
private void reportInitError() {
private void reportInitError(final String msg) {
WindowManager.getDefault().invokeWhenUIReady(new Runnable() {
@Override
public void run() {
final String msg = NbBundle.getMessage(this.getClass(), "Installer.reportInitError", KeywordSearch.getServer().getCurrentSolrServerPort(), Version.getName(), Server.PROPERTIES_CURRENT_SERVER_PORT, Server.PROPERTIES_FILE);
MessageNotifyUtil.Notify.error(NbBundle.getMessage(this.getClass(), "Installer.errorInitKsmMsg"), msg);
MessageNotifyUtil.Notify.error(NbBundle.getMessage(this.getClass(), "Installer.errorInitKsmMsg"), msg);
}
});

View File

@@ -45,7 +45,6 @@ import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger;
import javax.swing.AbstractAction;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.request.CoreAdminRequest;
import org.apache.solr.client.solrj.response.QueryResponse;
@@ -63,6 +62,8 @@ import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.client.solrj.impl.XMLResponseParser;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrException;
import org.sleuthkit.autopsy.casemodule.Case.CaseType;
import org.sleuthkit.autopsy.core.UserPreferences;
/**
* Handles for keeping track of a Solr server and its cores
@@ -148,7 +149,6 @@ public class Server {
public static final long MAX_CONTENT_SIZE = 1L * 1024 * 1024 * 1024;
private static final Logger logger = Logger.getLogger(Server.class.getName());
private static final String DEFAULT_CORE_NAME = "coreCase"; //NON-NLS
// TODO: DEFAULT_CORE_NAME needs to be replaced with unique names to support multiple open cases
public static final String CORE_EVT = "CORE_EVT"; //NON-NLS
public static final char ID_CHUNK_SEP = '_';
private String javaPath = "java"; //NON-NLS
@@ -160,6 +160,7 @@ public class Server {
static final String PROPERTIES_CURRENT_SERVER_PORT = "IndexingServerPort"; //NON-NLS
static final String PROPERTIES_CURRENT_STOP_PORT = "IndexingServerStopPort"; //NON-NLS
private static final String KEY = "jjk#09s"; //NON-NLS
static final String DEFAULT_SOLR_SERVER_HOST = "localhost"; //NON-NLS
static final int DEFAULT_SOLR_SERVER_PORT = 23232;
static final int DEFAULT_SOLR_STOP_PORT = 34343;
private int currentSolrServerPort = 0;
@@ -170,23 +171,27 @@ public class Server {
STOPPED, STARTED
};
private SolrServer solrServer;
private String instanceDir;
private File solrFolder;
private ServerAction serverAction;
// A reference to the locally running Solr instance.
private final HttpSolrServer localSolrServer;
// A reference to the Solr server we are currently connected to for the Case.
// This could be a local or remote server.
private HttpSolrServer currentSolrServer;
private final String instanceDir;
private final File solrFolder;
private final ServerAction serverAction;
private InputStreamPrinterThread errorRedirectThread;
private String solrUrl;
/**
* New instance for the server at the given URL
*
* @param url should be something like "http://localhost:23232/solr/"
*/
Server() {
initSettings();
this.solrUrl = "http://localhost:" + currentSolrServerPort + "/solr"; //NON-NLS
this.solrServer = new HttpSolrServer(solrUrl);
this.localSolrServer = new HttpSolrServer("http://localhost:" + currentSolrServerPort + "/solr"); //NON-NLS
serverAction = new ServerAction();
solrFolder = InstalledFileLocator.getDefault().locate("solr", Server.class.getPackage().getName(), false); //NON-NLS
instanceDir = solrFolder.getAbsolutePath() + File.separator + "solr"; //NON-NLS
@@ -196,6 +201,7 @@ public class Server {
}
private void initSettings() {
if (ModuleSettings.settingExists(PROPERTIES_FILE, PROPERTIES_CURRENT_SERVER_PORT)) {
try {
currentSolrServerPort = Integer.decode(ModuleSettings.getConfigSetting(PROPERTIES_FILE, PROPERTIES_CURRENT_SERVER_PORT));
@@ -207,7 +213,7 @@ public class Server {
currentSolrServerPort = DEFAULT_SOLR_SERVER_PORT;
ModuleSettings.setConfigSetting(PROPERTIES_FILE, PROPERTIES_CURRENT_SERVER_PORT, String.valueOf(currentSolrServerPort));
}
if (ModuleSettings.settingExists(PROPERTIES_FILE, PROPERTIES_CURRENT_STOP_PORT)) {
try {
currentSolrStopPort = Integer.decode(ModuleSettings.getConfigSetting(PROPERTIES_FILE, PROPERTIES_CURRENT_STOP_PORT));
@@ -325,10 +331,10 @@ public class Server {
* @return
*/
List<Long> getSolrPIDs() {
List<Long> pids = new ArrayList<Long>();
List<Long> pids = new ArrayList<>();
//NOTE: these needs to be in sync with process start string in start()
final String pidsQuery = "Args.4.eq=-DSTOP.KEY=" + KEY + ",Args.7.eq=start.jar"; //NON-NLS
final String pidsQuery = "Args.4.eq=-DSTOP.KEY=" + KEY + ",Args.6.eq=start.jar"; //NON-NLS
long[] pidsArr = PlatformUtil.getJavaPIDs(pidsQuery);
if (pidsArr != null) {
@@ -353,12 +359,44 @@ public class Server {
}
/**
* Tries to start a Solr instance in a separate process. Returns immediately
* Tries to start a local Solr instance in a separate process. Returns immediately
* (probably before the server is ready) and doesn't check whether it was
* successful.
*/
void start() throws KeywordSearchModuleException, SolrServerNoPortException {
if (isRunning()) {
// If a Solr server is running we stop it.
stop();
}
if (!isPortAvailable(currentSolrServerPort)){
// There is something already listening on our port. Let's see if
// this is from an earlier run that didn't successfully shut down
// and if so kill it.
final List<Long> pids = this.getSolrPIDs();
// If the culprit listening on the port is not a Solr process
// we refuse to start.
if (pids.isEmpty()) {
throw new SolrServerNoPortException(currentSolrServerPort);
}
// Ok, we've tried to stop it above but there still appears to be
// a Solr process listening on our port so we forcefully kill it.
killSolr();
// If either of the ports are still in use after our attempt to kill
// previously running processes we give up and throw an exception.
if (!isPortAvailable(currentSolrServerPort)) {
throw new SolrServerNoPortException(currentSolrServerPort);
}
if (!isPortAvailable(currentSolrStopPort)) {
throw new SolrServerNoPortException(currentSolrStopPort);
}
}
logger.log(Level.INFO, "Starting Solr server from: " + solrFolder.getAbsolutePath()); //NON-NLS
if (isPortAvailable(currentSolrServerPort)) {
logger.log(Level.INFO, "Port [" + currentSolrServerPort + "] available, starting Solr"); //NON-NLS
try {
@@ -405,6 +443,7 @@ public class Server {
} catch (InterruptedException ex) {
logger.log(Level.WARNING, "Timer interrupted"); //NON-NLS
}
final List<Long> pids = this.getSolrPIDs();
logger.log(Level.INFO, "New Solr process PID: " + pids); //NON-NLS
} catch (SecurityException ex) {
@@ -416,10 +455,7 @@ public class Server {
throw new KeywordSearchModuleException(
NbBundle.getMessage(this.getClass(), "Server.start.exception.cantStartSolr.msg2"), ex);
}
} else {
logger.log(Level.SEVERE, "Could not start Solr server process, port [" + currentSolrServerPort + "] not available!"); //NON-NLS
throw new SolrServerNoPortException(currentSolrServerPort);
}
}
}
/**
@@ -472,11 +508,12 @@ public class Server {
}
/**
* Tries to stop a Solr instance.
* Tries to stop the local Solr instance.
*
* Waits for the stop command to finish before returning.
*/
synchronized void stop() {
try {
logger.log(Level.INFO, "Stopping Solr server from: " + solrFolder.getAbsolutePath()); //NON-NLS
//try graceful shutdown
@@ -498,8 +535,7 @@ public class Server {
curSolrProcess = null;
}
} catch (InterruptedException ex) {
} catch (IOException ex) {
} catch (InterruptedException | IOException ex) {
} finally {
//stop Solr stream -> log redirect threads
try {
@@ -517,7 +553,7 @@ public class Server {
}
/**
* Tests if there's a Solr server running by sending it a core-status
* Tests if there's a local Solr server running by sending it a core-status
* request.
*
* @return false if the request failed with a connection error, otherwise
@@ -525,13 +561,20 @@ public class Server {
*/
synchronized boolean isRunning() throws KeywordSearchModuleException {
try {
if (isPortAvailable(currentSolrServerPort)) {
return false;
}
if (curSolrProcess != null && !curSolrProcess.isAlive()) {
return false;
}
// making a status request here instead of just doing solrServer.ping(), because
// that doesn't work when there are no cores
//TODO check if port avail and return false if it is
//TODO handle timeout in cases when some other type of server on that port
CoreAdminRequest.getStatus(null, solrServer);
CoreAdminRequest.getStatus(null, localSolrServer);
logger.log(Level.INFO, "Solr server is running"); //NON-NLS
} catch (SolrServerException ex) {
@@ -642,7 +685,8 @@ public class Server {
*/
private synchronized Core openCore(Case theCase) throws KeywordSearchModuleException {
String dataDir = getIndexDirPath(theCase);
return this.openCore(DEFAULT_CORE_NAME, new File(dataDir));
String coreName = theCase.getTextIndexName();
return this.openCore(coreName.isEmpty() ? DEFAULT_CORE_NAME : coreName, new File(dataDir), theCase.getCaseType());
}
/**
@@ -914,7 +958,7 @@ public class Server {
* @param dataDir directory to load/store the core data from/to
* @return new core
*/
private Core openCore(String coreName, File dataDir) throws KeywordSearchModuleException {
private Core openCore(String coreName, File dataDir, CaseType caseType) throws KeywordSearchModuleException {
try {
if (!dataDir.exists()) {
dataDir.mkdirs();
@@ -929,17 +973,24 @@ public class Server {
CoreAdminRequest.Create createCore = new CoreAdminRequest.Create();
createCore.setDataDir(dataDir.getAbsolutePath());
createCore.setInstanceDir(instanceDir);
createCore.setCoreName(coreName);
createCore.setConfigSet("AutopsyConfig");
this.solrServer.request(createCore);
if (caseType == CaseType.SINGLE_USER_CASE) {
currentSolrServer = this.localSolrServer;
//createCore.setInstanceDir(instanceDir);
}
else {
currentSolrServer = connectToRemoteSolrServer();
}
currentSolrServer.request(createCore);
final Core newCore = new Core(coreName);
return newCore;
} catch (SolrServerException ex) {
} catch (SolrServerException | SolrException ex) {
throw new KeywordSearchModuleException(
NbBundle.getMessage(this.getClass(), "Server.openCore.exception.cantOpen.msg"), ex);
} catch (IOException ex) {
@@ -948,6 +999,13 @@ public class Server {
}
}
private HttpSolrServer connectToRemoteSolrServer() {
String host = UserPreferences.getIndexingServerHost();
String port = UserPreferences.getIndexingServerPort();
return new HttpSolrServer("http://" + host + ":" + port + "/solr");
}
class Core {
// handle to the core in Solr
@@ -959,7 +1017,7 @@ public class Server {
private Core(String name) {
this.name = name;
this.solrCore = new HttpSolrServer(solrUrl + "/" + name);
this.solrCore = new HttpSolrServer(currentSolrServer.getBaseURL() + "/" + name);
//TODO test these settings
//solrCore.setSoTimeout(1000 * 60); // socket read timeout, make large enough so can index larger files
@@ -1062,7 +1120,7 @@ public class Server {
synchronized void close() throws KeywordSearchModuleException {
try {
CoreAdminRequest.unloadCore(this.name, solrServer);
CoreAdminRequest.unloadCore(this.name, currentSolrServer);
} catch (SolrServerException ex) {
throw new KeywordSearchModuleException(
NbBundle.getMessage(this.getClass(), "Server.close.exception.msg"), ex);