From bdb876552dc35a7a20442505aa81dcd803353a0a Mon Sep 17 00:00:00 2001 From: Torsten Grote <t@grobox.de> Date: Fri, 29 Jul 2016 15:17:18 -0300 Subject: [PATCH] Allow Validator to access metadata for pending messages Database queries for metadata only returned it for messages that were delivered already. However, there are cases (e.g. a pending message needs to be delivered) where the validator needs to retrieve the metadata from the database. For these cases, a special database query has been introduced. --- .../api/db/DatabaseComponent.java | 13 +++++++-- .../clients/BdfIncomingMessageHook.java | 1 - .../src/org/briarproject/db/Database.java | 10 ++++++- .../db/DatabaseComponentImpl.java | 9 +++++++ .../src/org/briarproject/db/JdbcDatabase.java | 27 +++++++++++++++++++ .../sync/ValidationManagerImpl.java | 2 +- .../org/briarproject/db/H2DatabaseTest.java | 4 +++ 7 files changed, 61 insertions(+), 5 deletions(-) diff --git a/briar-api/src/org/briarproject/api/db/DatabaseComponent.java b/briar-api/src/org/briarproject/api/db/DatabaseComponent.java index 123d8e4b16..3f123566f7 100644 --- a/briar-api/src/org/briarproject/api/db/DatabaseComponent.java +++ b/briar-api/src/org/briarproject/api/db/DatabaseComponent.java @@ -262,7 +262,7 @@ public interface DatabaseComponent { byte[] getRawMessage(Transaction txn, MessageId m) throws DbException; /** - * Returns the metadata for all messages in the given group. + * Returns the metadata for all delivered messages in the given group. * <p/> * Read-only. */ @@ -280,13 +280,22 @@ public interface DatabaseComponent { Metadata query) throws DbException; /** - * Returns the metadata for the given message. + * Returns the metadata for the given delivered message. * <p/> * Read-only. */ Metadata getMessageMetadata(Transaction txn, MessageId m) throws DbException; + /** + * Returns the metadata for the given delivered and pending message. + * This is meant to be only used by the ValidationManager + * <p/> + * Read-only. + */ + Metadata getMessageMetadataForValidator(Transaction txn, MessageId m) + throws DbException; + /** * Returns the status of all messages in the given group with respect to * the given contact. diff --git a/briar-core/src/org/briarproject/clients/BdfIncomingMessageHook.java b/briar-core/src/org/briarproject/clients/BdfIncomingMessageHook.java index e8d0b5e2f7..f8211623d2 100644 --- a/briar-core/src/org/briarproject/clients/BdfIncomingMessageHook.java +++ b/briar-core/src/org/briarproject/clients/BdfIncomingMessageHook.java @@ -12,7 +12,6 @@ import org.briarproject.api.db.Metadata; import org.briarproject.api.db.Transaction; import org.briarproject.api.sync.Message; import org.briarproject.api.sync.ValidationManager.IncomingMessageHook; -import org.briarproject.api.system.Clock; import static org.briarproject.api.clients.QueueMessage.QUEUE_MESSAGE_HEADER_LENGTH; import static org.briarproject.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH; diff --git a/briar-core/src/org/briarproject/db/Database.java b/briar-core/src/org/briarproject/db/Database.java index 9779217904..a63f411cbb 100644 --- a/briar-core/src/org/briarproject/db/Database.java +++ b/briar-core/src/org/briarproject/db/Database.java @@ -310,7 +310,7 @@ interface Database<T> { throws DbException; /** - * Returns the metadata for all messages in the given group. + * Returns the metadata for all delivered messages in the given group. * <p/> * Read-only. */ @@ -327,6 +327,14 @@ interface Database<T> { Map<MessageId, Metadata> getMessageMetadata(T txn, GroupId g, Metadata query) throws DbException; + /** + * Returns the metadata for the given delivered message. + * <p/> + * Read-only. + */ + Metadata getMessageMetadataForValidator(T txn, MessageId m) + throws DbException; + /** * Returns the metadata for the given message. * <p/> diff --git a/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java b/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java index 4f84a04bd0..f8eabd84c6 100644 --- a/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java +++ b/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java @@ -456,6 +456,15 @@ class DatabaseComponentImpl<T> implements DatabaseComponent { return db.getMessageMetadata(txn, m); } + public Metadata getMessageMetadataForValidator(Transaction transaction, + MessageId m) + throws DbException { + T txn = unbox(transaction); + if (!db.containsMessage(txn, m)) + throw new NoSuchMessageException(); + return db.getMessageMetadataForValidator(txn, m); + } + public Collection<MessageStatus> getMessageStatus(Transaction transaction, ContactId c, GroupId g) throws DbException { T txn = unbox(transaction); diff --git a/briar-core/src/org/briarproject/db/JdbcDatabase.java b/briar-core/src/org/briarproject/db/JdbcDatabase.java index a52fbe2a1d..363075dfd6 100644 --- a/briar-core/src/org/briarproject/db/JdbcDatabase.java +++ b/briar-core/src/org/briarproject/db/JdbcDatabase.java @@ -1324,6 +1324,33 @@ abstract class JdbcDatabase implements Database<Connection> { } } + public Metadata getMessageMetadataForValidator(Connection txn, MessageId m) + throws DbException { + PreparedStatement ps = null; + ResultSet rs = null; + try { + String sql = "SELECT key, value FROM messageMetadata AS md" + + " JOIN messages AS m" + + " ON m.messageId = md.messageId" + + " WHERE (m.state = ? OR m.state = ?)" + + " AND md.messageId = ?"; + ps = txn.prepareStatement(sql); + ps.setInt(1, DELIVERED.getValue()); + ps.setInt(2, PENDING.getValue()); + ps.setBytes(3, m.getBytes()); + rs = ps.executeQuery(); + Metadata metadata = new Metadata(); + while (rs.next()) metadata.put(rs.getString(1), rs.getBytes(2)); + rs.close(); + ps.close(); + return metadata; + } catch (SQLException e) { + tryToClose(rs); + tryToClose(ps); + throw new DbException(e); + } + } + public Collection<MessageStatus> getMessageStatus(Connection txn, ContactId c, GroupId g) throws DbException { PreparedStatement ps = null; diff --git a/briar-core/src/org/briarproject/sync/ValidationManagerImpl.java b/briar-core/src/org/briarproject/sync/ValidationManagerImpl.java index f6aa74c3ab..7853f0497d 100644 --- a/briar-core/src/org/briarproject/sync/ValidationManagerImpl.java +++ b/briar-core/src/org/briarproject/sync/ValidationManagerImpl.java @@ -188,7 +188,7 @@ class ValidationManagerImpl implements ValidationManager, Service, byte[] raw = db.getRawMessage(txn, id); m = parseMessage(id, raw); g = db.getGroup(txn, m.getGroupId()); - meta = db.getMessageMetadata(txn, id); + meta = db.getMessageMetadataForValidator(txn, id); txn.setComplete(); } finally { db.endTransaction(txn); diff --git a/briar-tests/src/org/briarproject/db/H2DatabaseTest.java b/briar-tests/src/org/briarproject/db/H2DatabaseTest.java index dbf48a82fd..f50dcb2bcb 100644 --- a/briar-tests/src/org/briarproject/db/H2DatabaseTest.java +++ b/briar-tests/src/org/briarproject/db/H2DatabaseTest.java @@ -1006,6 +1006,10 @@ public class H2DatabaseTest extends BriarTestCase { map = db.getMessageMetadata(txn, groupId); assertTrue(map.isEmpty()); + // validator gets also metadata for pending messages + retrieved = db.getMessageMetadataForValidator(txn, messageId); + assertFalse(retrieved.isEmpty()); + db.commitTransaction(txn); db.close(); } -- GitLab