Factor MessageTracker out of BdfIncomingMessageHook.

This commit is contained in:
akwizgran
2016-11-11 16:55:06 +00:00
parent ab16ee7465
commit aa210fc555
46 changed files with 628 additions and 379 deletions

View File

@@ -27,6 +27,7 @@ import org.briarproject.api.identity.Author.Status;
import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.Message;
@@ -69,6 +70,7 @@ import static org.briarproject.api.contact.ContactManager.AddContactHook;
import static org.briarproject.api.contact.ContactManager.RemoveContactHook;
import static org.briarproject.blogs.BlogPostValidator.authorToBdfDictionary;
@NotNullByDefault
class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
AddContactHook, RemoveContactHook, Client {
@@ -127,10 +129,8 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
@Override
public void removingContact(Transaction txn, Contact c) throws DbException {
if (c != null) {
Blog b = blogFactory.createBlog(c.getAuthor());
db.removeGroup(txn, b.getGroup());
}
Blog b = blogFactory.createBlog(c.getAuthor());
db.removeGroup(txn, b.getGroup());
}
@Override

View File

@@ -11,6 +11,7 @@ import org.briarproject.api.data.BdfEntry;
import org.briarproject.api.data.BdfList;
import org.briarproject.api.data.MetadataEncoder;
import org.briarproject.api.identity.Author;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.GroupFactory;
import org.briarproject.api.sync.InvalidMessageException;
@@ -42,6 +43,7 @@ import static org.briarproject.api.blogs.MessageType.COMMENT;
import static org.briarproject.api.blogs.MessageType.POST;
import static org.briarproject.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
@NotNullByDefault
class BlogPostValidator extends BdfMessageValidator {
private final GroupFactory groupFactory;
@@ -76,10 +78,10 @@ class BlogPostValidator extends BdfMessageValidator {
addMessageMetadata(c, m.getTimestamp());
break;
case WRAPPED_POST:
c = validateWrappedPost(m, g, body);
c = validateWrappedPost(body);
break;
case WRAPPED_COMMENT:
c = validateWrappedComment(m, g, body);
c = validateWrappedComment(body);
break;
default:
throw new InvalidMessageException("Unknown Message Type");
@@ -164,8 +166,8 @@ class BlogPostValidator extends BdfMessageValidator {
return new BdfMessageContext(meta, dependencies);
}
private BdfMessageContext validateWrappedPost(Message m, Group g,
BdfList body) throws InvalidMessageException, FormatException {
private BdfMessageContext validateWrappedPost(BdfList body)
throws InvalidMessageException, FormatException {
// p_group descriptor, p_timestamp, p_content, p_signature
checkSize(body, 4);
@@ -202,8 +204,8 @@ class BlogPostValidator extends BdfMessageValidator {
return new BdfMessageContext(meta);
}
private BdfMessageContext validateWrappedComment(Message m, Group g,
BdfList body) throws InvalidMessageException, FormatException {
private BdfMessageContext validateWrappedComment(BdfList body)
throws InvalidMessageException, FormatException {
// c_group descriptor, c_timestamp, c_comment, c_parent_original_id,
// c_parent_id, c_signature, parent_id

View File

@@ -3,31 +3,25 @@ package org.briarproject.clients;
import org.briarproject.api.FormatException;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.MessageQueueManager.IncomingQueueMessageHook;
import org.briarproject.api.clients.MessageTracker;
import org.briarproject.api.clients.QueueMessage;
import org.briarproject.api.data.BdfDictionary;
import org.briarproject.api.data.BdfEntry;
import org.briarproject.api.data.BdfList;
import org.briarproject.api.data.MetadataParser;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
import org.briarproject.api.db.Metadata;
import org.briarproject.api.db.Transaction;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.InvalidMessageException;
import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageId;
import org.briarproject.api.sync.ValidationManager.IncomingMessageHook;
import static org.briarproject.api.clients.QueueMessage.QUEUE_MESSAGE_HEADER_LENGTH;
import static org.briarproject.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
import static org.briarproject.clients.BdfConstants.GROUP_KEY_LATEST_MSG;
import static org.briarproject.clients.BdfConstants.GROUP_KEY_MSG_COUNT;
import static org.briarproject.clients.BdfConstants.GROUP_KEY_UNREAD_COUNT;
import static org.briarproject.clients.BdfConstants.MSG_KEY_READ;
@NotNullByDefault
public abstract class BdfIncomingMessageHook implements IncomingMessageHook,
IncomingQueueMessageHook, MessageTracker {
IncomingQueueMessageHook {
protected final DatabaseComponent db;
protected final ClientHelper clientHelper;
@@ -44,16 +38,16 @@ public abstract class BdfIncomingMessageHook implements IncomingMessageHook,
* Called once for each incoming message that passes validation.
*
* @throws DbException Should only be used for real database errors.
* Do not rethrow
* If this is thrown, delivery will be attempted again at next startup,
* whereas if a FormatException is thrown, the message will be permanently
* invalidated.
* @throws FormatException Use this for any non-database error
* that occurs while handling remotely created data.
* This includes errors that occur while handling locally created data
* in a context controlled by remotely created data
* (for example, parsing the metadata of a dependency
* of an incoming message).
* Throwing this will delete the incoming message and its metadata
* marking it as invalid in the database.
* Never rethrow DbException as FormatException
* Never rethrow DbException as FormatException!
*/
protected abstract boolean incomingMessage(Transaction txn, Message m,
BdfList body, BdfDictionary meta) throws DbException,
@@ -71,8 +65,12 @@ public abstract class BdfIncomingMessageHook implements IncomingMessageHook,
@Override
public void incomingMessage(Transaction txn, QueueMessage q, Metadata meta)
throws DbException, FormatException {
incomingMessage(txn, q, meta, QUEUE_MESSAGE_HEADER_LENGTH);
throws DbException, InvalidMessageException {
try {
incomingMessage(txn, q, meta, QUEUE_MESSAGE_HEADER_LENGTH);
} catch (FormatException e) {
throw new InvalidMessageException(e);
}
}
private boolean incomingMessage(Transaction txn, Message m, Metadata meta,
@@ -84,102 +82,4 @@ public abstract class BdfIncomingMessageHook implements IncomingMessageHook,
return incomingMessage(txn, m, body, metaDictionary);
}
protected void trackIncomingMessage(Transaction txn, Message m)
throws DbException {
trackMessage(txn, m.getGroupId(), m.getTimestamp(), false);
}
protected void trackOutgoingMessage(Transaction txn, Message m)
throws DbException {
trackMessage(txn, m.getGroupId(), m.getTimestamp(), true);
}
protected void trackMessage(Transaction txn, GroupId g, long time,
boolean read) throws DbException {
GroupCount c = getGroupCount(txn, g);
int msgCount = c.getMsgCount() + 1;
int unreadCount = c.getUnreadCount() + (read ? 0 : 1);
long latestTime =
time > c.getLatestMsgTime() ? time : c.getLatestMsgTime();
storeGroupCount(txn, g,
new GroupCount(msgCount, unreadCount, latestTime));
}
@Override
public GroupCount getGroupCount(GroupId g) throws DbException {
GroupCount count;
Transaction txn = db.startTransaction(true);
try {
count = getGroupCount(txn, g);
db.commitTransaction(txn);
}
finally {
db.endTransaction(txn);
}
return count;
}
protected GroupCount getGroupCount(Transaction txn, GroupId g)
throws DbException {
GroupCount count;
try {
BdfDictionary d = clientHelper.getGroupMetadataAsDictionary(txn, g);
count = new GroupCount(
d.getLong(GROUP_KEY_MSG_COUNT, 0L).intValue(),
d.getLong(GROUP_KEY_UNREAD_COUNT, 0L).intValue(),
d.getLong(GROUP_KEY_LATEST_MSG, 0L)
);
} catch (FormatException e) {
throw new DbException(e);
}
return count;
}
private void storeGroupCount(Transaction txn, GroupId g, GroupCount c)
throws DbException{
try {
BdfDictionary d = BdfDictionary.of(
new BdfEntry(GROUP_KEY_MSG_COUNT, c.getMsgCount()),
new BdfEntry(GROUP_KEY_UNREAD_COUNT, c.getUnreadCount()),
new BdfEntry(GROUP_KEY_LATEST_MSG, c.getLatestMsgTime())
);
clientHelper.mergeGroupMetadata(txn, g, d);
} catch (FormatException e) {
throw new DbException(e);
}
}
@Override
public void setReadFlag(GroupId g, MessageId m, boolean read)
throws DbException {
Transaction txn = db.startTransaction(false);
try {
// check current read status of message
BdfDictionary old =
clientHelper.getMessageMetadataAsDictionary(txn, m);
boolean wasRead = old.getBoolean(MSG_KEY_READ, false);
// if status changed
if (wasRead != read) {
// mark individual message as read
BdfDictionary meta = new BdfDictionary();
meta.put(MSG_KEY_READ, read);
clientHelper.mergeMessageMetadata(txn, m, meta);
// update unread counter in group metadata
GroupCount c = getGroupCount(txn, g);
BdfDictionary d = new BdfDictionary();
int count = c.getUnreadCount() + (read ? -1 : 1);
if (count < 0) throw new DbException();
d.put(GROUP_KEY_UNREAD_COUNT, count);
clientHelper.mergeGroupMetadata(txn, g, d);
}
db.commitTransaction(txn);
} catch (FormatException e) {
throw new DbException(e);
} finally {
db.endTransaction(txn);
}
}
}

View File

@@ -9,6 +9,7 @@ import org.briarproject.api.data.BdfDictionary;
import org.briarproject.api.data.BdfList;
import org.briarproject.api.data.MetadataEncoder;
import org.briarproject.api.db.Metadata;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.InvalidMessageException;
import org.briarproject.api.sync.Message;
@@ -25,6 +26,7 @@ import static org.briarproject.api.clients.QueueMessage.QUEUE_MESSAGE_HEADER_LEN
import static org.briarproject.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
import static org.briarproject.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE;
@NotNullByDefault
public abstract class BdfMessageValidator implements MessageValidator,
QueueMessageValidator {
@@ -108,7 +110,7 @@ public abstract class BdfMessageValidator implements MessageValidator,
if (b != null && b.length != length) throw new FormatException();
}
protected void checkSize(BdfList list, int minSize, int maxSize)
protected void checkSize(@Nullable BdfList list, int minSize, int maxSize)
throws FormatException {
if (list != null) {
if (list.size() < minSize) throw new FormatException();

View File

@@ -3,6 +3,7 @@ package org.briarproject.clients;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.ContactGroupFactory;
import org.briarproject.api.clients.MessageQueueManager;
import org.briarproject.api.clients.MessageTracker;
import org.briarproject.api.clients.QueueMessageFactory;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.data.BdfReaderFactory;
@@ -52,4 +53,8 @@ public class ClientsModule {
return new QueueMessageFactoryImpl(crypto);
}
@Provides
MessageTracker provideMessageTracker(MessageTrackerImpl messageTracker) {
return messageTracker;
}
}

View File

@@ -1,6 +1,8 @@
package org.briarproject.clients;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.MessageTracker;
import org.briarproject.api.clients.MessageTracker.GroupCount;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.data.MetadataParser;
@@ -8,25 +10,34 @@ import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
import org.briarproject.api.db.Transaction;
import org.briarproject.api.messaging.ConversationManager.ConversationClient;
import org.briarproject.api.sync.Group;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageId;
@NotNullByDefault
public abstract class ConversationClientImpl extends BdfIncomingMessageHook
implements ConversationClient {
protected ConversationClientImpl(DatabaseComponent db,
ClientHelper clientHelper, MetadataParser metadataParser) {
super(db, clientHelper, metadataParser);
}
protected final MessageTracker messageTracker;
protected abstract Group getContactGroup(Contact contact);
protected ConversationClientImpl(DatabaseComponent db,
ClientHelper clientHelper, MetadataParser metadataParser,
MessageTracker messageTracker) {
super(db, clientHelper, metadataParser);
this.messageTracker = messageTracker;
}
@Override
public GroupCount getGroupCount(Transaction txn, ContactId contactId)
throws DbException {
Contact contact = db.getContact(txn, contactId);
GroupId groupId = getContactGroup(contact).getId();
return getGroupCount(txn, groupId);
return messageTracker.getGroupCount(txn, groupId);
}
@Override
public void setReadFlag(GroupId g, MessageId m, boolean read)
throws DbException {
messageTracker.setReadFlag(g, m, read);
}
}

View File

@@ -11,6 +11,7 @@ import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
import org.briarproject.api.db.Metadata;
import org.briarproject.api.db.Transaction;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.ClientId;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.GroupId;
@@ -20,6 +21,7 @@ import org.briarproject.api.sync.MessageContext;
import org.briarproject.api.sync.MessageId;
import org.briarproject.api.sync.ValidationManager;
import org.briarproject.api.sync.ValidationManager.IncomingMessageHook;
import org.briarproject.api.sync.ValidationManager.MessageValidator;
import org.briarproject.util.ByteUtils;
import java.util.ArrayList;
@@ -29,12 +31,14 @@ import java.util.Map.Entry;
import java.util.TreeMap;
import java.util.logging.Logger;
import javax.annotation.Nullable;
import javax.inject.Inject;
import static java.util.logging.Level.INFO;
import static org.briarproject.api.clients.QueueMessage.QUEUE_MESSAGE_HEADER_LENGTH;
import static org.briarproject.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
@NotNullByDefault
class MessageQueueManagerImpl implements MessageQueueManager {
private static final String OUTGOING_POSITION_KEY = "nextOut";
@@ -139,6 +143,7 @@ class MessageQueueManagerImpl implements MessageQueueManager {
this.pending = pending;
}
@Nullable
MessageId popIncomingMessageId() {
Iterator<Entry<Long, MessageId>> it = pending.entrySet().iterator();
if (!it.hasNext()) {
@@ -161,8 +166,9 @@ class MessageQueueManagerImpl implements MessageQueueManager {
}
}
@NotNullByDefault
private static class DelegatingMessageValidator
implements ValidationManager.MessageValidator {
implements MessageValidator {
private final QueueMessageValidator delegate;
@@ -174,21 +180,24 @@ class MessageQueueManagerImpl implements MessageQueueManager {
public MessageContext validateMessage(Message m, Group g)
throws InvalidMessageException {
byte[] raw = m.getRaw();
if (raw.length < QUEUE_MESSAGE_HEADER_LENGTH) return null;
if (raw.length < QUEUE_MESSAGE_HEADER_LENGTH)
throw new InvalidMessageException();
long queuePosition = ByteUtils.readUint64(raw,
MESSAGE_HEADER_LENGTH);
if (queuePosition < 0) return null;
if (queuePosition < 0) throw new InvalidMessageException();
QueueMessage q = new QueueMessage(m.getId(), m.getGroupId(),
m.getTimestamp(), queuePosition, raw);
return delegate.validateMessage(q, g);
}
}
@NotNullByDefault
private class DelegatingIncomingMessageHook implements IncomingMessageHook {
private final IncomingQueueMessageHook delegate;
private DelegatingIncomingMessageHook(IncomingQueueMessageHook delegate) {
private DelegatingIncomingMessageHook(
IncomingQueueMessageHook delegate) {
this.delegate = delegate;
}
@@ -227,20 +236,16 @@ class MessageQueueManagerImpl implements MessageQueueManager {
// Save the queue state before passing control to the delegate
saveQueueState(txn, m.getGroupId(), queueState);
// Deliver the messages to the delegate
try {
delegate.incomingMessage(txn, q, meta);
for (MessageId id : consecutive) {
byte[] raw = db.getRawMessage(txn, id);
meta = db.getMessageMetadata(txn, id);
q = queueMessageFactory.createMessage(id, raw);
if (LOG.isLoggable(INFO)) {
LOG.info("Delivering pending message with position "
+ q.getQueuePosition());
}
delegate.incomingMessage(txn, q, meta);
delegate.incomingMessage(txn, q, meta);
for (MessageId id : consecutive) {
byte[] raw = db.getRawMessage(txn, id);
meta = db.getMessageMetadata(txn, id);
q = queueMessageFactory.createMessage(id, raw);
if (LOG.isLoggable(INFO)) {
LOG.info("Delivering pending message with position "
+ q.getQueuePosition());
}
} catch (FormatException e) {
throw new InvalidMessageException(e);
delegate.incomingMessage(txn, q, meta);
}
}
// message queues are only useful for groups with two members

View File

@@ -0,0 +1,132 @@
package org.briarproject.clients;
import org.briarproject.api.FormatException;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.MessageTracker;
import org.briarproject.api.data.BdfDictionary;
import org.briarproject.api.data.BdfEntry;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
import org.briarproject.api.db.Transaction;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageId;
import javax.inject.Inject;
import static org.briarproject.clients.BdfConstants.GROUP_KEY_LATEST_MSG;
import static org.briarproject.clients.BdfConstants.GROUP_KEY_MSG_COUNT;
import static org.briarproject.clients.BdfConstants.GROUP_KEY_UNREAD_COUNT;
import static org.briarproject.clients.BdfConstants.MSG_KEY_READ;
@NotNullByDefault
class MessageTrackerImpl implements MessageTracker {
private final DatabaseComponent db;
private final ClientHelper clientHelper;
@Inject
MessageTrackerImpl(DatabaseComponent db, ClientHelper clientHelper) {
this.db = db;
this.clientHelper = clientHelper;
}
@Override
public void trackIncomingMessage(Transaction txn, Message m)
throws DbException {
trackMessage(txn, m.getGroupId(), m.getTimestamp(), false);
}
@Override
public void trackOutgoingMessage(Transaction txn, Message m)
throws DbException {
trackMessage(txn, m.getGroupId(), m.getTimestamp(), true);
}
@Override
public void trackMessage(Transaction txn, GroupId g, long time,
boolean read) throws DbException {
GroupCount c = getGroupCount(txn, g);
int msgCount = c.getMsgCount() + 1;
int unreadCount = c.getUnreadCount() + (read ? 0 : 1);
long latestMsgTime = Math.max(c.getLatestMsgTime(), time);
storeGroupCount(txn, g, new GroupCount(msgCount, unreadCount,
latestMsgTime));
}
@Override
public GroupCount getGroupCount(GroupId g) throws DbException {
GroupCount count;
Transaction txn = db.startTransaction(true);
try {
count = getGroupCount(txn, g);
db.commitTransaction(txn);
} finally {
db.endTransaction(txn);
}
return count;
}
@Override
public GroupCount getGroupCount(Transaction txn, GroupId g)
throws DbException {
try {
BdfDictionary d = clientHelper.getGroupMetadataAsDictionary(txn, g);
return new GroupCount(
d.getLong(GROUP_KEY_MSG_COUNT, 0L).intValue(),
d.getLong(GROUP_KEY_UNREAD_COUNT, 0L).intValue(),
d.getLong(GROUP_KEY_LATEST_MSG, 0L)
);
} catch (FormatException e) {
throw new DbException(e);
}
}
private void storeGroupCount(Transaction txn, GroupId g, GroupCount c)
throws DbException {
try {
BdfDictionary d = BdfDictionary.of(
new BdfEntry(GROUP_KEY_MSG_COUNT, c.getMsgCount()),
new BdfEntry(GROUP_KEY_UNREAD_COUNT, c.getUnreadCount()),
new BdfEntry(GROUP_KEY_LATEST_MSG, c.getLatestMsgTime())
);
clientHelper.mergeGroupMetadata(txn, g, d);
} catch (FormatException e) {
throw new DbException(e);
}
}
@Override
public void setReadFlag(GroupId g, MessageId m, boolean read)
throws DbException {
Transaction txn = db.startTransaction(false);
try {
// check current read status of message
BdfDictionary old =
clientHelper.getMessageMetadataAsDictionary(txn, m);
boolean wasRead = old.getBoolean(MSG_KEY_READ, false);
// if status changed
if (wasRead != read) {
// mark individual message as read
BdfDictionary meta = new BdfDictionary();
meta.put(MSG_KEY_READ, read);
clientHelper.mergeMessageMetadata(txn, m, meta);
// update unread counter in group metadata
GroupCount c = getGroupCount(txn, g);
int unreadCount = c.getUnreadCount() + (read ? -1 : 1);
if (unreadCount < 0) throw new DbException();
storeGroupCount(txn, g, new GroupCount(c.getMsgCount(),
unreadCount, c.getLatestMsgTime()));
}
db.commitTransaction(txn);
} catch (FormatException e) {
throw new DbException(e);
} finally {
db.endTransaction(txn);
}
}
}

View File

@@ -2,6 +2,8 @@ package org.briarproject.forum;
import org.briarproject.api.FormatException;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.MessageTracker;
import org.briarproject.api.clients.MessageTracker.GroupCount;
import org.briarproject.api.data.BdfDictionary;
import org.briarproject.api.data.BdfList;
import org.briarproject.api.data.MetadataParser;
@@ -20,6 +22,7 @@ import org.briarproject.api.identity.Author.Status;
import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.Message;
@@ -52,22 +55,25 @@ import static org.briarproject.api.identity.Author.Status.ANONYMOUS;
import static org.briarproject.api.identity.Author.Status.OURSELVES;
import static org.briarproject.clients.BdfConstants.MSG_KEY_READ;
@NotNullByDefault
class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
private final IdentityManager identityManager;
private final ForumFactory forumFactory;
private final ForumPostFactory forumPostFactory;
private final MessageTracker messageTracker;
private final List<RemoveForumHook> removeHooks;
@Inject
ForumManagerImpl(DatabaseComponent db, IdentityManager identityManager,
ClientHelper clientHelper, MetadataParser metadataParser,
ForumFactory forumFactory, ForumPostFactory forumPostFactory) {
ForumFactory forumFactory, ForumPostFactory forumPostFactory,
MessageTracker messageTracker) {
super(db, clientHelper, metadataParser);
this.identityManager = identityManager;
this.forumFactory = forumFactory;
this.forumPostFactory = forumPostFactory;
this.messageTracker = messageTracker;
removeHooks = new CopyOnWriteArrayList<RemoveForumHook>();
}
@@ -75,7 +81,7 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
protected boolean incomingMessage(Transaction txn, Message m, BdfList body,
BdfDictionary meta) throws DbException, FormatException {
trackIncomingMessage(txn, m);
messageTracker.trackIncomingMessage(txn, m);
ForumPostHeader post = getForumPostHeader(txn, m.getId(), meta);
ForumPostReceivedEvent event =
@@ -146,7 +152,7 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
meta.put(KEY_LOCAL, true);
meta.put(MSG_KEY_READ, true);
clientHelper.addLocalMessage(txn, p.getMessage(), meta, true);
trackOutgoingMessage(txn, p.getMessage());
messageTracker.trackOutgoingMessage(txn, p.getMessage());
db.commitTransaction(txn);
} catch (FormatException e) {
throw new RuntimeException(e);
@@ -204,6 +210,7 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
try {
// Parent ID, author, forum post body, signature
BdfList message = clientHelper.getMessageAsList(m);
if (message == null) throw new DbException();
return message.getString(2);
} catch (FormatException e) {
throw new DbException(e);
@@ -253,6 +260,17 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
removeHooks.add(hook);
}
@Override
public GroupCount getGroupCount(GroupId g) throws DbException {
return messageTracker.getGroupCount(g);
}
@Override
public void setReadFlag(GroupId g, MessageId m, boolean read)
throws DbException {
messageTracker.setReadFlag(g, m, read);
}
private Forum parseForum(Group g) throws FormatException {
byte[] descriptor = g.getDescriptor();
// Name, salt

View File

@@ -9,6 +9,7 @@ import org.briarproject.api.data.BdfList;
import org.briarproject.api.data.MetadataEncoder;
import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorFactory;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.InvalidMessageException;
import org.briarproject.api.sync.Message;
@@ -25,6 +26,7 @@ import static org.briarproject.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENG
import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
@NotNullByDefault
class ForumPostValidator extends BdfMessageValidator {
private final AuthorFactory authorFactory;

View File

@@ -3,6 +3,7 @@ package org.briarproject.introduction;
import org.briarproject.api.FormatException;
import org.briarproject.api.clients.Client;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.MessageTracker;
import org.briarproject.api.clients.SessionId;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
@@ -23,6 +24,7 @@ import org.briarproject.api.introduction.IntroductionManager;
import org.briarproject.api.introduction.IntroductionMessage;
import org.briarproject.api.introduction.IntroductionRequest;
import org.briarproject.api.introduction.IntroductionResponse;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.Message;
@@ -73,6 +75,7 @@ import static org.briarproject.api.introduction.IntroductionConstants.TYPE_REQUE
import static org.briarproject.api.introduction.IntroductionConstants.TYPE_RESPONSE;
import static org.briarproject.clients.BdfConstants.MSG_KEY_READ;
@NotNullByDefault
class IntroductionManagerImpl extends ConversationClientImpl
implements IntroductionManager, Client, AddContactHook,
RemoveContactHook {
@@ -86,11 +89,12 @@ class IntroductionManagerImpl extends ConversationClientImpl
@Inject
IntroductionManagerImpl(DatabaseComponent db, ClientHelper clientHelper,
MetadataParser metadataParser, IntroducerManager introducerManager,
MetadataParser metadataParser, MessageTracker messageTracker,
IntroducerManager introducerManager,
IntroduceeManager introduceeManager,
IntroductionGroupFactory introductionGroupFactory) {
super(db, clientHelper, metadataParser);
super(db, clientHelper, metadataParser, messageTracker);
this.introducerManager = introducerManager;
this.introduceeManager = introduceeManager;
this.introductionGroupFactory = introductionGroupFactory;
@@ -213,7 +217,7 @@ class IntroductionManagerImpl extends ConversationClientImpl
introduceeManager.initialize(txn, groupId, message);
try {
introduceeManager.incomingMessage(txn, state, message);
trackIncomingMessage(txn, m);
messageTracker.trackIncomingMessage(txn, m);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
introduceeManager.abort(txn, state);
@@ -239,7 +243,8 @@ class IntroductionManagerImpl extends ConversationClientImpl
LOG.warning("Unknown role '" + role + "'");
throw new DbException();
}
if (type == TYPE_RESPONSE) trackIncomingMessage(txn, m);
if (type == TYPE_RESPONSE)
messageTracker.trackIncomingMessage(txn, m);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
if (role == ROLE_INTRODUCER) introducerManager.abort(txn, state);
@@ -260,7 +265,7 @@ class IntroductionManagerImpl extends ConversationClientImpl
}
@Override
protected Group getContactGroup(Contact contact) {
public Group getContactGroup(Contact contact) {
return introductionGroupFactory.createIntroductionGroup(contact);
}
@@ -274,8 +279,8 @@ class IntroductionManagerImpl extends ConversationClientImpl
introducerManager.makeIntroduction(txn, c1, c2, msg, timestamp);
Group g1 = getContactGroup(c1);
Group g2 = getContactGroup(c2);
trackMessage(txn, g1.getId(), timestamp, true);
trackMessage(txn, g2.getId(), timestamp, true);
messageTracker.trackMessage(txn, g1.getId(), timestamp, true);
messageTracker.trackMessage(txn, g2.getId(), timestamp, true);
db.commitTransaction(txn);
} finally {
db.endTransaction(txn);
@@ -295,7 +300,7 @@ class IntroductionManagerImpl extends ConversationClientImpl
getSessionState(txn, g.getId(), sessionId.getBytes());
introduceeManager.acceptIntroduction(txn, state, timestamp);
trackMessage(txn, g.getId(), timestamp, true);
messageTracker.trackMessage(txn, g.getId(), timestamp, true);
db.commitTransaction(txn);
} finally {
db.endTransaction(txn);
@@ -315,7 +320,7 @@ class IntroductionManagerImpl extends ConversationClientImpl
getSessionState(txn, g.getId(), sessionId.getBytes());
introduceeManager.declineIntroduction(txn, state, timestamp);
trackMessage(txn, g.getId(), timestamp, true);
messageTracker.trackMessage(txn, g.getId(), timestamp, true);
db.commitTransaction(txn);
} finally {
db.endTransaction(txn);

View File

@@ -7,6 +7,7 @@ import org.briarproject.api.clients.SessionId;
import org.briarproject.api.data.BdfDictionary;
import org.briarproject.api.data.BdfList;
import org.briarproject.api.data.MetadataEncoder;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.Message;
import org.briarproject.api.system.Clock;
@@ -39,6 +40,7 @@ import static org.briarproject.api.introduction.IntroductionConstants.TYPE_RESPO
import static org.briarproject.api.properties.TransportPropertyConstants.MAX_PROPERTIES_PER_TRANSPORT;
import static org.briarproject.api.properties.TransportPropertyConstants.MAX_PROPERTY_LENGTH;
@NotNullByDefault
class IntroductionValidator extends BdfMessageValidator {
IntroductionValidator(ClientHelper clientHelper,

View File

@@ -6,12 +6,14 @@ import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
import org.briarproject.api.db.Transaction;
import org.briarproject.api.messaging.ConversationManager;
import org.briarproject.api.nullsafety.NotNullByDefault;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import javax.inject.Inject;
@NotNullByDefault
class ConversationManagerImpl implements ConversationManager {
private final DatabaseComponent db;
@@ -32,9 +34,7 @@ class ConversationManagerImpl implements ConversationManager {
}
@Override
public GroupCount getGroupCount(ContactId contactId)
throws DbException {
public GroupCount getGroupCount(ContactId contactId) throws DbException {
int msgCount = 0, unreadCount = 0;
long latestTime = 0;
Transaction txn = db.startTransaction(true);

View File

@@ -4,6 +4,7 @@ import org.briarproject.api.FormatException;
import org.briarproject.api.clients.Client;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.ContactGroupFactory;
import org.briarproject.api.clients.MessageTracker;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.contact.ContactManager.AddContactHook;
@@ -18,6 +19,7 @@ import org.briarproject.api.event.PrivateMessageReceivedEvent;
import org.briarproject.api.messaging.MessagingManager;
import org.briarproject.api.messaging.PrivateMessage;
import org.briarproject.api.messaging.PrivateMessageHeader;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.Message;
@@ -33,6 +35,7 @@ import javax.inject.Inject;
import static org.briarproject.clients.BdfConstants.MSG_KEY_READ;
@NotNullByDefault
class MessagingManagerImpl extends ConversationClientImpl
implements MessagingManager, Client, AddContactHook, RemoveContactHook {
@@ -40,9 +43,9 @@ class MessagingManagerImpl extends ConversationClientImpl
@Inject
MessagingManagerImpl(DatabaseComponent db, ClientHelper clientHelper,
MetadataParser metadataParser,
MetadataParser metadataParser, MessageTracker messageTracker,
ContactGroupFactory contactGroupFactory) {
super(db, clientHelper, metadataParser);
super(db, clientHelper, metadataParser, messageTracker);
this.contactGroupFactory = contactGroupFactory;
}
@@ -72,7 +75,7 @@ class MessagingManagerImpl extends ConversationClientImpl
}
@Override
protected Group getContactGroup(Contact c) {
public Group getContactGroup(Contact c) {
return contactGroupFactory.createContactGroup(CLIENT_ID, c);
}
@@ -95,7 +98,7 @@ class MessagingManagerImpl extends ConversationClientImpl
PrivateMessageReceivedEvent event = new PrivateMessageReceivedEvent(
header, contactId, groupId);
txn.attach(event);
trackIncomingMessage(txn, m);
messageTracker.trackIncomingMessage(txn, m);
// don't share message
return false;
@@ -110,7 +113,7 @@ class MessagingManagerImpl extends ConversationClientImpl
meta.put("local", true);
meta.put("read", true);
clientHelper.addLocalMessage(txn, m.getMessage(), meta, true);
trackOutgoingMessage(txn, m.getMessage());
messageTracker.trackOutgoingMessage(txn, m.getMessage());
db.commitTransaction(txn);
} catch (FormatException e) {
throw new RuntimeException(e);
@@ -195,20 +198,11 @@ class MessagingManagerImpl extends ConversationClientImpl
try {
// 0: private message body
BdfList message = clientHelper.getMessageAsList(m);
if (message == null) throw new DbException();
return message.getString(0);
} catch (FormatException e) {
throw new DbException(e);
}
}
@Override
public GroupCount getGroupCount(Transaction txn, ContactId contactId)
throws DbException {
Contact contact = db.getContact(txn, contactId);
GroupId groupId = getContactGroup(contact).getId();
return getGroupCount(txn, groupId);
}
}

View File

@@ -6,6 +6,7 @@ import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.data.BdfDictionary;
import org.briarproject.api.data.BdfList;
import org.briarproject.api.data.MetadataEncoder;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.Message;
import org.briarproject.api.system.Clock;
@@ -14,6 +15,7 @@ import org.briarproject.clients.BdfMessageValidator;
import static org.briarproject.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_BODY_LENGTH;
import static org.briarproject.clients.BdfConstants.MSG_KEY_READ;
@NotNullByDefault
class PrivateMessageValidator extends BdfMessageValidator {
PrivateMessageValidator(ClientHelper clientHelper,

View File

@@ -8,6 +8,7 @@ import org.briarproject.api.data.BdfList;
import org.briarproject.api.data.MetadataEncoder;
import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorFactory;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.privategroup.MessageType;
import org.briarproject.api.privategroup.PrivateGroup;
import org.briarproject.api.privategroup.PrivateGroupFactory;
@@ -38,6 +39,7 @@ import static org.briarproject.privategroup.GroupConstants.KEY_READ;
import static org.briarproject.privategroup.GroupConstants.KEY_TIMESTAMP;
import static org.briarproject.privategroup.GroupConstants.KEY_TYPE;
@NotNullByDefault
class GroupMessageValidator extends BdfMessageValidator {
private final PrivateGroupFactory privateGroupFactory;

View File

@@ -2,6 +2,8 @@ package org.briarproject.privategroup;
import org.briarproject.api.FormatException;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.MessageTracker;
import org.briarproject.api.clients.MessageTracker.GroupCount;
import org.briarproject.api.clients.ProtocolStateException;
import org.briarproject.api.data.BdfDictionary;
import org.briarproject.api.data.BdfEntry;
@@ -75,17 +77,18 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
private final PrivateGroupFactory privateGroupFactory;
private final IdentityManager identityManager;
private final MessageTracker messageTracker;
private final List<PrivateGroupHook> hooks;
@Inject
PrivateGroupManagerImpl(ClientHelper clientHelper,
MetadataParser metadataParser, DatabaseComponent db,
PrivateGroupFactory privateGroupFactory,
IdentityManager identityManager) {
IdentityManager identityManager, MessageTracker messageTracker) {
super(db, clientHelper, metadataParser);
this.privateGroupFactory = privateGroupFactory;
this.identityManager = identityManager;
this.messageTracker = messageTracker;
hooks = new CopyOnWriteArrayList<PrivateGroupHook>();
}
@@ -126,7 +129,7 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
meta.put(KEY_TYPE, JOIN.getInt());
addMessageMetadata(meta, m, true);
clientHelper.addLocalMessage(txn, m.getMessage(), meta, true);
trackOutgoingMessage(txn, m.getMessage());
messageTracker.trackOutgoingMessage(txn, m.getMessage());
addMember(txn, m.getMessage().getGroupId(), m.getMember(), VISIBLE);
setPreviousMsgId(txn, m.getMessage().getGroupId(),
m.getMessage().getId());
@@ -218,7 +221,7 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
// track message
setPreviousMsgId(txn, g, m.getMessage().getId());
trackOutgoingMessage(txn, m.getMessage());
messageTracker.trackOutgoingMessage(txn, m.getMessage());
// broadcast event
attachGroupMessageAddedEvent(txn, m.getMessage(), meta, true);
@@ -437,6 +440,17 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
return false;
}
@Override
public GroupCount getGroupCount(GroupId g) throws DbException {
return messageTracker.getGroupCount(g);
}
@Override
public void setReadFlag(GroupId g, MessageId m, boolean read)
throws DbException {
messageTracker.setReadFlag(g, m, read);
}
@Override
public void relationshipRevealed(Transaction txn, GroupId g, AuthorId a,
boolean byContact) throws FormatException, DbException {
@@ -500,7 +514,7 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
}
addMember(txn, m.getGroupId(), member, v);
// track message and broadcast event
trackIncomingMessage(txn, m);
messageTracker.trackIncomingMessage(txn, m);
attachJoinMessageAddedEvent(txn, m, meta, false, v);
}
@@ -537,7 +551,7 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
if (previousType != JOIN && previousType != POST)
throw new FormatException();
// track message and broadcast event
trackIncomingMessage(txn, m);
messageTracker.trackIncomingMessage(txn, m);
attachGroupMessageAddedEvent(txn, m, meta, false);
}

View File

@@ -4,6 +4,7 @@ import org.briarproject.api.FormatException;
import org.briarproject.api.clients.Client;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.ContactGroupFactory;
import org.briarproject.api.clients.MessageTracker;
import org.briarproject.api.clients.SessionId;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
@@ -74,13 +75,14 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
@Inject
protected GroupInvitationManagerImpl(DatabaseComponent db,
ClientHelper clientHelper, MetadataParser metadataParser,
MessageTracker messageTracker,
ContactGroupFactory contactGroupFactory,
PrivateGroupFactory privateGroupFactory,
PrivateGroupManager privateGroupManager,
MessageParser messageParser, SessionParser sessionParser,
SessionEncoder sessionEncoder,
ProtocolEngineFactory engineFactory) {
super(db, clientHelper, metadataParser);
super(db, clientHelper, metadataParser, messageTracker);
this.contactGroupFactory = contactGroupFactory;
this.privateGroupFactory = privateGroupFactory;
this.privateGroupManager = privateGroupManager;
@@ -131,7 +133,7 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
}
@Override
protected Group getContactGroup(Contact c) {
public Group getContactGroup(Contact c) {
return contactGroupFactory.createContactGroup(CLIENT_ID, c);
}

View File

@@ -1,11 +1,12 @@
package org.briarproject.properties;
import org.briarproject.api.FormatException;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.BdfMessageContext;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.data.BdfDictionary;
import org.briarproject.api.data.BdfList;
import org.briarproject.api.data.MetadataEncoder;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.Message;
import org.briarproject.api.system.Clock;
@@ -15,6 +16,7 @@ import static org.briarproject.api.TransportId.MAX_TRANSPORT_ID_LENGTH;
import static org.briarproject.api.properties.TransportPropertyConstants.MAX_PROPERTIES_PER_TRANSPORT;
import static org.briarproject.api.properties.TransportPropertyConstants.MAX_PROPERTY_LENGTH;
@NotNullByDefault
public class TransportPropertyValidator extends BdfMessageValidator {
TransportPropertyValidator(ClientHelper clientHelper,

View File

@@ -12,6 +12,7 @@ import org.briarproject.api.blogs.BlogSharingMessage.BlogInvitation;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.ContactGroupFactory;
import org.briarproject.api.clients.MessageQueueManager;
import org.briarproject.api.clients.MessageTracker;
import org.briarproject.api.clients.SessionId;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
@@ -28,6 +29,7 @@ import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorFactory;
import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sharing.InvitationMessage;
import org.briarproject.api.sync.ClientId;
import org.briarproject.api.sync.GroupId;
@@ -43,6 +45,7 @@ import static org.briarproject.api.blogs.BlogConstants.BLOG_PUBLIC_KEY;
import static org.briarproject.api.sharing.SharingConstants.INVITATION_ID;
import static org.briarproject.api.sharing.SharingConstants.RESPONSE_ID;
@NotNullByDefault
class BlogSharingManagerImpl extends
SharingManagerImpl<Blog, BlogInvitation, BlogInviteeSessionState, BlogSharerSessionState, BlogInvitationReceivedEvent, BlogInvitationResponseReceivedEvent>
implements BlogSharingManager, RemoveBlogHook {
@@ -63,10 +66,11 @@ class BlogSharingManagerImpl extends
DatabaseComponent db, MessageQueueManager messageQueueManager,
MetadataEncoder metadataEncoder, MetadataParser metadataParser,
ContactGroupFactory contactGroupFactory, SecureRandom random,
IdentityManager identityManager) {
IdentityManager identityManager, MessageTracker messageTracker) {
super(db, messageQueueManager, clientHelper, metadataParser,
metadataEncoder, random, contactGroupFactory, clock);
metadataEncoder, random, contactGroupFactory, messageTracker,
clock);
this.blogManager = blogManager;
this.identityManager = identityManager;

View File

@@ -7,6 +7,7 @@ import org.briarproject.api.clients.SessionId;
import org.briarproject.api.data.BdfDictionary;
import org.briarproject.api.data.BdfList;
import org.briarproject.api.data.MetadataEncoder;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.Message;
import org.briarproject.api.system.Clock;
@@ -30,6 +31,7 @@ import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_LEAVE
import static org.briarproject.api.sharing.SharingConstants.TIME;
import static org.briarproject.api.sharing.SharingConstants.TYPE;
@NotNullByDefault
class BlogSharingValidator extends BdfMessageValidator {
@Inject

View File

@@ -4,6 +4,7 @@ import org.briarproject.api.FormatException;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.ContactGroupFactory;
import org.briarproject.api.clients.MessageQueueManager;
import org.briarproject.api.clients.MessageTracker;
import org.briarproject.api.clients.SessionId;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.data.BdfDictionary;
@@ -20,8 +21,10 @@ import org.briarproject.api.forum.ForumFactory;
import org.briarproject.api.forum.ForumInvitationRequest;
import org.briarproject.api.forum.ForumInvitationResponse;
import org.briarproject.api.forum.ForumManager;
import org.briarproject.api.forum.ForumManager.RemoveForumHook;
import org.briarproject.api.forum.ForumSharingManager;
import org.briarproject.api.forum.ForumSharingMessage.ForumInvitation;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sharing.InvitationMessage;
import org.briarproject.api.sync.ClientId;
import org.briarproject.api.sync.GroupId;
@@ -37,9 +40,10 @@ import static org.briarproject.api.forum.ForumConstants.FORUM_SALT;
import static org.briarproject.api.sharing.SharingConstants.INVITATION_ID;
import static org.briarproject.api.sharing.SharingConstants.RESPONSE_ID;
@NotNullByDefault
class ForumSharingManagerImpl extends
SharingManagerImpl<Forum, ForumInvitation, ForumInviteeSessionState, ForumSharerSessionState, ForumInvitationReceivedEvent, ForumInvitationResponseReceivedEvent>
implements ForumSharingManager, ForumManager.RemoveForumHook {
implements ForumSharingManager, RemoveForumHook {
private final SFactory sFactory;
private final IFactory iFactory;
@@ -57,9 +61,10 @@ class ForumSharingManagerImpl extends
MetadataEncoder metadataEncoder,
MetadataParser metadataParser,
ContactGroupFactory contactGroupFactory,
SecureRandom random) {
SecureRandom random, MessageTracker messageTracker) {
super(db, messageQueueManager, clientHelper, metadataParser,
metadataEncoder, random, contactGroupFactory, clock);
metadataEncoder, random, contactGroupFactory, messageTracker,
clock);
sFactory = new SFactory(forumFactory, forumManager);
iFactory = new IFactory();

View File

@@ -7,6 +7,7 @@ import org.briarproject.api.clients.SessionId;
import org.briarproject.api.data.BdfDictionary;
import org.briarproject.api.data.BdfList;
import org.briarproject.api.data.MetadataEncoder;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.Message;
import org.briarproject.api.system.Clock;
@@ -30,6 +31,7 @@ import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_LEAVE
import static org.briarproject.api.sharing.SharingConstants.TIME;
import static org.briarproject.api.sharing.SharingConstants.TYPE;
@NotNullByDefault
class ForumSharingValidator extends BdfMessageValidator {
@Inject

View File

@@ -6,6 +6,7 @@ import org.briarproject.api.clients.Client;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.ContactGroupFactory;
import org.briarproject.api.clients.MessageQueueManager;
import org.briarproject.api.clients.MessageTracker;
import org.briarproject.api.clients.SessionId;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
@@ -25,6 +26,7 @@ import org.briarproject.api.event.Event;
import org.briarproject.api.event.InvitationRequestReceivedEvent;
import org.briarproject.api.event.InvitationResponseReceivedEvent;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sharing.InvitationMessage;
import org.briarproject.api.sharing.Shareable;
import org.briarproject.api.sharing.SharingInvitationItem;
@@ -52,6 +54,8 @@ import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;
import javax.annotation.Nullable;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.api.clients.ProtocolEngine.StateUpdate;
@@ -86,6 +90,7 @@ import static org.briarproject.api.sharing.SharingMessage.Invitation;
import static org.briarproject.clients.BdfConstants.MSG_KEY_READ;
import static org.briarproject.sharing.InviteeSessionState.State.AWAIT_LOCAL_RESPONSE;
@NotNullByDefault
abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS extends InviteeSessionState, SS extends SharerSessionState, IR extends InvitationRequestReceivedEvent, IRR extends InvitationResponseReceivedEvent>
extends ConversationClientImpl
implements SharingManager<S>, Client, AddContactHook,
@@ -105,9 +110,8 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
MessageQueueManager messageQueueManager, ClientHelper clientHelper,
MetadataParser metadataParser, MetadataEncoder metadataEncoder,
SecureRandom random, ContactGroupFactory contactGroupFactory,
Clock clock) {
super(db, clientHelper, metadataParser);
MessageTracker messageTracker, Clock clock) {
super(db, clientHelper, metadataParser, messageTracker);
this.messageQueueManager = messageQueueManager;
this.metadataEncoder = metadataEncoder;
this.random = random;
@@ -226,7 +230,7 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
new InviteeEngine<IS, IR>(getIRFactory(), clock);
processInviteeStateUpdate(txn, m.getId(),
engine.onMessageReceived(state, msg));
trackIncomingMessage(txn, m);
messageTracker.trackIncomingMessage(txn, m);
} else if (msg.getType() == SHARE_MSG_TYPE_ACCEPT ||
msg.getType() == SHARE_MSG_TYPE_DECLINE) {
// we are a sharer who just received a response
@@ -237,7 +241,7 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
getIRRFactory(), clock);
processSharerStateUpdate(txn, m.getId(),
engine.onMessageReceived(state, msg));
trackIncomingMessage(txn, m);
messageTracker.trackIncomingMessage(txn, m);
} else if (msg.getType() == SHARE_MSG_TYPE_LEAVE ||
msg.getType() == SHARE_MSG_TYPE_ABORT) {
// we don't know who we are, so figure it out
@@ -296,7 +300,8 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
// track message
// TODO handle this properly without engine hacks (#376)
long time = update.toSend.get(0).getTime();
trackMessage(txn, localState.getGroupId(), time, true);
messageTracker.trackMessage(txn, localState.getGroupId(), time,
true);
db.commitTransaction(txn);
} catch (FormatException e) {
@@ -359,7 +364,7 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
// track message
// TODO handle this properly without engine hacks (#376)
long time = update.toSend.get(0).getTime();
trackMessage(txn, localState.getGroupId(), time, true);
messageTracker.trackMessage(txn, localState.getGroupId(), time, true);
}
@Override
@@ -581,16 +586,6 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
}
}
@Override
public GroupCount getGroupCount(Transaction txn, ContactId contactId)
throws DbException {
Contact contact = db.getContact(txn, contactId);
GroupId groupId = getContactGroup(contact).getId();
return getGroupCount(txn, groupId);
}
void removingShareable(Transaction txn, S f) throws DbException {
try {
for (Contact c : db.getContacts(txn)) {
@@ -827,7 +822,8 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
throw new FormatException();
}
private void processStateUpdate(Transaction txn, MessageId messageId,
private void processStateUpdate(Transaction txn,
@Nullable MessageId messageId,
StateUpdate<SharingSessionState, BaseMessage> result, S f)
throws DbException, FormatException {
@@ -859,8 +855,8 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
}
}
private void processSharerStateUpdate(Transaction txn, MessageId messageId,
StateUpdate<SS, BaseMessage> result)
private void processSharerStateUpdate(Transaction txn,
@Nullable MessageId messageId, StateUpdate<SS, BaseMessage> result)
throws DbException, FormatException {
StateUpdate<SharingSessionState, BaseMessage> r =
@@ -874,8 +870,8 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
processStateUpdate(txn, messageId, r, f);
}
private void processInviteeStateUpdate(Transaction txn, MessageId messageId,
StateUpdate<IS, BaseMessage> result)
private void processInviteeStateUpdate(Transaction txn,
@Nullable MessageId messageId, StateUpdate<IS, BaseMessage> result)
throws DbException, FormatException {
StateUpdate<SharingSessionState, BaseMessage> r =
@@ -947,7 +943,7 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
}
@Override
protected Group getContactGroup(Contact c) {
public Group getContactGroup(Contact c) {
return contactGroupFactory.createContactGroup(getClientId(), c);
}

View File

@@ -1,19 +1,22 @@
package org.briarproject.sync;
import org.briarproject.api.UniqueId;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageFactory;
import org.briarproject.api.sync.MessageId;
import org.briarproject.util.ByteUtils;
import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
import static org.briarproject.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
import static org.briarproject.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
@Immutable
@NotNullByDefault
class MessageFactoryImpl implements MessageFactory {
private final CryptoComponent crypto;

View File

@@ -1,6 +1,5 @@
package org.briarproject.sync;
import org.briarproject.api.UniqueId;
import org.briarproject.api.crypto.CryptoExecutor;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DatabaseExecutor;
@@ -13,15 +12,15 @@ import org.briarproject.api.event.Event;
import org.briarproject.api.event.EventListener;
import org.briarproject.api.event.MessageAddedEvent;
import org.briarproject.api.lifecycle.Service;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.ClientId;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.InvalidMessageException;
import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageContext;
import org.briarproject.api.sync.MessageFactory;
import org.briarproject.api.sync.MessageId;
import org.briarproject.api.sync.ValidationManager;
import org.briarproject.util.ByteUtils;
import java.util.Collection;
import java.util.LinkedList;
@@ -33,15 +32,17 @@ import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Logger;
import javax.annotation.concurrent.ThreadSafe;
import javax.inject.Inject;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
import static org.briarproject.api.sync.ValidationManager.State.DELIVERED;
import static org.briarproject.api.sync.ValidationManager.State.INVALID;
import static org.briarproject.api.sync.ValidationManager.State.PENDING;
@ThreadSafe
@NotNullByDefault
class ValidationManagerImpl implements ValidationManager, Service,
EventListener {
@@ -51,6 +52,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
private final DatabaseComponent db;
private final Executor dbExecutor;
private final Executor cryptoExecutor;
private final MessageFactory messageFactory;
private final Map<ClientId, MessageValidator> validators;
private final Map<ClientId, IncomingMessageHook> hooks;
private final AtomicBoolean used = new AtomicBoolean(false);
@@ -58,10 +60,12 @@ class ValidationManagerImpl implements ValidationManager, Service,
@Inject
ValidationManagerImpl(DatabaseComponent db,
@DatabaseExecutor Executor dbExecutor,
@CryptoExecutor Executor cryptoExecutor) {
@CryptoExecutor Executor cryptoExecutor,
MessageFactory messageFactory) {
this.db = db;
this.dbExecutor = dbExecutor;
this.cryptoExecutor = cryptoExecutor;
this.messageFactory = messageFactory;
validators = new ConcurrentHashMap<ClientId, MessageValidator>();
hooks = new ConcurrentHashMap<ClientId, IncomingMessageHook>();
}
@@ -134,7 +138,8 @@ class ValidationManagerImpl implements ValidationManager, Service,
try {
MessageId id = unvalidated.poll();
byte[] raw = db.getRawMessage(txn, id);
m = parseMessage(id, raw);
if (raw == null) throw new DbException();
m = messageFactory.createMessage(id, raw);
g = db.getGroup(txn, m.getGroupId());
db.commitTransaction(txn);
} finally {
@@ -210,7 +215,9 @@ class ValidationManagerImpl implements ValidationManager, Service,
invalidateMessage(txn, id);
invalidate = getDependentsToInvalidate(txn, id);
} else if (allDelivered) {
Message m = parseMessage(id, db.getRawMessage(txn, id));
byte[] raw = db.getRawMessage(txn, id);
if (raw == null) throw new DbException();
Message m = messageFactory.createMessage(id, raw);
Group g = db.getGroup(txn, m.getGroupId());
ClientId c = g.getClientId();
Metadata meta = db.getMessageMetadataForValidator(txn,
@@ -247,15 +254,6 @@ class ValidationManagerImpl implements ValidationManager, Service,
}
}
private Message parseMessage(MessageId id, byte[] raw) {
if (raw.length <= MESSAGE_HEADER_LENGTH)
throw new IllegalArgumentException();
byte[] groupId = new byte[UniqueId.LENGTH];
System.arraycopy(raw, 0, groupId, 0, UniqueId.LENGTH);
long timestamp = ByteUtils.readUint64(raw, UniqueId.LENGTH);
return new Message(id, new GroupId(groupId), timestamp, raw);
}
private void validateMessageAsync(final Message m, final Group g) {
cryptoExecutor.execute(new Runnable() {
@Override
@@ -412,7 +410,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
/**
* Shares the next message from the toShare queue asynchronously.
*
* <p>
* This method should only be called for messages that have all their
* dependencies delivered and have been delivered themselves.
*/