Skip to content

Commit 38281ed

Browse files
committed
fixes igniterealtime#354: Allow text-search/indexing to be disabled.
This introduces a new system property, `conversation.search.index-enabled`, that, when set to 'false', disables the full-text search functionality and corresponding indexing tasks. Disabling this functionality can save some resources on instances that do not use the feature, and have a large amount of messages in their database.
1 parent 1d80333 commit 38281ed

13 files changed

+137
-45
lines changed

changelog.html

+10
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@ <h1>
4444
Monitoring Plugin Changelog
4545
</h1>
4646

47+
<p><b>2.6.2</b> -- To be determined</p>
48+
<ul>
49+
<li>[<a href='https://github.com/igniterealtime/openfire-monitoring-plugin/issues/354'>Issue #354</a>] - Allow full-text search / indexing to be disabled</li>
50+
</ul>
51+
52+
<p><b>2.6.1</b> -- October 30, 2024</p>
53+
<ul>
54+
<li>Future release will require Openfire 4.10</li>
55+
</ul>
56+
4757
<p><b>2.6.1</b> -- October 30, 2024</p>
4858
<ul>
4959
<li>Explicitly denote that this version will not be compatible with Openfire 4.10.0 or later.</li>

plugin.xml

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
<description>Monitors conversations and statistics of the server.</description>
77
<author>Ignite Realtime</author>
88
<version>${project.version}</version>
9-
<date>2024-10-30</date>
9+
<date>2024-12-10</date>
1010
<minServerVersion>4.8.0</minServerVersion>
11-
<priorToServerVersion>4.10.0</priorToServerVersion>
11+
<priorToServerVersion>5.0.0</priorToServerVersion>
1212
<databaseKey>monitoring</databaseKey>
1313
<databaseVersion>8</databaseVersion>
1414

readme.html

+7
Original file line numberDiff line numberDiff line change
@@ -116,5 +116,12 @@ <h2>Configuration</h2>
116116
Server --&gt; Archiving --&gt; Archiving Settings
117117
</p>
118118

119+
<p>
120+
Since version 2.7.0, it is possibly to <em>disable</em> full-text search functionality by configuration. To do so, a
121+
system property named <tt>conversation.search.index-enabled</tt> must be defined, and should have the value
122+
<tt>false</tt>. The default setting is for this functionality to be <em>enabled</em>. Changes to this configuration
123+
require a restart for the new setting to be applied.
124+
</p>
125+
119126
</body>
120127
</html>

src/i18n/monitoring_i18n.properties

+1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ archive.settings.max.retrievable = Retrievable Messages
8383
archive.settings.max.retrievable.description = The number of days worth of messages a user is allowed to retrieve.
8484
archive.settings.index.settings = Index Settings
8585
archive.settings.index.settings.description = View and/or rebuild the current Search Index.
86+
archive.settings.index.settings.disabled = Full Text Search functionality has been disabled by configuration.
8687
archive.settings.current.index = Current Search Index
8788
archive.settings.current.index.description = The current size of the message index.
8889
archive.settings.message.count = Archived Message Count

src/i18n/monitoringservice_i18n.properties

+3-2
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,11 @@ system_property.conversation.maxTime=The max number of minutes a conversation ca
2222
system_property.conversation.messageArchiving=Enable archiving of one-to-one messages
2323
system_property.conversation.metadataArchiving=Enable archiving of conversation metadata
2424
system_property.conversation.roomArchiving=Enable archiving of MUC messages
25-
system_property.conversation.roomArchiving.PMinPersonalArchive=Controls whether MUC PMs are stored in the Personal Archive for the purposes of Message Arrchiving (XEP-0313)
26-
system_property.conversation.roomArchiving.PMinRoomArchive=Controls whether MUC PMs are stored in the Room Archive for the purposes of Message Arrchiving (XEP-0313)
25+
system_property.conversation.roomArchiving.PMinPersonalArchive=Controls whether MUC PMs are stored in the Personal Archive for the purposes of Message Archiving (XEP-0313)
26+
system_property.conversation.roomArchiving.PMinRoomArchive=Controls whether MUC PMs are stored in the Room Archive for the purposes of Message Archiving (XEP-0313)
2727
system_property.conversation.roomArchivingStanzas=Enable storing of full stanzas when MUC messages are archived
2828
system_property.conversation.roomsArchived=List of MUC rooms in which to archive messages. When empty, all rooms are archived.
29+
system_property.conversation.search.index-enabled=Controls if the full-text search index (Lucene) is enabled.
2930
system_property.conversation.search.updateInterval=How often, in minutes, to update the search index
3031
system_property.monitoring.search.allow-unrecognized-fields=If 'true', silently ignores unrecognized search filters in queries, which otherwise result in error responses.
3132
system_property.stats.mock.viewer=Displays random stats in Monitoring plugin admin pages

src/i18n/monitoringservice_i18n_nl.properties

+3-2
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,11 @@ system_property.conversation.maxTime=Het maximaal aantal minuten dat een convers
2222
system_property.conversation.messageArchiving=Schakel archivering van een-op-een berichten in
2323
system_property.conversation.metadataArchiving=Schakel archivering van metadata van gesprekken in
2424
system_property.conversation.roomArchiving=Schakel archivering van MUC-berichten in
25-
system_property.conversation.roomArchiving.PMinPersonalArchive=Bepaald of MUC PMs worden opgeslagen in het Persoonlijk Archief als onderdeel van Message Archiving (XEP-0313)
26-
system_property.conversation.roomArchiving.PMinRoomArchive=Bepaald of MUC PMs worden opgeslagen in het Gespreksruimte Archief als onderdeel van Message Archiving (XEP-0313)
25+
system_property.conversation.roomArchiving.PMinPersonalArchive=Bepaalt of MUC PMs worden opgeslagen in het Persoonlijk Archief als onderdeel van Message Archiving (XEP-0313)
26+
system_property.conversation.roomArchiving.PMinRoomArchive=Bepaalt of MUC PMs worden opgeslagen in het Gespreksruimte Archief als onderdeel van Message Archiving (XEP-0313)
2727
system_property.conversation.roomArchivingStanzas=Schakel het opslaan van volledige stanzas in voor MUC berichten
2828
system_property.conversation.roomsArchived=Lijst van MUC ruimtes waar berichten voor worden gearchiveerd. Indien leeg, dan worden berichten van alle ruimtes gearchiveerd.
29+
system_property.conversation.search.index-enabled=Bepaalt of de full-text zoekindex (Lucene) actief is.
2930
system_property.conversation.search.updateInterval=Hoe vaak, in minuten, de zoekindex wordt bijgewerkt
3031
system_property.monitoring.search.allow-unrecognized-fields=Als 'true' dan worden niet herkende zoekfilters genegeerd in plaats van beantwoord met een foutmelding.
3132
system_property.stats.mock.viewer=Toon willekeurige statistieken in de administratiepagina's van de Monitoring plugin

src/java/com/reucon/openfire/plugin/archive/impl/JdbcPersistenceManager.java

+7
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import org.dom4j.DocumentException;
1010
import org.jivesoftware.database.DbConnectionManager;
1111
import org.jivesoftware.openfire.archive.ConversationManager;
12+
import org.jivesoftware.openfire.index.LuceneIndexer;
1213
import org.slf4j.Logger;
1314
import org.slf4j.LoggerFactory;
1415
import org.xmpp.packet.JID;
@@ -320,6 +321,9 @@ public Collection<ArchivedMessage> findMessages(Date startDate, Date endDate, JI
320321
List<ArchivedMessage> msgs = Collections.emptyList();
321322
int totalCount = 0;
322323
if ( query != null && !query.isEmpty() ) {
324+
if (!LuceneIndexer.ENABLED.getValue()) {
325+
throw new DataRetrievalException("Unable to process a search request that contains a text-based query, as the full-text index functionality has been disabled by configuration.");
326+
}
323327
final PaginatedMessageLuceneQuery paginatedMessageLuceneQuery = new PaginatedMessageLuceneQuery( startDate, endDate, owner, with, query );
324328
Log.debug("Request for message archive of user '{}' resulted in the following query data: {}", owner, paginatedMessageLuceneQuery);
325329
totalCount = paginatedMessageLuceneQuery.getTotalCount();
@@ -377,6 +381,9 @@ public Collection<ArchivedMessage> findMessages(Date startDate, Date endDate, JI
377381
final List<ArchivedMessage> nextPage;
378382
if ( query != null && !query.isEmpty() )
379383
{
384+
if (!LuceneIndexer.ENABLED.getValue()) {
385+
throw new DataRetrievalException("Unable to process a search request that contains a text-based query, as the full-text index functionality has been disabled by configuration.");
386+
}
380387
final PaginatedMessageLuceneQuery paginatedMessageLuceneQuery = new PaginatedMessageLuceneQuery(startDate, endDate, owner, with, query);
381388
nextPage = paginatedMessageLuceneQuery.getPage(afterForNextPage, beforeForNextPage, 1, isPagingBackwards);
382389
}

src/java/com/reucon/openfire/plugin/archive/impl/MucMamPersistenceManager.java

+7
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import org.jivesoftware.database.DbConnectionManager;
1212
import org.jivesoftware.openfire.XMPPServer;
1313
import org.jivesoftware.openfire.archive.MonitoringConstants;
14+
import org.jivesoftware.openfire.index.LuceneIndexer;
1415
import org.jivesoftware.openfire.muc.MUCRoom;
1516
import org.jivesoftware.openfire.muc.MultiUserChatManager;
1617
import org.jivesoftware.openfire.muc.MultiUserChatService;
@@ -80,6 +81,9 @@ public Collection<ArchivedMessage> findMessages(Date startDate, Date endDate, JI
8081
final List<ArchivedMessage> msgs;
8182
final int totalCount;
8283
if ( query != null && !query.isEmpty() ) {
84+
if (!LuceneIndexer.ENABLED.getValue()) {
85+
throw new DataRetrievalException("Unable to process a search request that contains a text-based query, as the full-text index functionality has been disabled by configuration.");
86+
}
8387
// When there's a 'query' element, the search needs to go through a Lucene index (which takes care of text-search).
8488
if (USE_OPENFIRE_TABLES.getValue()) {
8589
Log.debug("Using Openfire tables");
@@ -165,6 +169,9 @@ public Collection<ArchivedMessage> findMessages(Date startDate, Date endDate, JI
165169
final List<ArchivedMessage> nextPage;
166170
if ( query != null && !query.isEmpty() )
167171
{
172+
if (!LuceneIndexer.ENABLED.getValue()) {
173+
throw new DataRetrievalException("Unable to process a search request that contains a text-based query, as the full-text index functionality has been disabled by configuration.");
174+
}
168175
final PaginatedMucMessageFromOpenfireLuceneQuery paginatedMucMessageLuceneQuery = new PaginatedMucMessageFromOpenfireLuceneQuery(startDate, endDate, room, with, query);
169176
nextPage = paginatedMucMessageLuceneQuery.getPage(afterForNextPage, beforeForNextPage, 1, isPagingBackwards);
170177
}

src/java/com/reucon/openfire/plugin/archive/xep0313/IQQueryHandler.java

+14-3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import org.jivesoftware.openfire.container.Plugin;
1616
import org.jivesoftware.openfire.disco.ServerFeaturesProvider;
1717
import org.jivesoftware.openfire.forward.Forwarded;
18+
import org.jivesoftware.openfire.index.LuceneIndexer;
1819
import org.jivesoftware.openfire.muc.MUCRole;
1920
import org.jivesoftware.openfire.muc.MUCRoom;
2021
import org.jivesoftware.openfire.muc.MultiUserChatService;
@@ -602,7 +603,9 @@ private IQ buildSupportedFieldsResult(IQ packet) {
602603
form.addField("with", "Author of message", FormField.Type.jid_single);
603604
form.addField("start", "Message sent on or after timestamp.", FormField.Type.text_single);
604605
form.addField("end", "Message sent on or before timestamp.", FormField.Type.text_single);
605-
form.addField("{urn:xmpp:fulltext:0}fulltext", "Free text search", FormField.Type.text_single);
606+
if (LuceneIndexer.ENABLED.getValue()) {
607+
form.addField("{urn:xmpp:fulltext:0}fulltext", "Free text search", FormField.Type.text_single);
608+
}
606609

607610
query.add(form.getElement());
608611

@@ -617,14 +620,22 @@ private IQ buildSupportedFieldsResult(IQ packet) {
617620
* @return A list of fields. Never null.
618621
*/
619622
private List<String> getSupportedFieldVariables() {
620-
return Arrays.asList( "FORM_TYPE", "with", "start", "end", "{urn:xmpp:fulltext:0}fulltext", "withtext", "search");
623+
final List<String> results = Arrays.asList("FORM_TYPE", "with", "start", "end");
624+
if (LuceneIndexer.ENABLED.getValue()) {
625+
results.add("{urn:xmpp:fulltext:0}fulltext");
626+
results.add("withtext");
627+
results.add("search");
628+
}
629+
return results;
621630
}
622631

623632
@Override
624633
public Iterator<String> getFeatures() {
625634
final List<String> result = new ArrayList<>();
626635
result.add(NAMESPACE);
627-
result.add("urn:xmpp:fulltext:0");
636+
if (LuceneIndexer.ENABLED.getValue()) {
637+
result.add("urn:xmpp:fulltext:0");
638+
}
628639
return result.iterator();
629640
}
630641

src/java/org/jivesoftware/openfire/index/LuceneIndexer.java

+38-3
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,13 @@ public abstract class LuceneIndexer
7070
.setPlugin(MonitoringConstants.PLUGIN_NAME)
7171
.build();
7272

73+
public static final SystemProperty<Boolean> ENABLED = SystemProperty.Builder.ofType( Boolean.class )
74+
.setKey("conversation.search.index-enabled")
75+
.setDefaultValue(true)
76+
.setDynamic(false)
77+
.setPlugin(MonitoringConstants.PLUGIN_NAME)
78+
.build();
79+
7380
public LuceneIndexer(TaskEngine taskEngine, Path searchDir, String logName, int schemaVersion)
7481
{
7582
this.taskEngine = taskEngine;
@@ -80,7 +87,13 @@ public LuceneIndexer(TaskEngine taskEngine, Path searchDir, String logName, int
8087

8188
public void start()
8289
{
90+
if (!ENABLED.getValue()) {
91+
Log.debug("Unable to start: indexing is disabled by configuration.");
92+
return;
93+
}
94+
8395
Log.debug("Starting...");
96+
8497
if (!Files.exists(searchDir))
8598
{
8699
try {
@@ -231,7 +244,10 @@ public void stop()
231244
{
232245
Log.debug("Stopping...");
233246
stopped = true;
234-
indexUpdater.cancel();
247+
if (indexUpdater != null) {
248+
indexUpdater.cancel();
249+
indexUpdater = null;
250+
}
235251
if ( searcher != null )
236252
{
237253
try
@@ -246,13 +262,16 @@ public void stop()
246262
}
247263
try
248264
{
249-
directory.close();
265+
if (directory != null) {
266+
directory.close();
267+
}
250268
}
251269
catch ( Exception e )
252270
{
253271
Log.error(e.getMessage(), e);
254272
}
255273
directory = null;
274+
256275
indexProperties = null;
257276
searchDir = null;
258277
rebuildFuture = null;
@@ -287,6 +306,11 @@ public long getIndexSize()
287306
*/
288307
public void updateIndex()
289308
{
309+
if (!ENABLED.getValue()) {
310+
Log.debug("Unable to update: indexing is disabled by configuration.");
311+
return;
312+
}
313+
290314
// Immediately return if the service has been stopped.
291315
if (stopped) {
292316
return;
@@ -329,7 +353,13 @@ public void updateIndex()
329353
* @return a Future to indicate the status of rebuilding the index or <tt>null</tt> if
330354
* rebuilding the index is not possible.
331355
*/
332-
public synchronized Future<Integer> rebuildIndex() {
356+
public synchronized Future<Integer> rebuildIndex()
357+
{
358+
if (!ENABLED.getValue()) {
359+
Log.debug("Unable to rebuild: indexing is disabled by configuration.");
360+
return null;
361+
}
362+
333363
// Immediately return if the service has been stopped.
334364
if (stopped) {
335365
return null;
@@ -430,6 +460,11 @@ public Future<Integer> getIndexRebuildProgress()
430460
*/
431461
public synchronized IndexSearcher getSearcher() throws IOException
432462
{
463+
if (!ENABLED.getValue()) {
464+
Log.debug("Unable to get index: indexing is disabled by configuration.");
465+
return null;
466+
}
467+
433468
// If the searcher hasn't been instantiated, create it.
434469
if ( searcher == null )
435470
{

src/web/archive-search.jsp

+5-4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
<%@ page import="org.slf4j.LoggerFactory" %>
1313
<%@ page import="org.jivesoftware.openfire.archive.*" %>
1414
<%@ page import="org.jivesoftware.openfire.cluster.ClusterManager" %>
15+
<%@ page import="org.jivesoftware.openfire.index.LuceneIndexer" %>
1516

1617
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
1718
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
@@ -566,10 +567,9 @@
566567

567568

568569
</td>
569-
<td>
570-
<td width="0" height="100%" valign="middle">
571-
<div class="verticalrule"></div>
572-
</td>
570+
<% if (LuceneIndexer.ENABLED.getValue()) { %>
571+
<td width="0" height="100%" valign="middle">
572+
<div class="verticalrule"></div>
573573
</td>
574574
<td>
575575
<table>
@@ -593,6 +593,7 @@
593593
</tr>
594594
</table>
595595
</td>
596+
<% } %>
596597
</tr>
597598
</table>
598599
</div>

src/web/archiving-settings.jsp

+14-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
<%@ page import="com.reucon.openfire.plugin.archive.impl.MessageIndexer" %>
1717
<%@ page import="org.jivesoftware.openfire.archive.MonitoringConstants" %>
1818
<%@ page import="org.jivesoftware.openfire.cluster.ClusterManager" %>
19+
<%@ page import="org.jivesoftware.openfire.index.LuceneIndexer" %>
1920

2021
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
2122
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
@@ -38,6 +39,7 @@
3839
<title><fmt:message key="archive.settings.title"/></title>
3940
<meta name="pageID" content="archiving-settings"/>
4041
<link rel="stylesheet" type="text/css" href="style/style.css">
42+
<% if (LuceneIndexer.ENABLED.getValue()) { %>
4143
<script type="text/javascript">
4244
// Calls a getBuildProgress
4345
function getBuildProgress() {
@@ -70,6 +72,7 @@
7072
7173
//# sourceURL=archiving-settings.jsp
7274
</script>
75+
<% } %>
7376
<style type="text/css">
7477
.small-label {
7578
font-size: 11px;
@@ -483,6 +486,7 @@
483486
</tr>
484487
</thead>
485488
<tbody>
489+
<% if (LuceneIndexer.ENABLED.getValue()) { %>
486490
<tr>
487491
<td colspan="3" width="100%"><p><fmt:message key="archive.settings.index.settings.description"/></p></td>
488492
</tr>
@@ -507,18 +511,26 @@
507511
<% } %>
508512
<td></td>
509513
</tr>
514+
<% } else { %>
515+
<tr>
516+
<td colspan="3" width="100%"><p><fmt:message key="archive.settings.index.settings.disabled"/></p></td>
517+
</tr>
518+
<% } %>
510519
</tbody>
511520
</table>
512521

522+
<% if (LuceneIndexer.ENABLED.getValue()) { %>
513523
<input type="submit" name="rebuild" value="<fmt:message key="archive.settings.rebuild" />"/>
514524
<span id="rebuildElement" style="display:none;" class="jive-description">Rebuilding is <span id="rebuildProgress"></span>% complete.</span>
515-
516-
<%} %>
525+
<% } %>
526+
<% } %>
517527
</form>
518528

529+
<% if (LuceneIndexer.ENABLED.getValue()) { %>
519530
<script type="text/javascript">
520531
getBuildProgress();
521532
</script>
533+
<% } %>
522534

523535
</body>
524536
</html>

0 commit comments

Comments
 (0)