Merge branch '584-store-latest-timestamp-and-unread-count-in-group-metadata-for-private-messaging' into 'master'

Store message count, unread count and timestamp of latest message in group metadata

This is to eventually address #373 and slowness of other lists. The group metadata is not yet used, but if this MR isn't merged fast, another commit that actually uses it and thus takes care of the slowness will be added.

Closes #584, #585, #586

See merge request !336
This commit is contained in:
akwizgran
2016-10-05 16:20:32 +00:00
25 changed files with 421 additions and 141 deletions

View File

@@ -8,6 +8,7 @@ import org.briarproject.api.blogs.BlogInvitationResponse;
import org.briarproject.api.blogs.BlogManager;
import org.briarproject.api.blogs.BlogPostFactory;
import org.briarproject.api.blogs.BlogSharingManager;
import org.briarproject.api.clients.ContactGroupFactory;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.contact.ContactManager;
@@ -25,6 +26,7 @@ import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.sharing.InvitationMessage;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.SyncSession;
import org.briarproject.api.sync.SyncSessionFactory;
import org.briarproject.api.sync.ValidationManager.State;
@@ -62,12 +64,12 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class BlogSharingIntegrationTest extends BriarTestCase {
public class BlogSharingIntegrationTest extends BriarIntegrationTest {
private LifecycleManager lifecycleManager0, lifecycleManager1,
lifecycleManager2;
private SyncSessionFactory sync0, sync1, sync2;
private BlogManager blogManager0, blogManager1, blogManager2;
private SyncSessionFactory sync0, sync1;
private BlogManager blogManager0, blogManager1;
private ContactManager contactManager0, contactManager1, contactManager2;
private Contact contact1, contact2, contact01, contact02;
private ContactId contactId1, contactId2, contactId01, contactId02;
@@ -83,6 +85,8 @@ public class BlogSharingIntegrationTest extends BriarTestCase {
@Inject
AuthorFactory authorFactory;
@Inject
ContactGroupFactory contactGroupFactory;
@Inject
BlogPostFactory blogPostFactory;
@Inject
CryptoComponent cryptoComponent;
@@ -138,13 +142,11 @@ public class BlogSharingIntegrationTest extends BriarTestCase {
contactManager2 = t2.getContactManager();
blogManager0 = t0.getBlogManager();
blogManager1 = t1.getBlogManager();
blogManager2 = t2.getBlogManager();
blogSharingManager0 = t0.getBlogSharingManager();
blogSharingManager1 = t1.getBlogSharingManager();
blogSharingManager2 = t2.getBlogSharingManager();
sync0 = t0.getSyncSessionFactory();
sync1 = t1.getSyncSessionFactory();
sync2 = t2.getSyncSessionFactory();
// initialize waiters fresh for each test
eventWaiter = new Waiter();
@@ -187,15 +189,23 @@ public class BlogSharingIntegrationTest extends BriarTestCase {
// invitee has own blog and that of the sharer
assertEquals(2, blogManager1.getBlogs().size());
// get sharing group and assert group message count
GroupId g = contactGroupFactory
.createContactGroup(blogSharingManager0.getClientId(),
contact1).getId();
assertGroupCount(blogSharingManager0, g, 1, 0);
// sync first request message
sync0To1();
eventWaiter.await(TIMEOUT, 1);
assertTrue(listener1.requestReceived);
assertGroupCount(blogSharingManager1, g, 2, 1);
// sync response back
sync1To0();
eventWaiter.await(TIMEOUT, 1);
assertTrue(listener0.responseReceived);
assertGroupCount(blogSharingManager0, g, 2, 1);
// blog was added successfully
assertEquals(0, blogSharingManager0.getInvitations().size());
@@ -232,6 +242,10 @@ public class BlogSharingIntegrationTest extends BriarTestCase {
assertFalse(blogSharingManager0.canBeShared(blog2.getId(), contact1));
assertFalse(blogSharingManager1.canBeShared(blog2.getId(), contact01));
// group message count is still correct
assertGroupCount(blogSharingManager0, g, 2, 1);
assertGroupCount(blogSharingManager1, g, 2, 1);
stopLifecycles();
}
@@ -510,8 +524,7 @@ public class BlogSharingIntegrationTest extends BriarTestCase {
private class SharerListener implements EventListener {
volatile boolean requestReceived = false;
volatile boolean responseReceived = false;
private volatile boolean responseReceived = false;
@Override
public void eventOccurred(Event e) {
@@ -534,7 +547,6 @@ public class BlogSharingIntegrationTest extends BriarTestCase {
BlogInvitationReceivedEvent event =
(BlogInvitationReceivedEvent) e;
eventWaiter.assertEquals(contactId1, event.getContactId());
requestReceived = true;
Blog b = event.getBlog();
try {
Contact c = contactManager0.getContact(contactId1);
@@ -550,17 +562,16 @@ public class BlogSharingIntegrationTest extends BriarTestCase {
private class InviteeListener implements EventListener {
volatile boolean requestReceived = false;
volatile boolean responseReceived = false;
private volatile boolean requestReceived = false;
private final boolean accept, answer;
InviteeListener(boolean accept, boolean answer) {
private InviteeListener(boolean accept, boolean answer) {
this.accept = accept;
this.answer = answer;
}
InviteeListener(boolean accept) {
private InviteeListener(boolean accept) {
this(accept, true);
}
@@ -596,7 +607,6 @@ public class BlogSharingIntegrationTest extends BriarTestCase {
BlogInvitationResponseReceivedEvent event =
(BlogInvitationResponseReceivedEvent) e;
eventWaiter.assertEquals(contactId01, event.getContactId());
responseReceived = true;
eventWaiter.resume();
}
}

View File

@@ -0,0 +1,32 @@
package org.briarproject;
import org.briarproject.api.clients.MessageTracker;
import org.briarproject.api.clients.MessageTracker.GroupCount;
import org.briarproject.api.db.DbException;
import org.briarproject.api.sync.GroupId;
import static org.junit.Assert.assertEquals;
public abstract class BriarIntegrationTest extends BriarTestCase {
// TODO maybe we could add uncaught exception handlers for other threads here (#670)
protected void assertGroupCount(MessageTracker tracker, GroupId g,
long msgCount, long unreadCount, long latestMsg)
throws DbException {
GroupCount groupCount = tracker.getGroupCount(g);
assertEquals(msgCount, groupCount.getMsgCount());
assertEquals(unreadCount, groupCount.getUnreadCount());
assertEquals(latestMsg, groupCount.getLatestMsgTime());
}
protected void assertGroupCount(MessageTracker tracker, GroupId g,
long msgCount, long unreadCount) throws DbException {
GroupCount c1 = tracker.getGroupCount(g);
assertEquals(msgCount, c1.getMsgCount());
assertEquals(unreadCount, c1.getUnreadCount());
}
}

View File

@@ -59,7 +59,7 @@ import static org.briarproject.api.sync.ValidationManager.State.INVALID;
import static org.briarproject.api.sync.ValidationManager.State.PENDING;
import static org.junit.Assert.assertTrue;
public class ForumManagerTest {
public class ForumManagerTest extends BriarIntegrationTest {
private LifecycleManager lifecycleManager0, lifecycleManager1;
private SyncSessionFactory sync0, sync1;
@@ -150,9 +150,19 @@ public class ForumManagerTest {
createForumPost(forum.getGroup().getId(), post1, body2, ms2);
assertEquals(ms2, post2.getMessage().getTimestamp());
forumManager0.addLocalPost(post1);
forumManager0.setReadFlag(post1.getMessage().getId(), true);
forumManager0.setReadFlag(forum.getGroup().getId(),
post1.getMessage().getId(), true);
assertGroupCount(forumManager0, forum.getGroup().getId(), 1, 0,
post1.getMessage().getTimestamp());
forumManager0.addLocalPost(post2);
forumManager0.setReadFlag(post2.getMessage().getId(), false);
forumManager0.setReadFlag(forum.getGroup().getId(),
post2.getMessage().getId(), false);
assertGroupCount(forumManager0, forum.getGroup().getId(), 2, 1,
post2.getMessage().getTimestamp());
forumManager0.setReadFlag(forum.getGroup().getId(),
post2.getMessage().getId(), false);
assertGroupCount(forumManager0, forum.getGroup().getId(), 2, 1,
post2.getMessage().getTimestamp());
Collection<ForumPostHeader> headers =
forumManager0.getPostHeaders(forum.getGroup().getId());
assertEquals(2, headers.size());
@@ -202,23 +212,29 @@ public class ForumManagerTest {
forumManager0.addLocalPost(post1);
assertEquals(1, forumManager0.getPostHeaders(g).size());
assertEquals(0, forumManager1.getPostHeaders(g).size());
assertGroupCount(forumManager0, g, 1, 0, time);
assertGroupCount(forumManager1, g, 0, 0, 0);
// send post to 1
sync0To1();
deliveryWaiter.await(TIMEOUT, 1);
assertEquals(1, forumManager1.getPostHeaders(g).size());
assertGroupCount(forumManager1, g, 1, 1, time);
// add another forum post
time = clock.currentTimeMillis();
ForumPost post2 = createForumPost(g, null, "b", time);
long time2 = clock.currentTimeMillis();
ForumPost post2 = createForumPost(g, null, "b", time2);
forumManager1.addLocalPost(post2);
assertEquals(1, forumManager0.getPostHeaders(g).size());
assertEquals(2, forumManager1.getPostHeaders(g).size());
assertGroupCount(forumManager0, g, 1, 0, time);
assertGroupCount(forumManager1, g, 2, 1, time2);
// send post to 0
sync1To0();
deliveryWaiter.await(TIMEOUT, 1);
assertEquals(2, forumManager1.getPostHeaders(g).size());
assertGroupCount(forumManager0, g, 2, 1, time2);
stopLifecycles();
}

View File

@@ -4,7 +4,7 @@ import android.support.annotation.Nullable;
import net.jodah.concurrentunit.Waiter;
import org.briarproject.BriarTestCase;
import org.briarproject.BriarIntegrationTest;
import org.briarproject.TestDatabaseModule;
import org.briarproject.TestUtils;
import org.briarproject.api.FormatException;
@@ -99,7 +99,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
public class IntroductionIntegrationTest extends BriarTestCase {
public class IntroductionIntegrationTest extends BriarIntegrationTest {
private LifecycleManager lifecycleManager0, lifecycleManager1,
lifecycleManager2;
@@ -200,29 +200,43 @@ public class IntroductionIntegrationTest extends BriarTestCase {
introductionManager0
.makeIntroduction(introducee1, introducee2, "Hi!", time);
// check that messages are tracked properly
Group g1 = introductionGroupFactory
.createIntroductionGroup(introducee1);
Group g2 = introductionGroupFactory
.createIntroductionGroup(introducee2);
assertGroupCount(introductionManager0, g1.getId(), 1, 0, time);
assertGroupCount(introductionManager0, g2.getId(), 1, 0, time);
// sync first request message
deliverMessage(sync0, contactId0, sync1, contactId1, "0 to 1");
eventWaiter.await(TIMEOUT, 1);
assertTrue(listener1.requestReceived);
assertGroupCount(introductionManager1, g1.getId(), 2, 1);
// sync second request message
deliverMessage(sync0, contactId0, sync2, contactId2, "0 to 2");
eventWaiter.await(TIMEOUT, 1);
assertTrue(listener2.requestReceived);
assertGroupCount(introductionManager2, g2.getId(), 2, 1);
// sync first response
deliverMessage(sync1, contactId1, sync0, contactId0, "1 to 0");
eventWaiter.await(TIMEOUT, 1);
assertTrue(listener0.response1Received);
assertGroupCount(introductionManager0, g1.getId(), 2, 1);
// sync second response
deliverMessage(sync2, contactId2, sync0, contactId0, "2 to 0");
eventWaiter.await(TIMEOUT, 1);
assertTrue(listener0.response2Received);
assertGroupCount(introductionManager0, g2.getId(), 2, 1);
// sync forwarded responses to introducees
deliverMessage(sync0, contactId0, sync1, contactId1, "0 to 1");
deliverMessage(sync0, contactId0, sync2, contactId2, "0 to 2");
assertGroupCount(introductionManager1, g1.getId(), 3, 2);
assertGroupCount(introductionManager2, g2.getId(), 3, 2);
// sync first ACK and its forward
deliverMessage(sync1, contactId1, sync0, contactId0, "1 to 0");
@@ -255,6 +269,10 @@ public class IntroductionIntegrationTest extends BriarTestCase {
}
assertDefaultUiMessages();
assertGroupCount(introductionManager0, g1.getId(), 2, 1);
assertGroupCount(introductionManager0, g2.getId(), 2, 1);
assertGroupCount(introductionManager1, g1.getId(), 3, 2);
assertGroupCount(introductionManager2, g2.getId(), 3, 2);
} finally {
stopLifecycles();
}

View File

@@ -499,7 +499,7 @@ public class ConversationActivity extends BriarActivity
for (MessageId m : unread)
// not really clean, but the messaging manager can
// handle introduction messages as well
messagingManager.setReadFlag(m, true);
messagingManager.setReadFlag(groupId, m, true);
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Marking read took " + duration + " ms");
@@ -614,7 +614,7 @@ public class ConversationActivity extends BriarActivity
@Override
public void run() {
try {
messagingManager.setReadFlag(m, true);
messagingManager.setReadFlag(groupId, m, true);
loadMessages();
} catch (DbException e) {
if (LOG.isLoggable(WARNING))

View File

@@ -291,13 +291,15 @@ public class ForumControllerImpl extends DbControllerImpl
@Override
public void entriesRead(final Collection<ForumEntry> forumEntries) {
if (forum == null) return;
runOnDbThread(new Runnable() {
@Override
public void run() {
try {
long now = System.currentTimeMillis();
for (ForumEntry fe : forumEntries) {
forumManager.setReadFlag(fe.getId(), true);
forumManager
.setReadFlag(forum.getId(), fe.getId(), true);
}
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))

View File

@@ -0,0 +1,44 @@
package org.briarproject.api.clients;
import org.briarproject.api.db.DbException;
import org.briarproject.api.db.Transaction;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageId;
public interface MessageTracker {
/**
* Gets the number of visible and unread messages in the group
* as well as the timestamp of the latest message
**/
GroupCount getGroupCount(GroupId g) throws DbException;
/**
* Marks a message as read or unread and updates the group counts in g.
**/
void setReadFlag(GroupId g, MessageId m, boolean read) throws DbException;
class GroupCount {
private final long msgCount, unreadCount, latestMsgTime;
public GroupCount(long msgCount, long unreadCount, long latestMsgTime) {
this.msgCount = msgCount;
this.unreadCount = unreadCount;
this.latestMsgTime = latestMsgTime;
}
public long getMsgCount() {
return msgCount;
}
public long getUnreadCount() {
return unreadCount;
}
public long getLatestMsgTime() {
return latestMsgTime;
}
}
}

View File

@@ -28,6 +28,5 @@ public interface ForumConstants {
String KEY_PUBLIC_NAME = "publicKey";
String KEY_AUTHOR = "author";
String KEY_LOCAL = "local";
String KEY_READ = "read";
}

View File

@@ -1,5 +1,6 @@
package org.briarproject.api.forum;
import org.briarproject.api.clients.MessageTracker;
import org.briarproject.api.db.DbException;
import org.briarproject.api.db.Transaction;
import org.briarproject.api.sync.ClientId;
@@ -8,7 +9,7 @@ import org.briarproject.api.sync.MessageId;
import java.util.Collection;
public interface ForumManager {
public interface ForumManager extends MessageTracker {
/** Returns the unique ID of the forum client. */
ClientId getClientId();
@@ -37,9 +38,6 @@ public interface ForumManager {
/** Returns the headers of all posts in the given forum. */
Collection<ForumPostHeader> getPostHeaders(GroupId g) throws DbException;
/** Marks a forum post as read or unread. */
void setReadFlag(MessageId m, boolean read) throws DbException;
/** Registers a hook to be called whenever a forum is removed. */
void registerRemoveForumHook(RemoveForumHook hook);

View File

@@ -45,7 +45,6 @@ public interface IntroductionConstants {
String CONTACT_ID_2 = "contactId2";
String RESPONSE_1 = "response1";
String RESPONSE_2 = "response2";
String READ = "read";
/* Introduction Request Action */
String PUBLIC_KEY1 = "publicKey1";

View File

@@ -1,6 +1,7 @@
package org.briarproject.api.introduction;
import org.briarproject.api.FormatException;
import org.briarproject.api.clients.MessageTracker;
import org.briarproject.api.clients.SessionId;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
@@ -9,7 +10,7 @@ import org.briarproject.api.sync.ClientId;
import java.util.Collection;
public interface IntroductionManager {
public interface IntroductionManager extends MessageTracker {
/** Returns the unique ID of the introduction client. */
ClientId getClientId();

View File

@@ -1,5 +1,6 @@
package org.briarproject.api.messaging;
import org.briarproject.api.clients.MessageTracker;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.db.DbException;
import org.briarproject.api.sync.ClientId;
@@ -8,7 +9,7 @@ import org.briarproject.api.sync.MessageId;
import java.util.Collection;
public interface MessagingManager {
public interface MessagingManager extends MessageTracker {
/** Returns the unique ID of the messaging client. */
ClientId getClientId();
@@ -31,6 +32,4 @@ public interface MessagingManager {
/** Returns the body of the private message with the given ID. */
byte[] getMessageBody(MessageId m) throws DbException;
/** Marks a private message as read or unread. */
void setReadFlag(MessageId m, boolean read) throws DbException;
}

View File

@@ -1,5 +1,6 @@
package org.briarproject.api.privategroup;
import org.briarproject.api.clients.MessageTracker;
import org.briarproject.api.db.DbException;
import org.briarproject.api.db.Transaction;
import org.briarproject.api.sync.ClientId;
@@ -9,7 +10,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.Collection;
public interface PrivateGroupManager {
public interface PrivateGroupManager extends MessageTracker {
/** Returns the unique ID of the private group client. */
@NotNull
@@ -40,7 +41,4 @@ public interface PrivateGroupManager {
@NotNull
Collection<GroupMessageHeader> getHeaders(GroupId g) throws DbException;
/** Marks a group message as read or unread. */
void setReadFlag(MessageId m, boolean read) throws DbException;
}

View File

@@ -16,7 +16,6 @@ public interface SharingConstants {
String STATE = "state";
String LOCAL = "local";
String TIME = "time";
String READ = "read";
String IS_SHARER = "isSharer";
String SHAREABLE_ID = "shareableId";
String INVITATION_MSG = "invitationMsg";

View File

@@ -1,5 +1,6 @@
package org.briarproject.api.sharing;
import org.briarproject.api.clients.MessageTracker;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.db.DbException;
@@ -8,7 +9,7 @@ import org.briarproject.api.sync.GroupId;
import java.util.Collection;
public interface SharingManager<S extends Shareable> {
public interface SharingManager<S extends Shareable> extends MessageTracker {
/** Returns the unique ID of the group sharing client. */
ClientId getClientId();

View File

@@ -86,7 +86,6 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
"dafbe56f0c8971365cea4bb5f08ec9a6" +
"1d686e058b943997b6ff259ba423f613"));
private final DatabaseComponent db;
private final IdentityManager identityManager;
private final ContactManager contactManager;
private final BlogFactory blogFactory;
@@ -98,9 +97,8 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
ClientHelper clientHelper, MetadataParser metadataParser,
ContactManager contactManager, BlogFactory blogFactory,
BlogPostFactory blogPostFactory) {
super(clientHelper, metadataParser);
super(db, clientHelper, metadataParser);
this.db = db;
this.identityManager = identityManager;
this.contactManager = contactManager;
this.blogFactory = blogFactory;

View File

@@ -0,0 +1,11 @@
package org.briarproject.clients;
public interface BdfConstants {
String GROUP_KEY_MSG_COUNT = "messageCount";
String GROUP_KEY_UNREAD_COUNT = "unreadCount";
String GROUP_KEY_LATEST_MSG = "latestMessageTime";
String MSG_KEY_READ = "read";
}

View File

@@ -3,27 +3,38 @@ 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.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;
public abstract class BdfIncomingMessageHook implements IncomingMessageHook,
IncomingQueueMessageHook {
IncomingQueueMessageHook, MessageTracker {
protected final DatabaseComponent db;
protected final ClientHelper clientHelper;
protected final MetadataParser metadataParser;
protected BdfIncomingMessageHook(ClientHelper clientHelper,
MetadataParser metadataParser) {
protected BdfIncomingMessageHook(DatabaseComponent db,
ClientHelper clientHelper, MetadataParser metadataParser) {
this.db = db;
this.clientHelper = clientHelper;
this.metadataParser = metadataParser;
}
@@ -56,4 +67,102 @@ public abstract class BdfIncomingMessageHook implements IncomingMessageHook,
throw new DbException(e);
}
}
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);
long msgCount = c.getMsgCount() + 1;
long 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);
txn.setComplete();
}
finally {
db.endTransaction(txn);
}
return count;
}
private 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),
d.getLong(GROUP_KEY_UNREAD_COUNT, 0L),
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();
d.put(GROUP_KEY_UNREAD_COUNT,
c.getUnreadCount() + (read ? -1 : 1));
clientHelper.mergeGroupMetadata(txn, g, d);
}
txn.setComplete();
} catch (FormatException e) {
throw new DbException(e);
} finally {
db.endTransaction(txn);
}
}
}

View File

@@ -45,9 +45,9 @@ import static org.briarproject.api.forum.ForumConstants.KEY_LOCAL;
import static org.briarproject.api.forum.ForumConstants.KEY_NAME;
import static org.briarproject.api.forum.ForumConstants.KEY_PARENT;
import static org.briarproject.api.forum.ForumConstants.KEY_PUBLIC_NAME;
import static org.briarproject.api.forum.ForumConstants.KEY_READ;
import static org.briarproject.api.forum.ForumConstants.KEY_TIMESTAMP;
import static org.briarproject.api.identity.Author.Status.ANONYMOUS;
import static org.briarproject.clients.BdfConstants.MSG_KEY_READ;
class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
@@ -55,7 +55,6 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
"859a7be50dca035b64bd6902fb797097"
+ "795af837abbf8c16d750b3c2ccc186ea"));
private final DatabaseComponent db;
private final IdentityManager identityManager;
private final ForumFactory forumFactory;
private final List<RemoveForumHook> removeHooks;
@@ -64,9 +63,8 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
ForumManagerImpl(DatabaseComponent db, IdentityManager identityManager,
ClientHelper clientHelper, MetadataParser metadataParser,
ForumFactory forumFactory) {
super(db, clientHelper, metadataParser);
super(clientHelper, metadataParser);
this.db = db;
this.identityManager = identityManager;
this.forumFactory = forumFactory;
removeHooks = new CopyOnWriteArrayList<RemoveForumHook>();
@@ -76,6 +74,8 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
protected boolean incomingMessage(Transaction txn, Message m, BdfList body,
BdfDictionary meta) throws DbException, FormatException {
trackIncomingMessage(txn, m);
ForumPostHeader post = getForumPostHeader(txn, m.getId(), meta);
ForumPostReceivedEvent event =
new ForumPostReceivedEvent(post, m.getGroupId());
@@ -119,6 +119,7 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
@Override
public void addLocalPost(ForumPost p) throws DbException {
Transaction txn = db.startTransaction(false);
try {
BdfDictionary meta = new BdfDictionary();
meta.put(KEY_TIMESTAMP, p.getMessage().getTimestamp());
@@ -132,10 +133,14 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
meta.put(KEY_AUTHOR, authorMeta);
}
meta.put(KEY_LOCAL, true);
meta.put(KEY_READ, true);
clientHelper.addLocalMessage(p.getMessage(), meta, true);
meta.put(MSG_KEY_READ, true);
clientHelper.addLocalMessage(txn, p.getMessage(), meta, true);
trackOutgoingMessage(txn, p.getMessage());
txn.setComplete();
} catch (FormatException e) {
throw new RuntimeException(e);
} finally {
db.endTransaction(txn);
}
}
@@ -230,17 +235,6 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
}
}
@Override
public void setReadFlag(MessageId m, boolean read) throws DbException {
try {
BdfDictionary meta = new BdfDictionary();
meta.put(KEY_READ, read);
clientHelper.mergeMessageMetadata(m, meta);
} catch (FormatException e) {
throw new RuntimeException(e);
}
}
@Override
public void registerRemoveForumHook(RemoveForumHook hook) {
removeHooks.add(hook);
@@ -281,7 +275,7 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
status = identityManager.getAuthorStatus(txn, author.getId());
}
}
boolean read = meta.getBoolean(KEY_READ);
boolean read = meta.getBoolean(MSG_KEY_READ);
return new ForumPostHeader(id, parentId, timestamp, author, status,
read);

View File

@@ -60,7 +60,6 @@ import static org.briarproject.api.introduction.IntroductionConstants.MESSAGE_TI
import static org.briarproject.api.introduction.IntroductionConstants.MSG;
import static org.briarproject.api.introduction.IntroductionConstants.NAME;
import static org.briarproject.api.introduction.IntroductionConstants.NOT_OUR_RESPONSE;
import static org.briarproject.api.introduction.IntroductionConstants.READ;
import static org.briarproject.api.introduction.IntroductionConstants.REMOTE_AUTHOR_ID;
import static org.briarproject.api.introduction.IntroductionConstants.REMOTE_AUTHOR_IS_US;
import static org.briarproject.api.introduction.IntroductionConstants.RESPONSE_1;
@@ -75,6 +74,7 @@ import static org.briarproject.api.introduction.IntroductionConstants.TYPE_ABORT
import static org.briarproject.api.introduction.IntroductionConstants.TYPE_ACK;
import static org.briarproject.api.introduction.IntroductionConstants.TYPE_REQUEST;
import static org.briarproject.api.introduction.IntroductionConstants.TYPE_RESPONSE;
import static org.briarproject.clients.BdfConstants.MSG_KEY_READ;
class IntroductionManagerImpl extends BdfIncomingMessageHook
implements IntroductionManager, Client, AddContactHook,
@@ -87,7 +87,6 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
private static final Logger LOG =
Logger.getLogger(IntroductionManagerImpl.class.getName());
private final DatabaseComponent db;
private final IntroducerManager introducerManager;
private final IntroduceeManager introduceeManager;
private final IntroductionGroupFactory introductionGroupFactory;
@@ -98,8 +97,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
IntroduceeManager introduceeManager,
IntroductionGroupFactory introductionGroupFactory) {
super(clientHelper, metadataParser);
this.db = db;
super(db, clientHelper, metadataParser);
this.introducerManager = introducerManager;
this.introduceeManager = introduceeManager;
this.introductionGroupFactory = introductionGroupFactory;
@@ -208,7 +206,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
*/
@Override
protected boolean incomingMessage(Transaction txn, Message m, BdfList body,
BdfDictionary message) throws DbException {
BdfDictionary message) throws DbException {
// Get message data and type
GroupId groupId = m.getGroupId();
@@ -237,6 +235,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
}
try {
introduceeManager.incomingMessage(txn, state, message);
trackIncomingMessage(txn, m);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
introduceeManager.abort(txn, state);
@@ -270,6 +269,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
deleteMessage(txn, m.getId());
}
}
if (type == TYPE_RESPONSE) trackIncomingMessage(txn, m);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
if (role == ROLE_INTRODUCER) introducerManager.abort(txn, state);
@@ -296,6 +296,10 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
Transaction txn = db.startTransaction(false);
try {
introducerManager.makeIntroduction(txn, c1, c2, msg, timestamp);
Group g1 = introductionGroupFactory.createIntroductionGroup(c1);
Group g2 = introductionGroupFactory.createIntroductionGroup(c2);
trackMessage(txn, g1.getId(), timestamp, true);
trackMessage(txn, g2.getId(), timestamp, true);
txn.setComplete();
} finally {
db.endTransaction(txn);
@@ -315,6 +319,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
getSessionState(txn, g.getId(), sessionId.getBytes());
introduceeManager.acceptIntroduction(txn, state, timestamp);
trackMessage(txn, g.getId(), timestamp, true);
txn.setComplete();
} finally {
db.endTransaction(txn);
@@ -334,6 +339,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
getSessionState(txn, g.getId(), sessionId.getBytes());
introduceeManager.declineIntroduction(txn, state, timestamp);
trackMessage(txn, g.getId(), timestamp, true);
txn.setComplete();
} finally {
db.endTransaction(txn);
@@ -377,7 +383,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
boolean local;
long time = msg.getLong(MESSAGE_TIME);
boolean accepted = msg.getBoolean(ACCEPT, false);
boolean read = msg.getBoolean(READ, false);
boolean read = msg.getBoolean(MSG_KEY_READ, false);
AuthorId authorId;
String name;
if (type == TYPE_RESPONSE) {

View File

@@ -33,6 +33,8 @@ import java.util.Map;
import javax.inject.Inject;
import static org.briarproject.clients.BdfConstants.MSG_KEY_READ;
class MessagingManagerImpl extends BdfIncomingMessageHook
implements MessagingManager, Client, AddContactHook, RemoveContactHook {
@@ -40,16 +42,13 @@ class MessagingManagerImpl extends BdfIncomingMessageHook
"6bcdc006c0910b0f44e40644c3b31f1a"
+ "8bf9a6d6021d40d219c86b731b903070"));
private final DatabaseComponent db;
private final ContactGroupFactory contactGroupFactory;
@Inject
MessagingManagerImpl(DatabaseComponent db, ClientHelper clientHelper,
MetadataParser metadataParser,
ContactGroupFactory contactGroupFactory) {
super(clientHelper, metadataParser);
this.db = db;
super(db, clientHelper, metadataParser);
this.contactGroupFactory = contactGroupFactory;
}
@@ -100,12 +99,13 @@ class MessagingManagerImpl extends BdfIncomingMessageHook
long timestamp = meta.getLong("timestamp");
String contentType = meta.getString("contentType");
boolean local = meta.getBoolean("local");
boolean read = meta.getBoolean("read");
boolean read = meta.getBoolean(MSG_KEY_READ);
PrivateMessageHeader header = new PrivateMessageHeader(
m.getId(), timestamp, contentType, local, read, false, false);
PrivateMessageReceivedEvent event = new PrivateMessageReceivedEvent(
header, groupId);
txn.attach(event);
trackIncomingMessage(txn, m);
// don't share message
return false;
@@ -113,6 +113,7 @@ class MessagingManagerImpl extends BdfIncomingMessageHook
@Override
public void addLocalMessage(PrivateMessage m) throws DbException {
Transaction txn = db.startTransaction(false);
try {
BdfDictionary meta = new BdfDictionary();
meta.put("timestamp", m.getMessage().getTimestamp());
@@ -120,9 +121,13 @@ class MessagingManagerImpl extends BdfIncomingMessageHook
meta.put("contentType", m.getContentType());
meta.put("local", true);
meta.put("read", true);
clientHelper.addLocalMessage(m.getMessage(), meta, true);
clientHelper.addLocalMessage(txn, m.getMessage(), meta, true);
trackOutgoingMessage(txn, m.getMessage());
txn.setComplete();
} catch (FormatException e) {
throw new RuntimeException(e);
} finally {
db.endTransaction(txn);
}
}
@@ -196,14 +201,4 @@ class MessagingManagerImpl extends BdfIncomingMessageHook
}
}
@Override
public void setReadFlag(MessageId m, boolean read) throws DbException {
try {
BdfDictionary meta = new BdfDictionary();
meta.put("read", read);
clientHelper.mergeMessageMetadata(m, meta);
} catch (FormatException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -14,6 +14,7 @@ import org.briarproject.clients.BdfMessageValidator;
import static org.briarproject.api.messaging.MessagingConstants.MAX_CONTENT_TYPE_LENGTH;
import static org.briarproject.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_BODY_LENGTH;
import static org.briarproject.clients.BdfConstants.MSG_KEY_READ;
class PrivateMessageValidator extends BdfMessageValidator {
@@ -42,7 +43,7 @@ class PrivateMessageValidator extends BdfMessageValidator {
if (parentId != null) meta.put("parent", parentId);
meta.put("contentType", contentType);
meta.put("local", false);
meta.put("read", false);
meta.put(MSG_KEY_READ, false);
return new BdfMessageContext(meta);
}
}

View File

@@ -28,8 +28,6 @@ import java.util.Collections;
import javax.inject.Inject;
import static org.briarproject.privategroup.Constants.KEY_READ;
public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
PrivateGroupManager {
@@ -37,7 +35,6 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
StringUtils.fromHexString("5072697661746547726f75704d616e61"
+ "67657220627920546f727374656e2047"));
private final DatabaseComponent db;
private final IdentityManager identityManager;
private final PrivateGroupFactory privateGroupFactory;
@@ -46,9 +43,8 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
MetadataParser metadataParser, DatabaseComponent db,
IdentityManager identityManager,
PrivateGroupFactory privateGroupFactory) {
super(clientHelper, metadataParser);
super(db, clientHelper, metadataParser);
this.db = db;
this.identityManager = identityManager;
this.privateGroupFactory = privateGroupFactory;
}
@@ -61,11 +57,16 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
@Override
public void addLocalMessage(GroupMessage m) throws DbException {
Transaction txn = db.startTransaction(false);
try {
BdfDictionary meta = new BdfDictionary();
clientHelper.addLocalMessage(m.getMessage(), meta, true);
clientHelper.addLocalMessage(txn, m.getMessage(), meta, true);
trackOutgoingMessage(txn, m.getMessage());
txn.setComplete();
} catch (FormatException e) {
throw new DbException(e);
} finally {
db.endTransaction(txn);
}
}
@@ -104,21 +105,12 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
return Collections.emptyList();
}
@Override
public void setReadFlag(MessageId m, boolean read) throws DbException {
try {
BdfDictionary meta = new BdfDictionary();
meta.put(KEY_READ, read);
clientHelper.mergeMessageMetadata(m, meta);
} catch (FormatException e) {
throw new RuntimeException(e);
}
}
@Override
protected boolean incomingMessage(Transaction txn, Message m, BdfList body,
BdfDictionary meta) throws DbException, FormatException {
trackIncomingMessage(txn, m);
return true;
}

View File

@@ -58,7 +58,6 @@ import static org.briarproject.api.clients.ProtocolEngine.StateUpdate;
import static org.briarproject.api.sharing.SharingConstants.CONTACT_ID;
import static org.briarproject.api.sharing.SharingConstants.IS_SHARER;
import static org.briarproject.api.sharing.SharingConstants.LOCAL;
import static org.briarproject.api.sharing.SharingConstants.READ;
import static org.briarproject.api.sharing.SharingConstants.SESSION_ID;
import static org.briarproject.api.sharing.SharingConstants.SHAREABLE_ID;
import static org.briarproject.api.sharing.SharingConstants.SHARED_BY_US;
@@ -83,6 +82,7 @@ import static org.briarproject.api.sharing.SharingConstants.TO_BE_SHARED_BY_US;
import static org.briarproject.api.sharing.SharingConstants.TYPE;
import static org.briarproject.api.sharing.SharingMessage.BaseMessage;
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;
abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS extends InviteeSessionState, SS extends SharerSessionState, IR extends InvitationReceivedEvent, IRR extends InvitationResponseReceivedEvent>
@@ -93,7 +93,6 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
private static final Logger LOG =
Logger.getLogger(SharingManagerImpl.class.getName());
private final DatabaseComponent db;
private final MessageQueueManager messageQueueManager;
private final MetadataEncoder metadataEncoder;
private final SecureRandom random;
@@ -106,9 +105,8 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
MetadataParser metadataParser, MetadataEncoder metadataEncoder,
SecureRandom random, ContactGroupFactory contactGroupFactory,
Clock clock) {
super(db, clientHelper, metadataParser);
super(clientHelper, metadataParser);
this.db = db;
this.messageQueueManager = messageQueueManager;
this.metadataEncoder = metadataEncoder;
this.random = random;
@@ -226,6 +224,7 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
new InviteeEngine<IS, IR>(getIRFactory());
processInviteeStateUpdate(txn, m.getId(),
engine.onMessageReceived(state, msg));
trackIncomingMessage(txn, m);
} catch (FormatException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
deleteMessage(txn, m.getId());
@@ -239,6 +238,7 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
getIRRFactory());
processSharerStateUpdate(txn, m.getId(),
engine.onMessageReceived(state, msg));
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
@@ -290,6 +290,10 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
engine.onLocalAction(localState,
SharerSessionState.Action.LOCAL_INVITATION));
// track message
long time = clock.currentTimeMillis();
trackMessage(txn, localState.getGroupId(), time, true);
txn.setComplete();
} catch (FormatException e) {
throw new DbException();
@@ -321,6 +325,10 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
processInviteeStateUpdate(txn, null,
engine.onLocalAction(localState, localAction));
// track message
long time = clock.currentTimeMillis();
trackMessage(txn, localState.getGroupId(), time, true);
txn.setComplete();
} catch (FormatException e) {
throw new DbException(e);
@@ -352,7 +360,7 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
db.getMessageStatus(txn, contactId, m.getKey());
long time = d.getLong(TIME);
boolean local = d.getBoolean(LOCAL);
boolean read = d.getBoolean(READ, false);
boolean read = d.getBoolean(MSG_KEY_READ, false);
boolean available = false;
if (type == SHARE_MSG_TYPE_INVITATION) {

View File

@@ -4,28 +4,24 @@ import org.briarproject.BriarTestCase;
import org.briarproject.TestUtils;
import org.briarproject.api.FormatException;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.MessageQueueManager;
import org.briarproject.api.clients.ContactGroupFactory;
import org.briarproject.api.clients.SessionId;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.data.BdfDictionary;
import org.briarproject.api.data.BdfEntry;
import org.briarproject.api.data.BdfList;
import org.briarproject.api.data.MetadataEncoder;
import org.briarproject.api.data.MetadataParser;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
import org.briarproject.api.db.Transaction;
import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.clients.SessionId;
import org.briarproject.api.sync.ClientId;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageId;
import org.briarproject.api.sync.MessageStatus;
import org.briarproject.api.system.Clock;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.jmock.lib.legacy.ClassImposteriser;
@@ -46,30 +42,29 @@ import static org.briarproject.api.introduction.IntroductionConstants.TYPE;
import static org.briarproject.api.introduction.IntroductionConstants.TYPE_REQUEST;
import static org.briarproject.api.introduction.IntroductionConstants.TYPE_RESPONSE;
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.junit.Assert.assertFalse;
public class IntroductionManagerImplTest extends BriarTestCase {
final Mockery context;
final IntroductionManagerImpl introductionManager;
final IntroducerManager introducerManager;
final IntroduceeManager introduceeManager;
final DatabaseComponent db;
final ContactGroupFactory contactGroupFactory;
final ClientHelper clientHelper;
final MetadataEncoder metadataEncoder;
final MessageQueueManager messageQueueManager;
final IntroductionGroupFactory introductionGroupFactory;
final Clock clock;
final SessionId sessionId = new SessionId(TestUtils.getRandomId());
final long time = 42L;
final Contact introducee1;
final Contact introducee2;
final Group localGroup0;
final Group introductionGroup1;
final Group introductionGroup2;
final Message message1;
Transaction txn;
private final Mockery context;
private final IntroductionManagerImpl introductionManager;
private final IntroducerManager introducerManager;
private final IntroduceeManager introduceeManager;
private final DatabaseComponent db;
private final ClientHelper clientHelper;
private final IntroductionGroupFactory introductionGroupFactory;
private final SessionId sessionId = new SessionId(TestUtils.getRandomId());
private final long time = 42L;
private final Contact introducee1;
private final Contact introducee2;
private final Group introductionGroup1;
private final Group introductionGroup2;
private final Message message1;
private Transaction txn;
private BdfDictionary metadataBefore, metadataAfter;
public IntroductionManagerImplTest() {
AuthorId authorId1 = new AuthorId(TestUtils.getRandomId());
@@ -89,8 +84,6 @@ public class IntroductionManagerImplTest extends BriarTestCase {
new Contact(contactId2, author2, localAuthorId2, true, true);
ClientId clientId = new ClientId(TestUtils.getRandomId());
localGroup0 = new Group(new GroupId(TestUtils.getRandomId()),
clientId, new byte[0]);
introductionGroup1 = new Group(new GroupId(TestUtils.getRandomId()),
clientId, new byte[0]);
introductionGroup2 = new Group(new GroupId(TestUtils.getRandomId()),
@@ -102,6 +95,14 @@ public class IntroductionManagerImplTest extends BriarTestCase {
time,
TestUtils.getRandomBytes(MESSAGE_HEADER_LENGTH + 1)
);
metadataBefore = BdfDictionary.of(
new BdfEntry(GROUP_KEY_MSG_COUNT, 41L),
new BdfEntry(GROUP_KEY_LATEST_MSG, 0L)
);
metadataAfter = BdfDictionary.of(
new BdfEntry(GROUP_KEY_MSG_COUNT, 42L),
new BdfEntry(GROUP_KEY_LATEST_MSG, time)
);
// mock ALL THE THINGS!!!
context = new Mockery();
@@ -109,15 +110,9 @@ public class IntroductionManagerImplTest extends BriarTestCase {
introducerManager = context.mock(IntroducerManager.class);
introduceeManager = context.mock(IntroduceeManager.class);
db = context.mock(DatabaseComponent.class);
contactGroupFactory = context.mock(ContactGroupFactory.class);
clientHelper = context.mock(ClientHelper.class);
metadataEncoder =
context.mock(MetadataEncoder.class);
messageQueueManager =
context.mock(MessageQueueManager.class);
MetadataParser metadataParser = context.mock(MetadataParser.class);
introductionGroupFactory = context.mock(IntroductionGroupFactory.class);
clock = context.mock(Clock.class);
introductionManager = new IntroductionManagerImpl(
db, clientHelper, metadataParser, introducerManager,
@@ -135,6 +130,27 @@ public class IntroductionManagerImplTest extends BriarTestCase {
oneOf(introducerManager)
.makeIntroduction(txn, introducee1, introducee2, null,
time);
// get both introduction groups
oneOf(introductionGroupFactory)
.createIntroductionGroup(introducee1);
will(returnValue(introductionGroup1));
oneOf(introductionGroupFactory)
.createIntroductionGroup(introducee2);
will(returnValue(introductionGroup2));
// track message for group 1
oneOf(clientHelper).getGroupMetadataAsDictionary(txn,
introductionGroup1.getId());
will(returnValue(metadataBefore));
oneOf(clientHelper)
.mergeGroupMetadata(txn, introductionGroup1.getId(),
metadataAfter);
// track message for group 2
oneOf(clientHelper).getGroupMetadataAsDictionary(txn,
introductionGroup2.getId());
will(returnValue(metadataBefore));
oneOf(clientHelper)
.mergeGroupMetadata(txn, introductionGroup2.getId(),
metadataAfter);
oneOf(db).endTransaction(txn);
}});
@@ -163,6 +179,13 @@ public class IntroductionManagerImplTest extends BriarTestCase {
oneOf(clientHelper).getMessageMetadataAsDictionary(txn, sessionId);
will(returnValue(state));
oneOf(introduceeManager).acceptIntroduction(txn, state, time);
// track message
oneOf(clientHelper).getGroupMetadataAsDictionary(txn,
introductionGroup1.getId());
will(returnValue(metadataBefore));
oneOf(clientHelper)
.mergeGroupMetadata(txn, introductionGroup1.getId(),
metadataAfter);
oneOf(db).endTransaction(txn);
}});
@@ -191,6 +214,13 @@ public class IntroductionManagerImplTest extends BriarTestCase {
oneOf(clientHelper).getMessageMetadataAsDictionary(txn, sessionId);
will(returnValue(state));
oneOf(introduceeManager).declineIntroduction(txn, state, time);
// track message
oneOf(clientHelper).getGroupMetadataAsDictionary(txn,
introductionGroup1.getId());
will(returnValue(metadataBefore));
oneOf(clientHelper)
.mergeGroupMetadata(txn, introductionGroup1.getId(),
metadataAfter);
oneOf(db).endTransaction(txn);
}});
@@ -241,12 +271,22 @@ public class IntroductionManagerImplTest extends BriarTestCase {
final BdfDictionary state = new BdfDictionary();
txn = new Transaction(null, false);
metadataBefore.put(GROUP_KEY_UNREAD_COUNT, 1L);
metadataAfter.put(GROUP_KEY_UNREAD_COUNT, 2L);
context.checking(new Expectations() {{
oneOf(introduceeManager)
.initialize(txn, introductionGroup1.getId(), msg);
will(returnValue(state));
oneOf(introduceeManager)
.incomingMessage(txn, state, msg);
// track message
oneOf(clientHelper).getGroupMetadataAsDictionary(txn,
introductionGroup1.getId());
will(returnValue(metadataBefore));
oneOf(clientHelper)
.mergeGroupMetadata(txn, introductionGroup1.getId(),
metadataAfter);
}});
introductionManager
@@ -272,10 +312,20 @@ public class IntroductionManagerImplTest extends BriarTestCase {
txn = new Transaction(null, false);
metadataBefore.put(GROUP_KEY_UNREAD_COUNT, 41L);
metadataAfter.put(GROUP_KEY_UNREAD_COUNT, 42L);
context.checking(new Expectations() {{
oneOf(clientHelper).getMessageMetadataAsDictionary(txn, sessionId);
will(returnValue(state));
oneOf(introducerManager).incomingMessage(txn, state, msg);
// track message
oneOf(clientHelper).getGroupMetadataAsDictionary(txn,
introductionGroup1.getId());
will(returnValue(metadataBefore));
oneOf(clientHelper)
.mergeGroupMetadata(txn, introductionGroup1.getId(),
metadataAfter);
}});
introductionManager