19 package org.sleuthkit.autopsy.keywordsearch;
21 import java.awt.event.ActionEvent;
22 import java.beans.PropertyChangeListener;
23 import java.io.BufferedReader;
24 import java.io.BufferedWriter;
26 import java.io.FileOutputStream;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.io.InputStreamReader;
30 import java.io.OutputStream;
31 import java.io.OutputStreamWriter;
32 import java.net.ConnectException;
33 import java.net.ServerSocket;
34 import java.net.SocketException;
35 import java.nio.charset.Charset;
36 import java.nio.file.Files;
37 import java.nio.file.Path;
38 import java.nio.file.Paths;
39 import java.util.ArrayList;
40 import java.util.Arrays;
41 import java.util.Collection;
42 import java.util.List;
43 import java.util.concurrent.locks.ReentrantReadWriteLock;
44 import java.util.logging.Level;
45 import javax.swing.AbstractAction;
46 import org.apache.solr.client.solrj.SolrQuery;
47 import org.apache.solr.client.solrj.SolrRequest;
48 import org.apache.solr.client.solrj.SolrServerException;
49 import org.apache.solr.client.solrj.impl.HttpSolrServer;
50 import org.apache.solr.client.solrj.impl.XMLResponseParser;
51 import org.apache.solr.client.solrj.request.CoreAdminRequest;
52 import org.apache.solr.client.solrj.response.CoreAdminResponse;
53 import org.apache.solr.client.solrj.response.QueryResponse;
54 import org.apache.solr.client.solrj.response.TermsResponse;
55 import org.apache.solr.common.SolrDocument;
56 import org.apache.solr.common.SolrDocumentList;
57 import org.apache.solr.common.SolrException;
58 import org.apache.solr.common.SolrInputDocument;
59 import org.apache.solr.common.util.NamedList;
60 import org.openide.modules.InstalledFileLocator;
61 import org.openide.modules.Places;
62 import org.openide.util.NbBundle;
85 public String toString() {
91 public String toString() {
98 public String toString() {
104 public String toString() {
105 return "content_str";
110 public String toString() {
116 public String toString() {
122 public String toString() {
129 public String toString() {
136 public String toString() {
143 public String toString() {
150 public String toString() {
156 public String toString() {
162 public String toString() {
180 static final String PROPERTIES_FILE = KeywordSearchSettings.MODULE_NAME;
181 static final String PROPERTIES_CURRENT_SERVER_PORT =
"IndexingServerPort";
182 static final String PROPERTIES_CURRENT_STOP_PORT =
"IndexingServerStopPort";
183 private static final String
KEY =
"jjk#09s";
184 static final String DEFAULT_SOLR_SERVER_HOST =
"localhost";
185 static final int DEFAULT_SOLR_SERVER_PORT = 23232;
186 static final int DEFAULT_SOLR_STOP_PORT = 34343;
189 private static final boolean DEBUG =
false;
190 private static final String
SOLR =
"solr";
220 this.localSolrServer =
new HttpSolrServer(
"http://localhost:" + currentSolrServerPort +
"/solr");
221 serverAction =
new ServerAction();
222 solrFolder = InstalledFileLocator.getDefault().locate(
"solr",
Server.class.getPackage().getName(),
false);
226 if (!solrHome.toFile().exists()) {
228 Files.createDirectory(solrHome);
229 Files.copy(Paths.get(solrFolder.getAbsolutePath(),
"solr",
"solr.xml"), solrHome.resolve(
"solr.xml"));
230 Files.copy(Paths.get(solrFolder.getAbsolutePath(),
"solr",
"zoo.cfg"), solrHome.resolve(
"zoo.cfg"));
231 }
catch (IOException ex) {
232 logger.log(Level.SEVERE,
"Failed to create Solr home folder:", ex);
235 currentCoreLock =
new ReentrantReadWriteLock(
true);
237 logger.log(Level.INFO,
"Created Server instance using Java at {0}", javaPath);
245 }
catch (NumberFormatException nfe) {
246 logger.log(Level.WARNING,
"Could not decode indexing server port, value was not a valid port number, using the default. ", nfe);
247 currentSolrServerPort = DEFAULT_SOLR_SERVER_PORT;
250 currentSolrServerPort = DEFAULT_SOLR_SERVER_PORT;
257 }
catch (NumberFormatException nfe) {
258 logger.log(Level.WARNING,
"Could not decode indexing server stop port, value was not a valid port number, using default", nfe);
259 currentSolrStopPort = DEFAULT_SOLR_STOP_PORT;
262 currentSolrStopPort = DEFAULT_SOLR_STOP_PORT;
268 public void finalize() throws java.lang.Throwable {
274 serverAction.addPropertyChangeListener(l);
277 int getCurrentSolrServerPort() {
281 int getCurrentSolrStopPort() {
292 volatile boolean doRun =
true;
295 this.stream = stream;
297 final String log = Places.getUserDirectory().getAbsolutePath()
298 + File.separator +
"var" + File.separator +
"log"
299 + File.separator +
"solr.log." + type;
300 File outputFile =
new File(log.concat(
".0"));
301 File first =
new File(log.concat(
".1"));
302 File second =
new File(log.concat(
".2"));
303 if (second.exists()) {
306 if (first.exists()) {
307 first.renameTo(second);
309 if (outputFile.exists()) {
310 outputFile.renameTo(first);
312 outputFile.createNewFile();
314 out =
new FileOutputStream(outputFile);
316 }
catch (Exception ex) {
317 logger.log(Level.WARNING,
"Failed to create solr log file", ex);
328 try (InputStreamReader isr =
new InputStreamReader(stream);
329 BufferedReader br =
new BufferedReader(isr);
331 BufferedWriter bw =
new BufferedWriter(osw);) {
334 while (doRun && (line = br.readLine()) != null) {
343 }
catch (IOException ex) {
344 logger.log(Level.SEVERE,
"Error redirecting Solr output stream", ex);
359 final String MAX_SOLR_MEM_MB_PAR =
"-Xmx" + Integer.toString(MAX_SOLR_MEM_MB) +
"m";
360 List<String> commandLine =
new ArrayList<>();
361 commandLine.add(javaPath);
362 commandLine.add(MAX_SOLR_MEM_MB_PAR);
363 commandLine.add(
"-DSTOP.PORT=" + currentSolrStopPort);
364 commandLine.add(
"-Djetty.port=" + currentSolrServerPort);
365 commandLine.add(
"-DSTOP.KEY=" + KEY);
366 commandLine.add(
"-jar");
367 commandLine.add(
"start.jar");
369 commandLine.addAll(solrArguments);
371 ProcessBuilder solrProcessBuilder =
new ProcessBuilder(commandLine);
372 solrProcessBuilder.directory(solrFolder);
375 Path solrStdoutPath = Paths.get(Places.getUserDirectory().getAbsolutePath(),
"var",
"log",
"solr.log.stdout");
376 solrProcessBuilder.redirectOutput(solrStdoutPath.toFile());
378 Path solrStderrPath = Paths.get(Places.getUserDirectory().getAbsolutePath(),
"var",
"log",
"solr.log.stderr");
379 solrProcessBuilder.redirectError(solrStderrPath.toFile());
381 logger.log(Level.INFO,
"Running Solr command: {0}", solrProcessBuilder.command());
382 Process process = solrProcessBuilder.start();
383 logger.log(Level.INFO,
"Finished running Solr command");
392 List<Long> getSolrPIDs() {
393 List<Long> pids =
new ArrayList<>();
396 final String pidsQuery =
"Args.*.eq=-DSTOP.KEY=" + KEY +
",Args.*.eq=start.jar";
399 if (pidsArr != null) {
400 for (
int i = 0; i < pidsArr.length; ++i) {
401 pids.add(pidsArr[i]);
413 List<Long> solrPids = getSolrPIDs();
414 for (
long pid : solrPids) {
415 logger.log(Level.INFO,
"Trying to kill old Solr process, PID: {0}", pid);
416 PlatformUtil.killProcess(pid);
425 void start() throws KeywordSearchModuleException, SolrServerNoPortException {
431 if (!isPortAvailable(currentSolrServerPort)) {
435 final List<Long> pids = this.getSolrPIDs();
439 if (pids.isEmpty()) {
440 throw new SolrServerNoPortException(currentSolrServerPort);
449 if (!isPortAvailable(currentSolrServerPort)) {
450 throw new SolrServerNoPortException(currentSolrServerPort);
452 if (!isPortAvailable(currentSolrStopPort)) {
453 throw new SolrServerNoPortException(currentSolrStopPort);
457 logger.log(Level.INFO,
"Starting Solr server from: {0}", solrFolder.getAbsolutePath());
459 if (isPortAvailable(currentSolrServerPort)) {
460 logger.log(Level.INFO,
"Port [{0}] available, starting Solr", currentSolrServerPort);
463 Arrays.asList(
"-Dbootstrap_confdir=../solr/configsets/AutopsyConfig/conf",
464 "-Dcollection.configName=AutopsyConfig")));
469 Thread.sleep(10 * 1000);
470 }
catch (InterruptedException ex) {
471 logger.log(Level.WARNING,
"Timer interrupted");
474 final List<Long> pids = this.getSolrPIDs();
475 logger.log(Level.INFO,
"New Solr process PID: {0}", pids);
476 }
catch (SecurityException ex) {
477 logger.log(Level.SEVERE,
"Could not start Solr process!", ex);
478 throw new KeywordSearchModuleException(
479 NbBundle.getMessage(
this.getClass(),
"Server.start.exception.cantStartSolr.msg"), ex);
480 }
catch (IOException ex) {
481 logger.log(Level.SEVERE,
"Could not start Solr server process!", ex);
482 throw new KeywordSearchModuleException(
483 NbBundle.getMessage(
this.getClass(),
"Server.start.exception.cantStartSolr.msg2"), ex);
493 static boolean isPortAvailable(
int port) {
494 ServerSocket ss = null;
497 ss =
new ServerSocket(port, 0, java.net.Inet4Address.getByName(
"localhost"));
499 ss.setReuseAddress(
true);
504 }
catch (IOException e) {
509 }
catch (IOException e) {
524 void changeSolrServerPort(
int port) {
525 currentSolrServerPort = port;
526 ModuleSettings.setConfigSetting(PROPERTIES_FILE, PROPERTIES_CURRENT_SERVER_PORT, String.valueOf(port));
534 void changeSolrStopPort(
int port) {
535 currentSolrStopPort = port;
536 ModuleSettings.setConfigSetting(PROPERTIES_FILE, PROPERTIES_CURRENT_STOP_PORT, String.valueOf(port));
544 synchronized void stop() {
549 }
catch (KeywordSearchModuleException e) {
550 logger.log(Level.WARNING,
"Failed to close core: ", e);
554 logger.log(Level.INFO,
"Stopping Solr server from: {0}", solrFolder.getAbsolutePath());
557 Process process =
runSolrCommand(
new ArrayList<>(Arrays.asList(
"--stop")));
559 logger.log(Level.INFO,
"Waiting for Solr server to stop");
563 if (curSolrProcess != null) {
564 curSolrProcess.destroy();
565 curSolrProcess = null;
568 }
catch (IOException | InterruptedException ex) {
569 logger.log(Level.WARNING,
"Error while attempting to stop Solr server", ex);
573 if (errorRedirectThread != null) {
574 errorRedirectThread.stopRun();
575 errorRedirectThread = null;
582 logger.log(Level.INFO,
"Finished stopping Solr server");
593 synchronized boolean isRunning() throws KeywordSearchModuleException {
596 if (isPortAvailable(currentSolrServerPort)) {
603 CoreAdminRequest.getStatus(null, localSolrServer);
605 logger.log(Level.INFO,
"Solr server is running");
606 }
catch (SolrServerException ex) {
608 Throwable cause = ex.getRootCause();
613 if (cause instanceof ConnectException || cause instanceof SocketException) {
614 logger.log(Level.INFO,
"Solr server is not running, cause: {0}", cause.getMessage());
617 throw new KeywordSearchModuleException(
618 NbBundle.getMessage(
this.getClass(),
"Server.isRunning.exception.errCheckSolrRunning.msg"), ex);
620 }
catch (SolrException ex) {
622 logger.log(Level.INFO,
"Solr server is not running", ex);
624 }
catch (IOException ex) {
625 throw new KeywordSearchModuleException(
626 NbBundle.getMessage(
this.getClass(),
"Server.isRunning.exception.errCheckSolrRunning.msg2"), ex);
644 void openCoreForCase(Case theCase, Index index)
throws KeywordSearchModuleException {
645 currentCoreLock.writeLock().lock();
647 currentCore =
openCore(theCase, index);
652 }
catch (NoOpenCoreException ex) {
653 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(),
"Server.openCore.exception.cantOpen.msg"), ex);
656 serverAction.putValue(CORE_EVT, CORE_EVT_STATES.STARTED);
658 currentCoreLock.writeLock().unlock();
667 boolean coreIsOpen() {
668 currentCoreLock.readLock().lock();
670 return (null != currentCore);
672 currentCoreLock.readLock().unlock();
676 Index getIndexInfo() throws NoOpenCoreException {
677 currentCoreLock.readLock().lock();
679 if (null == currentCore) {
680 throw new NoOpenCoreException();
682 return currentCore.getIndexInfo();
684 currentCoreLock.readLock().unlock();
688 void closeCore() throws KeywordSearchModuleException {
689 currentCoreLock.writeLock().lock();
691 if (null != currentCore) {
694 serverAction.putValue(CORE_EVT, CORE_EVT_STATES.STOPPED);
697 currentCoreLock.writeLock().unlock();
701 void addDocument(SolrInputDocument doc)
throws KeywordSearchModuleException, NoOpenCoreException {
702 currentCoreLock.readLock().lock();
704 if (null == currentCore) {
705 throw new NoOpenCoreException();
707 currentCore.addDocument(doc);
709 currentCoreLock.readLock().unlock();
722 "# {0} - core name",
"Server.deleteCore.exception.msg=Failed to delete Solr core {0}",})
723 void deleteCore(String coreName, Case.CaseType caseType)
throws KeywordSearchServiceException {
725 HttpSolrServer solrServer;
726 if (caseType == CaseType.SINGLE_USER_CASE) {
727 Integer localSolrServerPort = Integer.decode(ModuleSettings.getConfigSetting(PROPERTIES_FILE, PROPERTIES_CURRENT_SERVER_PORT));
728 solrServer =
new HttpSolrServer(
"http://localhost:" + localSolrServerPort +
"/solr");
730 String host = UserPreferences.getIndexingServerHost();
731 String port = UserPreferences.getIndexingServerPort();
732 solrServer =
new HttpSolrServer(
"http://" + host +
":" + port +
"/solr");
734 connectToSolrServer(solrServer);
735 CoreAdminResponse response = CoreAdminRequest.getStatus(coreName, solrServer);
736 if (null != response.getCoreStatus(coreName).get(
"instanceDir")) {
746 org.apache.solr.client.solrj.request.CoreAdminRequest.unloadCore(coreName,
true,
true, solrServer);
748 }
catch (SolrServerException | HttpSolrServer.RemoteSolrException | IOException ex) {
749 throw new KeywordSearchServiceException(Bundle.Server_deleteCore_exception_msg(coreName), ex);
764 private Core
openCore(
Case theCase, Index index)
throws KeywordSearchModuleException {
772 currentSolrServer =
new HttpSolrServer(
"http://" + host +
":" + port +
"/solr");
774 connectToSolrServer(currentSolrServer);
776 }
catch (SolrServerException | IOException ex) {
777 throw new KeywordSearchModuleException(NbBundle.getMessage(
Server.class,
"Server.connect.exception.msg", ex.getLocalizedMessage()), ex);
781 File dataDir =
new File(
new File(index.getIndexPath()).getParent());
782 if (!dataDir.exists()) {
786 if (!this.isRunning()) {
787 logger.log(Level.SEVERE,
"Core create/open requested, but server not yet running");
788 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(),
"Server.openCore.exception.msg"));
791 String coreName = index.getIndexName();
802 Path corePropertiesFile = Paths.get(solrFolder.toString(),
SOLR, coreName,
CORE_PROPERTIES);
803 if (corePropertiesFile.toFile().exists()) {
805 corePropertiesFile.toFile().delete();
806 }
catch (Exception ex) {
807 logger.log(Level.INFO,
"Could not delete pre-existing core.properties prior to opening the core.");
812 CoreAdminRequest.Create createCoreRequest =
new CoreAdminRequest.Create();
813 createCoreRequest.setDataDir(dataDir.getAbsolutePath());
814 createCoreRequest.setCoreName(coreName);
815 createCoreRequest.setConfigSet(
"AutopsyConfig");
816 createCoreRequest.setIsLoadOnStartup(
false);
817 createCoreRequest.setIsTransient(
true);
818 currentSolrServer.request(createCoreRequest);
822 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(),
"Server.openCore.exception.noIndexDir.msg"));
825 return new Core(coreName, theCase.getCaseType(), index);
827 }
catch (Exception ex) {
828 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(),
"Server.openCore.exception.cantOpen.msg"), ex);
837 void commit() throws SolrServerException, NoOpenCoreException {
838 currentCoreLock.readLock().lock();
840 if (null == currentCore) {
841 throw new NoOpenCoreException();
843 currentCore.commit();
845 currentCoreLock.readLock().unlock();
849 NamedList<Object> request(SolrRequest request)
throws SolrServerException, NoOpenCoreException {
850 currentCoreLock.readLock().lock();
852 if (null == currentCore) {
853 throw new NoOpenCoreException();
855 return currentCore.request(request);
857 currentCoreLock.readLock().unlock();
872 currentCoreLock.readLock().lock();
874 if (null == currentCore) {
875 throw new NoOpenCoreException();
878 return currentCore.queryNumIndexedFiles();
879 }
catch (SolrServerException | IOException ex) {
880 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(),
"Server.queryNumIdxFiles.exception.msg"), ex);
883 currentCoreLock.readLock().unlock();
897 currentCoreLock.readLock().lock();
899 if (null == currentCore) {
900 throw new NoOpenCoreException();
903 return currentCore.queryNumIndexedChunks();
904 }
catch (SolrServerException | IOException ex) {
905 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(),
"Server.queryNumIdxChunks.exception.msg"), ex);
908 currentCoreLock.readLock().unlock();
922 currentCoreLock.readLock().lock();
924 if (null == currentCore) {
925 throw new NoOpenCoreException();
928 return currentCore.queryNumIndexedDocuments();
929 }
catch (SolrServerException | IOException ex) {
930 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(),
"Server.queryNumIdxDocs.exception.msg"), ex);
933 currentCoreLock.readLock().unlock();
947 public boolean queryIsIndexed(
long contentID)
throws KeywordSearchModuleException, NoOpenCoreException {
948 currentCoreLock.readLock().lock();
950 if (null == currentCore) {
951 throw new NoOpenCoreException();
954 return currentCore.queryIsIndexed(contentID);
955 }
catch (SolrServerException | IOException ex) {
956 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(),
"Server.queryIsIdxd.exception.msg"), ex);
960 currentCoreLock.readLock().unlock();
975 public int queryNumFileChunks(
long fileID)
throws KeywordSearchModuleException, NoOpenCoreException {
976 currentCoreLock.readLock().lock();
978 if (null == currentCore) {
979 throw new NoOpenCoreException();
982 return currentCore.queryNumFileChunks(fileID);
983 }
catch (SolrServerException | IOException ex) {
984 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(),
"Server.queryNumFileChunks.exception.msg"), ex);
987 currentCoreLock.readLock().unlock();
1001 public QueryResponse
query(SolrQuery sq)
throws KeywordSearchModuleException, NoOpenCoreException, IOException {
1002 currentCoreLock.readLock().lock();
1004 if (null == currentCore) {
1005 throw new NoOpenCoreException();
1008 return currentCore.query(sq);
1009 }
catch (SolrServerException ex) {
1010 logger.log(Level.SEVERE,
"Solr query failed: " + sq.getQuery(), ex);
1011 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(),
"Server.query.exception.msg", sq.getQuery()), ex);
1014 currentCoreLock.readLock().unlock();
1029 public QueryResponse
query(SolrQuery sq, SolrRequest.METHOD method) throws KeywordSearchModuleException, NoOpenCoreException {
1030 currentCoreLock.readLock().lock();
1032 if (null == currentCore) {
1033 throw new NoOpenCoreException();
1036 return currentCore.query(sq, method);
1037 }
catch (SolrServerException | IOException ex) {
1038 logger.log(Level.SEVERE,
"Solr query failed: " + sq.getQuery(), ex);
1039 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(),
"Server.query2.exception.msg", sq.getQuery()), ex);
1042 currentCoreLock.readLock().unlock();
1056 public TermsResponse
queryTerms(SolrQuery sq)
throws KeywordSearchModuleException, NoOpenCoreException {
1057 currentCoreLock.readLock().lock();
1059 if (null == currentCore) {
1060 throw new NoOpenCoreException();
1063 return currentCore.queryTerms(sq);
1064 }
catch (SolrServerException | IOException ex) {
1065 logger.log(Level.SEVERE,
"Solr terms query failed: " + sq.getQuery(), ex);
1066 throw new KeywordSearchModuleException(NbBundle.getMessage(
this.getClass(),
"Server.queryTerms.exception.msg", sq.getQuery()), ex);
1069 currentCoreLock.readLock().unlock();
1083 currentCoreLock.readLock().lock();
1085 if (null == currentCore) {
1086 throw new NoOpenCoreException();
1088 return currentCore.getSolrContent(content.getId(), 0);
1090 currentCoreLock.readLock().unlock();
1106 public String
getSolrContent(
final Content content,
int chunkID)
throws NoOpenCoreException {
1107 currentCoreLock.readLock().lock();
1109 if (null == currentCore) {
1110 throw new NoOpenCoreException();
1112 return currentCore.getSolrContent(content.getId(), chunkID);
1114 currentCoreLock.readLock().unlock();
1128 currentCoreLock.readLock().lock();
1130 if (null == currentCore) {
1131 throw new NoOpenCoreException();
1133 return currentCore.getSolrContent(objectID, 0);
1135 currentCoreLock.readLock().unlock();
1149 public String
getSolrContent(
final long objectID,
final int chunkID)
throws NoOpenCoreException {
1150 currentCoreLock.readLock().lock();
1152 if (null == currentCore) {
1153 throw new NoOpenCoreException();
1155 return currentCore.getSolrContent(objectID, chunkID);
1157 currentCoreLock.readLock().unlock();
1182 void connectToSolrServer(HttpSolrServer solrServer)
throws SolrServerException, IOException {
1183 CoreAdminRequest.getStatus(null, solrServer);
1199 private boolean coreIsLoaded(String coreName)
throws SolrServerException, IOException {
1200 CoreAdminResponse response = CoreAdminRequest.getStatus(coreName, currentSolrServer);
1201 return response.getCoreStatus(coreName).get(
"instanceDir") != null;
1215 CoreAdminResponse response = CoreAdminRequest.getStatus(coreName, currentSolrServer);
1216 Object dataDirPath = response.getCoreStatus(coreName).get(
"dataDir");
1217 if (null != dataDirPath) {
1218 File indexDir = Paths.get((String) dataDirPath,
"index").toFile();
1219 return indexDir.exists();
1228 private final String name;
1232 private final Index textIndex;
1236 private final HttpSolrServer solrCore;
1238 private final int QUERY_TIMEOUT_MILLISECONDS = 86400000;
1240 private Core(String name,
CaseType caseType, Index index) {
1242 this.caseType = caseType;
1243 this.textIndex = index;
1245 this.solrCore =
new HttpSolrServer(currentSolrServer.getBaseURL() +
"/" + name);
1249 solrCore.setSoTimeout(QUERY_TIMEOUT_MILLISECONDS);
1251 solrCore.setDefaultMaxConnectionsPerHost(32);
1252 solrCore.setMaxTotalConnections(32);
1253 solrCore.setFollowRedirects(
false);
1256 solrCore.setAllowCompression(
true);
1257 solrCore.setParser(
new XMLResponseParser());
1270 private Index getIndexInfo() {
1271 return this.textIndex;
1274 private QueryResponse
query(SolrQuery sq)
throws SolrServerException, IOException {
1275 return solrCore.query(sq);
1278 private NamedList<Object> request(SolrRequest request)
throws SolrServerException {
1280 return solrCore.request(request);
1281 }
catch (IOException e) {
1282 logger.log(Level.WARNING,
"Could not issue Solr request. ", e);
1283 throw new SolrServerException(
1284 NbBundle.getMessage(
this.getClass(),
"Server.request.exception.exception.msg"), e);
1289 private QueryResponse
query(SolrQuery sq, SolrRequest.METHOD method) throws SolrServerException, IOException {
1290 return solrCore.query(sq, method);
1293 private TermsResponse
queryTerms(SolrQuery sq)
throws SolrServerException, IOException {
1294 QueryResponse qres = solrCore.query(sq);
1295 return qres.getTermsResponse();
1298 private void commit() throws SolrServerException {
1301 solrCore.commit(
true,
true);
1302 }
catch (IOException e) {
1303 logger.log(Level.WARNING,
"Could not commit index. ", e);
1304 throw new SolrServerException(NbBundle.getMessage(
this.getClass(),
"Server.commit.exception.msg"), e);
1308 void addDocument(SolrInputDocument doc)
throws KeywordSearchModuleException {
1311 }
catch (SolrServerException ex) {
1312 logger.log(Level.SEVERE,
"Could not add document to index via update handler: " + doc.getField(
"id"), ex);
1313 throw new KeywordSearchModuleException(
1314 NbBundle.getMessage(
this.getClass(),
"Server.addDoc.exception.msg", doc.getField(
"id")), ex);
1315 }
catch (IOException ex) {
1316 logger.log(Level.SEVERE,
"Could not add document to index via update handler: " + doc.getField(
"id"), ex);
1317 throw new KeywordSearchModuleException(
1318 NbBundle.getMessage(
this.getClass(),
"Server.addDoc.exception.msg2", doc.getField(
"id")), ex);
1332 final SolrQuery q =
new SolrQuery();
1334 String filterQuery = Schema.ID.toString() +
":" + KeywordSearchUtil.escapeLuceneQuery(Long.toString(contentID));
1336 filterQuery = filterQuery + Server.CHUNK_ID_SEPARATOR + chunkID;
1338 q.addFilterQuery(filterQuery);
1339 q.setFields(Schema.TEXT.toString());
1342 SolrDocumentList solrDocuments = solrCore.query(q).getResults();
1344 if (!solrDocuments.isEmpty()) {
1345 SolrDocument solrDocument = solrDocuments.get(0);
1346 if (solrDocument != null) {
1347 Collection<Object> fieldValues = solrDocument.getFieldValues(Schema.TEXT.toString());
1348 if (fieldValues.size() == 1)
1350 return fieldValues.toArray(
new String[0])[0];
1354 return fieldValues.toArray(
new String[0])[1];
1358 }
catch (SolrServerException ex) {
1359 logger.log(Level.SEVERE,
"Error getting content from Solr. Solr document id " + contentID +
", chunk id " + chunkID +
", query: " + filterQuery, ex);
1366 synchronized void close() throws KeywordSearchModuleException {
1373 CoreAdminRequest.unloadCore(this.name, currentSolrServer);
1374 }
catch (SolrServerException ex) {
1375 throw new KeywordSearchModuleException(
1376 NbBundle.getMessage(
this.getClass(),
"Server.close.exception.msg"), ex);
1377 }
catch (IOException ex) {
1378 throw new KeywordSearchModuleException(
1379 NbBundle.getMessage(
this.getClass(),
"Server.close.exception.msg2"), ex);
1406 SolrQuery q =
new SolrQuery(Server.Schema.ID +
":*" + Server.CHUNK_ID_SEPARATOR +
"*");
1408 int numChunks = (int)
query(q).getResults().getNumFound();
1423 SolrQuery q =
new SolrQuery(
"*:*");
1425 return (
int)
query(q).getResults().getNumFound();
1437 private boolean queryIsIndexed(
long contentID)
throws SolrServerException, IOException {
1438 String
id = KeywordSearchUtil.escapeLuceneQuery(Long.toString(contentID));
1439 SolrQuery q =
new SolrQuery(
"*:*");
1440 q.addFilterQuery(Server.Schema.ID.toString() +
":" + id);
1443 return (
int)
query(q).getResults().getNumFound() != 0;
1457 private int queryNumFileChunks(
long contentID)
throws SolrServerException, IOException {
1458 String
id = KeywordSearchUtil.escapeLuceneQuery(Long.toString(contentID));
1460 =
new SolrQuery(Server.Schema.ID +
":" +
id + Server.CHUNK_ID_SEPARATOR +
"*");
1462 return (
int)
query(q).getResults().getNumFound();
1466 class ServerAction
extends AbstractAction {
1468 private static final long serialVersionUID = 1L;
1471 public void actionPerformed(ActionEvent e) {
1472 logger.log(Level.INFO, e.paramString().trim());
1479 class SolrServerNoPortException
extends SocketException {
1481 private static final long serialVersionUID = 1L;
1486 private final int port;
1488 SolrServerNoPortException(
int port) {
1489 super(NbBundle.getMessage(Server.class,
"Server.solrServerNoPortException.msg", port,
1490 Server.PROPERTIES_CURRENT_SERVER_PORT));
1494 int getPortNumber() {
int queryNumIndexedFiles()
String getSolrContent(final long objectID)
final ReentrantReadWriteLock currentCoreLock
int queryNumIndexedChunks()
static final char ID_CHUNK_SEP
final ServerAction serverAction
static String getIndexingServerPort()
static final String CORE_PROPERTIES
boolean coreIsLoaded(String coreName)
final HttpSolrServer localSolrServer
static final Logger logger
void addServerActionListener(PropertyChangeListener l)
static final String HL_ANALYZE_CHARS_UNLIMITED
Process runSolrCommand(List< String > solrArguments)
String getSolrContent(final Content content)
static final long MAX_CONTENT_SIZE
boolean coreIndexFolderExists(String coreName)
HttpSolrServer currentSolrServer
int queryNumIndexedDocuments()
static synchronized void setConfigSetting(String moduleName, String settingName, String settingVal)
static final String CHUNK_ID_SEPARATOR
static final String CORE_EVT
static final Charset DEFAULT_INDEXED_TEXT_CHARSET
default Charset to index text as
InputStreamPrinterThread errorRedirectThread
QueryResponse query(SolrQuery sq)
static String getConfigSetting(String moduleName, String settingName)
int currentSolrServerPort
TermsResponse queryTerms(SolrQuery sq)
boolean queryIsIndexed(long contentID)
String getSolrContent(final Content content, int chunkID)
String getSolrContent(final long objectID, final int chunkID)
synchronized static Logger getLogger(String name)
Core openCore(Case theCase, Index index)
static final int MAX_SOLR_MEM_MB
static String getChunkIdString(long parentID, int childID)
static String getIndexingServerHost()
static boolean settingExists(String moduleName, String settingName)
int queryNumFileChunks(long fileID)
static final boolean DEBUG
QueryResponse query(SolrQuery sq, SolrRequest.METHOD method)