Skip to content

Commit be1a9d2

Browse files
authored
Merge pull request #144 from guusdk/tmp_refactoring-mam-query
Adding support for private MUC messages to MAM
2 parents 8cd75b6 + ebc37a4 commit be1a9d2

37 files changed

+1466
-618
lines changed

changelog.html

+7
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,17 @@ <h1>
4848
<ul>
4949
<li>[<a href='https://issues.igniterealtime.org/browse/OF-2157'>OF-2157</a>] - SequenceManager generated IDs are unreliable whilst clustering.</li>
5050
<li>[<a href='https://github.com/igniterealtime/openfire-monitoring-plugin/issues/19'>Issue #19</a>] - Monitoring / Archive plugin fails to reconstruct archived stanza</li>
51+
<li>[<a href='https://github.com/igniterealtime/openfire-monitoring-plugin/issues/133'>Issue #133</a>] - Allow PMs to be returned when querying MUC archives</li>
5152
<li>[<a href='https://github.com/igniterealtime/openfire-monitoring-plugin/issues/137'>Issue #137</a>] - MUC messages duplicated as one-on-one messages</li>
5253
<li>[<a href='https://github.com/igniterealtime/openfire-monitoring-plugin/issues/138'>Issue #138</a>] - Stanzas not always stored for one-to-one messages whilst clustered</li>
5354
<li>[<a href='https://github.com/igniterealtime/openfire-monitoring-plugin/issues/139'>Issue #139</a>] - Reduce code complexity</li>
5455
<li>[<a href='https://github.com/igniterealtime/openfire-monitoring-plugin/issues/141'>Issue #141</a>] - Make Archiver configuration configurable</li>
56+
<li>[<a href='https://github.com/igniterealtime/openfire-monitoring-plugin/issues/142'>Issue #142</a>] - Do not require plugin restart after config change</li>
57+
<li>[<a href='https://github.com/igniterealtime/openfire-monitoring-plugin/issues/145'>Issue #145</a>] - Replace deprecated API usage</li>
58+
<li>[<a href='https://github.com/igniterealtime/openfire-monitoring-plugin/issues/146'>Issue #146</a>] - Allow database used for MUC MAM to be configurable</li>
59+
<li>[<a href='https://github.com/igniterealtime/openfire-monitoring-plugin/issues/147'>Issue #147</a>] - Allow how MUC PMs are stored to be configurable</li>
60+
<li>[<a href='https://github.com/igniterealtime/openfire-monitoring-plugin/issues/148'>Issue #148</a>] - Database errors should cause an XMPP error</li>
61+
<li>[<a href='https://github.com/igniterealtime/openfire-monitoring-plugin/issues/152'>Issue #152</a>] - Update iText library to 7.1.13</li>
5562
</ul>
5663

5764
<p><b>2.1.0</b> -- September 10, 2020</p>

plugin.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<minServerVersion>4.4.0</minServerVersion>
1111
<minJavaVersion>1.8</minJavaVersion>
1212
<databaseKey>monitoring</databaseKey>
13-
<databaseVersion>6</databaseVersion>
13+
<databaseVersion>7</databaseVersion>
1414

1515
<adminconsole>
1616
<tab id="tab-server">

pom.xml

+9-4
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,15 @@
7979
<version>8.4.0</version>
8080
</dependency>
8181
<dependency>
82-
<groupId>com.lowagie</groupId>
83-
<artifactId>itext</artifactId>
84-
<!-- NB. Later versions are available at com.itextpdf:itextpdf but require code changes -->
85-
<version>2.0.8</version>
82+
<groupId>com.itextpdf</groupId>
83+
<artifactId>itext7-core</artifactId>
84+
<version>7.1.13</version>
85+
<type>pom</type>
86+
</dependency>
87+
<dependency>
88+
<groupId>com.orsonpdf</groupId>
89+
<artifactId>orsonpdf</artifactId>
90+
<version>1.7</version>
8691
</dependency>
8792
<dependency>
8893
<groupId>org.picocontainer</groupId>

src/database/monitoring_db2.sql

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
INSERT INTO ofVersion (name, version) VALUES ('monitoring', 6);
2+
INSERT INTO ofVersion (name, version) VALUES ('monitoring', 7);
33

44
CREATE TABLE ofConversation (
55
conversationID INTEGER NOT NULL,
@@ -34,17 +34,19 @@ CREATE TABLE ofMessageArchive (
3434
toJIDResource VARCHAR(255) NULL,
3535
sentDate BIGINT NOT NULL,
3636
stanza LONG VARCHAR NULL,
37-
body LONG VARCHAR
37+
body LONG VARCHAR NULL,
38+
isPMforJID VARCHAR(1024) NULL
3839
);
3940
CREATE INDEX ofMessageArchive_con_idx ON ofMessageArchive (conversationID);
4041
CREATE INDEX ofMessageArchive_fromjid_idx ON ofMessageArchive (fromJID);
4142
CREATE INDEX ofMessageArchive_tojid_idx ON ofMessageArchive (toJID);
4243
CREATE INDEX ofMessageArchive_sent_idx ON ofMessageArchive (sentDate);
44+
CREATE INDEX ofMessageArchive_pm_idx ON ofMessageArchive (isPMforJID);
4345

4446
CREATE TABLE ofRRDs (
4547
id VARCHAR(100) NOT NULL,
46-
updatedDate BIGINT NOT NULL,
47-
bytes BLOB,
48+
updatedDate BIGINT NOT NULL,
49+
bytes BLOB NULL,
4850
CONSTRAINT ofRRDs_pk PRIMARY KEY (id)
4951
);
5052

src/database/monitoring_hsqldb.sql

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
INSERT INTO ofVersion (name, version) VALUES ('monitoring', 6);
2+
INSERT INTO ofVersion (name, version) VALUES ('monitoring', 7);
33

44
CREATE TABLE ofConversation (
55
conversationID BIGINT NOT NULL,
@@ -34,17 +34,19 @@ CREATE TABLE ofMessageArchive (
3434
toJIDResource VARCHAR(255) NULL,
3535
sentDate BIGINT NOT NULL,
3636
stanza LONGVARCHAR NULL,
37-
body LONGVARCHAR
37+
body LONGVARCHAR NULL,
38+
isPMforJID VARCHAR(1024) NULL
3839
);
3940
CREATE INDEX ofMessageArchive_con_idx ON ofMessageArchive (conversationID);
4041
CREATE INDEX ofMessageArchive_fromjid_idx ON ofMessageArchive (fromJID);
4142
CREATE INDEX ofMessageArchive_tojid_idx ON ofMessageArchive (toJID);
4243
CREATE INDEX ofMessageArchive_sent_idx ON ofMessageArchive (sentDate);
44+
CREATE INDEX ofMessageArchive_pm_idx ON ofMessageArchive (isPMforJID);
4345

4446
CREATE TABLE ofRRDs (
4547
id VARCHAR(100) NOT NULL,
4648
updatedDate BIGINT NOT NULL,
47-
bytes BLOB NULL,
49+
bytes BLOB NULL,
4850
CONSTRAINT ofRRDs_pk PRIMARY KEY (id)
4951
);
5052

src/database/monitoring_mysql.sql

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
INSERT INTO ofVersion (name, version) VALUES ('monitoring', 6);
2+
INSERT INTO ofVersion (name, version) VALUES ('monitoring', 7);
33

44
CREATE TABLE ofConversation (
55
conversationID BIGINT NOT NULL,
@@ -34,11 +34,13 @@ CREATE TABLE ofMessageArchive (
3434
toJIDResource VARCHAR(100) NULL,
3535
sentDate BIGINT NOT NULL,
3636
stanza TEXT NULL,
37-
body TEXT,
37+
body TEXT NULL,
38+
isPMforJID VARCHAR(255) NOT NULL,
3839
INDEX ofMessageArchive_con_idx (conversationID),
3940
INDEX ofMessageArchive_fromjid_idx (fromJID),
4041
INDEX ofMessageArchive_tojid_idx (toJID),
41-
INDEX ofMessageArchive_sent_idx (sentDate)
42+
INDEX ofMessageArchive_sent_idx (sentDate),
43+
INDEX ofMessageArchive_pm_idx (isPMforJID)
4244
);
4345

4446
CREATE TABLE ofRRDs (

src/database/monitoring_oracle.sql

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
INSERT INTO ofVersion (name, version) VALUES ('monitoring', 6);
2+
INSERT INTO ofVersion (name, version) VALUES ('monitoring', 7);
33

44
CREATE TABLE ofConversation (
55
conversationID INTEGER NOT NULL,
@@ -34,12 +34,14 @@ CREATE TABLE ofMessageArchive (
3434
toJIDResource VARCHAR2(255) NULL,
3535
sentDate INTEGER NOT NULL,
3636
stanza CLOB NULL,
37-
body CLOB
37+
body CLOB NULL,
38+
isPMforJID VARCHAR2(1024) NULL
3839
);
3940
CREATE INDEX ofMessageArchive_con_idx ON ofMessageArchive (conversationID);
4041
CREATE INDEX ofMessageArchive_fromjid_idx ON ofMessageArchive (fromJID);
4142
CREATE INDEX ofMessageArchive_tojid_idx ON ofMessageArchive (toJID);
4243
CREATE INDEX ofMessageArchive_sent_idx ON ofMessageArchive (sentDate);
44+
CREATE INDEX ofMessageArchive_pm_idx ON ofMessageArchive (isPMforJID);
4345

4446
CREATE TABLE ofRRDs (
4547
id VARCHAR2(100) NOT NULL,

src/database/monitoring_postgresql.sql

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
INSERT INTO ofVersion (name, version) VALUES ('monitoring', 6);
2+
INSERT INTO ofVersion (name, version) VALUES ('monitoring', 7);
33

44
CREATE TABLE ofConversation (
55
conversationID INTEGER NOT NULL,
@@ -34,12 +34,14 @@ CREATE TABLE ofMessageArchive (
3434
toJIDResource VARCHAR(1024) NULL,
3535
sentDate BIGINT NOT NULL,
3636
stanza TEXT NULL,
37-
body TEXT
37+
body TEXT NULL,
38+
isPMforJID VARCHAR(1024) NULL
3839
);
3940
CREATE INDEX ofMessageArchive_con_idx ON ofMessageArchive (conversationID);
4041
CREATE INDEX ofMessageArchive_fromjid_idx ON ofMessageArchive (fromJID);
4142
CREATE INDEX ofMessageArchive_tojid_idx ON ofMessageArchive (toJID);
4243
CREATE INDEX ofMessageArchive_sent_idx ON ofMessageArchive (sentDate);
44+
CREATE INDEX ofMessageArchive_pm_idx ON ofMessageArchive (isPMforJID);
4345

4446
CREATE TABLE ofRRDs (
4547
id VARCHAR(100) NOT NULL,

src/database/monitoring_sqlserver.sql

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
INSERT INTO ofVersion (name, version) VALUES ('monitoring', 6);
2+
INSERT INTO ofVersion (name, version) VALUES ('monitoring', 7);
33

44
CREATE TABLE ofConversation (
55
conversationID BIGINT NOT NULL,
@@ -34,12 +34,14 @@ CREATE TABLE ofMessageArchive (
3434
toJIDResource NVARCHAR(1024) NULL,
3535
sentDate BIGINT NOT NULL,
3636
stanza NVARCHAR(MAX) NULL,
37-
body NVARCHAR(MAX)
37+
body NVARCHAR(MAX) NULL,
38+
isPMforJID NVARCHAR(1024) NULL
3839
);
3940
CREATE INDEX ofMessageArchive_con_idx ON ofMessageArchive (conversationID);
4041
CREATE INDEX ofMessageArchive_fromjid_idx ON ofMessageArchive (fromJID);
4142
CREATE INDEX ofMessageArchive_tojid_idx ON ofMessageArchive (toJID);
4243
CREATE INDEX ofMessageArchive_sent_idx ON ofMessageArchive (sentDate);
44+
CREATE INDEX ofMessageArchive_pm_idx ON ofMessageArchive (isPMforJID);
4345

4446
CREATE TABLE ofRRDs (
4547
id NVARCHAR(100) NOT NULL,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
ALTER TABLE ofMessageArchive ADD COLUMN isPMforJID VARCHAR(1024) NULL;
2+
CREATE INDEX ofMessageArchive_pm_idx ON ofMessageArchive (isPMforJID);
3+
4+
-- Update database version
5+
UPDATE ofVersion SET version = 7 WHERE name = 'monitoring';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
ALTER TABLE ofMessageArchive ADD COLUMN isPMforJID VARCHAR(1024) NULL;
2+
CREATE INDEX ofMessageArchive_pm_idx ON ofMessageArchive (isPMforJID);
3+
4+
-- Update database version
5+
UPDATE ofVersion SET version = 7 WHERE name = 'monitoring';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
ALTER TABLE ofMessageArchive ADD COLUMN isPMforJID VARCHAR(255) NULL;
2+
ALTER TABLE ofMessageArchive ADD INDEX ofMessageArchive_pm_idx (isPMforJID);
3+
4+
-- Update database version
5+
UPDATE ofVersion SET version = 7 WHERE name = 'monitoring';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
ALTER TABLE ofMessageArchive ADD isPMforJID VARCHAR2(1024) NULL;
2+
CREATE INDEX ofMessageArchive_pm_idx ON ofMessageArchive (isPMforJID);
3+
4+
-- Update database version
5+
UPDATE ofVersion SET version = 7 WHERE name = 'monitoring';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
ALTER TABLE ofMessageArchive ADD COLUMN isPMforJID VARCHAR(1024) NULL;
2+
CREATE INDEX ofMessageArchive_pm_idx ON ofMessageArchive (isPMforJID);
3+
4+
-- Update database version
5+
UPDATE ofVersion SET version = 7 WHERE name = 'monitoring';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
ALTER TABLE ofMessageArchive ADD isPMforJID NVARCHAR(1024) NULL;
2+
CREATE INDEX ofMessageArchive_pm_idx ON ofMessageArchive (isPMforJID);
3+
4+
-- Update database version
5+
UPDATE ofVersion SET version = 7 WHERE name = 'monitoring';

src/java/com/reucon/openfire/plugin/archive/PersistenceManager.java

+10-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.reucon.openfire.plugin.archive;
22

3+
import com.reucon.openfire.plugin.archive.impl.DataRetrievalException;
34
import com.reucon.openfire.plugin.archive.model.ArchivedMessage;
45
import com.reucon.openfire.plugin.archive.model.Conversation;
56
import com.reucon.openfire.plugin.archive.xep0059.XmppResultSet;
@@ -29,16 +30,17 @@ public interface PersistenceManager
2930
/**
3031
* Searches for messages.
3132
*
32-
* @param startDate earliest start date of the message to find or <code>null</code> for any.
33-
* @param endDate latest end date of the message to find or <code>null</code> for any.
34-
* @param owner bare jid of the owner of the message to find or <code>null</code> for any.
35-
* @param with jid of the communication partner or <code>null</code> for any. This is either
36-
* the jid of another XMPP user or the jid of a group chat.
37-
* @param query A query string, typically representing keywords or a partial text, or <code>null</code>.
38-
* @param useStableID true if MAM2 or another protocol is used that depends on XEP-0359.
33+
* @param startDate earliest start date of the message to find or <code>null</code> for any.
34+
* @param endDate latest end date of the message to find or <code>null</code> for any.
35+
* @param archiveOwner bare jid of the owner of the archive in which to find messages or <code>null</code> for any.
36+
* @param messageOwner bare jid of the owner of the message to find or <code>null</code> for any.
37+
* @param with jid of the communication partner or <code>null</code> for any. This is either
38+
* the jid of another XMPP user or the jid of a group chat.
39+
* @param query A query string, typically representing keywords or a partial text, or <code>null</code>.
40+
* @param useStableID true if MAM2 or another protocol is used that depends on XEP-0359.
3941
* @return the messages that matched search criteria (possibly empty, never null).
4042
*/
41-
Collection<ArchivedMessage> findMessages( Date startDate, Date endDate, JID owner, JID with, String query, XmppResultSet xmppResultSet, boolean useStableID) throws NotFoundException;
43+
Collection<ArchivedMessage> findMessages( Date startDate, Date endDate, JID archiveOwner, JID messageOwner, JID with, String query, XmppResultSet xmppResultSet, boolean useStableID) throws NotFoundException, DataRetrievalException;
4244

4345
/**
4446
* Returns the conversation with the given owner, with and start time including participants and messages.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright (C) 2020 Ignite Realtime Foundation. All rights reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.reucon.openfire.plugin.archive.impl;
17+
18+
/**
19+
* Used when data could not be retrieved from persistent storage.
20+
*/
21+
public class DataRetrievalException extends Exception
22+
{
23+
public DataRetrievalException() {
24+
super();
25+
}
26+
27+
public DataRetrievalException(String message) {
28+
super(message);
29+
}
30+
31+
public DataRetrievalException(String message, Throwable cause) {
32+
super(message, cause);
33+
}
34+
35+
public DataRetrievalException(Throwable cause) {
36+
super(cause);
37+
}
38+
39+
protected DataRetrievalException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
40+
super(message, cause, enableSuppression, writableStackTrace);
41+
}
42+
}

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

+9-10
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import com.reucon.openfire.plugin.archive.model.ArchivedMessage.Direction;
66
import com.reucon.openfire.plugin.archive.model.Conversation;
77
import com.reucon.openfire.plugin.archive.model.Participant;
8-
import com.reucon.openfire.plugin.archive.util.StanzaIDUtil;
98
import com.reucon.openfire.plugin.archive.xep0059.XmppResultSet;
109
import org.dom4j.*;
1110
import org.jivesoftware.database.DbConnectionManager;
@@ -15,7 +14,6 @@
1514
import org.slf4j.Logger;
1615
import org.slf4j.LoggerFactory;
1716
import org.xmpp.packet.JID;
18-
import org.xmpp.packet.Message;
1917

2018
import java.sql.Connection;
2119
import java.sql.PreparedStatement;
@@ -24,7 +22,7 @@
2422
import java.util.*;
2523

2624
/**
27-
* Manages database persistence.
25+
* Manages database interactions to work with 'personal archives' for messages.
2826
*/
2927
public class JdbcPersistenceManager implements PersistenceManager {
3028
private static final Logger Log = LoggerFactory.getLogger( JdbcPersistenceManager.class );
@@ -277,8 +275,10 @@ private int bindConversationParameters(Date startDate, Date endDate, JID owner,
277275
}
278276

279277
@Override
280-
public Collection<ArchivedMessage> findMessages(Date startDate, Date endDate, JID owner, JID with, String query, XmppResultSet xmppResultSet, boolean useStableID) {
281-
278+
public Collection<ArchivedMessage> findMessages(Date startDate, Date endDate, JID owner, JID messageOwner, JID with, String query, XmppResultSet xmppResultSet, boolean useStableID) throws DataRetrievalException {
279+
if ( !owner.equals(messageOwner)) {
280+
throw new IllegalArgumentException("A personal archive can't be queried for messages of a different owner than the archive. Supplied archive owner: " + owner + ", supplied message owner: " + messageOwner);
281+
}
282282
Log.debug( "Finding messages of owner '{}' with start date '{}', end date '{}' with '{}' and resultset '{}', useStableId '{}'.", owner, startDate, endDate, with, xmppResultSet, useStableID );
283283

284284
if (startDate == null) {
@@ -467,7 +467,7 @@ public Conversation getConversation(JID owner, JID with, Date start) {
467467
while (rs.next()) {
468468
ArchivedMessage message;
469469

470-
message = extractMessage(rs);
470+
message = extractMessage(owner, rs);
471471
conversation.addMessage(message);
472472
}
473473
} catch (SQLException | DocumentException sqle) {
@@ -538,18 +538,17 @@ private Collection<Participant> extractParticipant(ResultSet rs) throws SQLExcep
538538
return participants;
539539
}
540540

541-
static ArchivedMessage extractMessage(ResultSet rs) throws SQLException, DocumentException {
541+
static ArchivedMessage extractMessage(final JID owner, ResultSet rs) throws SQLException, DocumentException {
542542
Date time = millisToDate(rs.getLong("sentDate"));
543543
String body = rs.getString("body");
544544
String stanza = rs.getString("stanza");
545-
String bareJid = rs.getString("bareJID");
546545
String fromJid = rs.getString("fromJID");
547546
String fromJIDResource = rs.getString("fromJIDResource");
548547
String toJid = rs.getString("toJID");
549548
String toJIDResource = rs.getString("toJIDResource");
550549
Long id = rs.getLong( "messageID" );
551550

552-
return asArchivedMessage( new JID(bareJid), fromJid, fromJIDResource, toJid, toJIDResource, time, body, stanza, id );
551+
return asArchivedMessage( owner, fromJid, fromJIDResource, toJid, toJIDResource, time, body, stanza, id );
553552
}
554553

555554
/**
@@ -566,7 +565,7 @@ public static ArchivedMessage getArchivedMessage( long messageId, JID owner )
566565
ResultSet rs = null;
567566
try {
568567
connection = DbConnectionManager.getConnection();
569-
final String query = "SELECT DISTINCT ofMessageArchive.fromJID, ofMessageArchive.fromJIDResource, ofMessageArchive.toJID, ofMessageArchive.toJIDResource, ofMessageArchive.sentDate, ofMessageArchive.body, ofMessageArchive.stanza, ofMessageArchive.messageID "
568+
final String query = "SELECT ofMessageArchive.fromJID, ofMessageArchive.fromJIDResource, ofMessageArchive.toJID, ofMessageArchive.toJIDResource, ofMessageArchive.sentDate, ofMessageArchive.body, ofMessageArchive.stanza, ofMessageArchive.messageID "
570569
+ "FROM ofMessageArchive "
571570
+ "INNER JOIN ofConParticipant ON ofMessageArchive.conversationID = ofConParticipant.conversationID "
572571
+ "WHERE (ofMessageArchive.stanza IS NOT NULL OR ofMessageArchive.body IS NOT NULL) "

0 commit comments

Comments
 (0)