Create a basic ConversationManager for querying GroupCount

This is also lays the groundwork for #384
This commit is contained in:
Torsten Grote
2016-10-05 14:38:51 -03:00
parent 457c30f3f2
commit f52819f4ca
14 changed files with 214 additions and 23 deletions

View File

@@ -17,6 +17,7 @@ import org.briarproject.event.EventModule;
import org.briarproject.forum.ForumModule;
import org.briarproject.identity.IdentityModule;
import org.briarproject.lifecycle.LifecycleModule;
import org.briarproject.messaging.MessagingModule;
import org.briarproject.properties.PropertiesModule;
import org.briarproject.sharing.SharingModule;
import org.briarproject.sync.SyncModule;
@@ -46,7 +47,8 @@ import dagger.Component;
SharingModule.class,
SyncModule.class,
SystemModule.class,
TransportModule.class
TransportModule.class,
MessagingModule.class
})
interface BlogSharingIntegrationTestComponent {

View File

@@ -17,6 +17,7 @@ import org.briarproject.event.EventModule;
import org.briarproject.forum.ForumModule;
import org.briarproject.identity.IdentityModule;
import org.briarproject.lifecycle.LifecycleModule;
import org.briarproject.messaging.MessagingModule;
import org.briarproject.properties.PropertiesModule;
import org.briarproject.sharing.SharingModule;
import org.briarproject.sync.SyncModule;
@@ -46,7 +47,8 @@ import dagger.Component;
SharingModule.class,
SyncModule.class,
SystemModule.class,
TransportModule.class
TransportModule.class,
MessagingModule.class
})
interface ForumManagerTestComponent {

View File

@@ -21,6 +21,7 @@ import org.briarproject.event.EventModule;
import org.briarproject.forum.ForumModule;
import org.briarproject.identity.IdentityModule;
import org.briarproject.lifecycle.LifecycleModule;
import org.briarproject.messaging.MessagingModule;
import org.briarproject.properties.PropertiesModule;
import org.briarproject.sharing.SharingModule;
import org.briarproject.sync.SyncModule;
@@ -50,7 +51,8 @@ import dagger.Component;
SharingModule.class,
SyncModule.class,
SystemModule.class,
TransportModule.class
TransportModule.class,
MessagingModule.class
})
interface ForumSharingIntegrationTestComponent {

View File

@@ -20,6 +20,7 @@ import org.briarproject.db.DatabaseModule;
import org.briarproject.event.EventModule;
import org.briarproject.identity.IdentityModule;
import org.briarproject.lifecycle.LifecycleModule;
import org.briarproject.messaging.MessagingModule;
import org.briarproject.properties.PropertiesModule;
import org.briarproject.sync.SyncModule;
import org.briarproject.system.SystemModule;
@@ -46,7 +47,8 @@ import dagger.Component;
SyncModule.class,
SystemModule.class,
DataModule.class,
PropertiesModule.class
PropertiesModule.class,
MessagingModule.class
})
public interface IntroductionIntegrationTestComponent {

View File

@@ -0,0 +1,28 @@
package org.briarproject.api.messaging;
import org.briarproject.api.clients.MessageTracker.GroupCount;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.db.DbException;
import org.briarproject.api.db.Transaction;
import org.briarproject.api.sync.GroupId;
public interface ConversationManager {
/**
* Clients that present messages in a private conversation need to
* register themselves here.
*/
void registerConversationClient(ConversationClient client);
/** Get the main group ID that represents this conversation */
GroupId getConversationId(ContactId contactId) throws DbException;
/** Get the unified group count for all private conversation messages. */
GroupCount getGroupCount(ContactId contactId) throws DbException;
interface ConversationClient {
GroupCount getGroupCount(Transaction txn, ContactId contactId)
throws DbException;
}
}

View File

@@ -103,7 +103,7 @@ public abstract class BdfIncomingMessageHook implements IncomingMessageHook,
return count;
}
private GroupCount getGroupCount(Transaction txn, GroupId g)
protected GroupCount getGroupCount(Transaction txn, GroupId g)
throws DbException {
GroupCount count;
try {

View File

@@ -0,0 +1,34 @@
package org.briarproject.clients;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
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.messaging.ConversationManager;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.GroupId;
public abstract class ConversationClient extends BdfIncomingMessageHook
implements ConversationManager.ConversationClient {
protected ConversationClient(DatabaseComponent db,
ClientHelper clientHelper, MetadataParser metadataParser) {
super(db, clientHelper, metadataParser);
}
// TODO overwrite super methods to store GroupCount data in a single group
protected abstract Group getContactGroup(Contact contact);
@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

@@ -29,7 +29,7 @@ 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.clients.BdfIncomingMessageHook;
import org.briarproject.clients.ConversationClient;
import org.briarproject.util.StringUtils;
import java.io.IOException;
@@ -76,7 +76,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;
class IntroductionManagerImpl extends BdfIncomingMessageHook
class IntroductionManagerImpl extends ConversationClient
implements IntroductionManager, Client, AddContactHook,
RemoveContactHook {
@@ -119,7 +119,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
public void addingContact(Transaction txn, Contact c) throws DbException {
try {
// Create an introduction group for sending introduction messages
Group g = introductionGroupFactory.createIntroductionGroup(c);
Group g = getContactGroup(c);
// Return if we've already set things up for this contact
if (db.containsGroup(txn, g.getId())) return;
// Store the group and share it with the contact
@@ -196,7 +196,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
// remove the group (all messages will be removed with it)
// this contact won't get our abort message, but the other will
db.removeGroup(txn, introductionGroupFactory.createIntroductionGroup(c));
db.removeGroup(txn, getContactGroup(c));
}
/**
@@ -288,6 +288,11 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
return false;
}
@Override
protected Group getContactGroup(Contact contact) {
return introductionGroupFactory.createIntroductionGroup(contact);
}
@Override
public void makeIntroduction(Contact c1, Contact c2, String msg,
final long timestamp)
@@ -296,8 +301,8 @@ 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);
Group g1 = getContactGroup(c1);
Group g2 = getContactGroup(c2);
trackMessage(txn, g1.getId(), timestamp, true);
trackMessage(txn, g2.getId(), timestamp, true);
txn.setComplete();
@@ -314,7 +319,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
Transaction txn = db.startTransaction(false);
try {
Contact c = db.getContact(txn, contactId);
Group g = introductionGroupFactory.createIntroductionGroup(c);
Group g = getContactGroup(c);
BdfDictionary state =
getSessionState(txn, g.getId(), sessionId.getBytes());
@@ -334,7 +339,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
Transaction txn = db.startTransaction(false);
try {
Contact c = db.getContact(txn, contactId);
Group g = introductionGroupFactory.createIntroductionGroup(c);
Group g = getContactGroup(c);
BdfDictionary state =
getSessionState(txn, g.getId(), sessionId.getBytes());
@@ -358,9 +363,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
Transaction txn = db.startTransaction(true);
try {
// get messages and their status
GroupId g = introductionGroupFactory
.createIntroductionGroup(db.getContact(txn, contactId))
.getId();
GroupId g = getContactGroup(db.getContact(txn, contactId)).getId();
metadata = clientHelper.getMessageMetadataAsDictionary(txn, g);
statuses = db.getMessageStatus(txn, contactId, g);

View File

@@ -6,6 +6,7 @@ import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.data.MetadataEncoder;
import org.briarproject.api.introduction.IntroductionManager;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.messaging.ConversationManager;
import org.briarproject.api.system.Clock;
import javax.inject.Inject;
@@ -47,6 +48,7 @@ public class IntroductionModule {
LifecycleManager lifecycleManager,
ContactManager contactManager,
MessageQueueManager messageQueueManager,
ConversationManager conversationManager,
IntroductionManagerImpl introductionManager) {
lifecycleManager.registerClient(introductionManager);
@@ -55,6 +57,7 @@ public class IntroductionModule {
messageQueueManager.registerIncomingMessageHook(
introductionManager.getClientId(),
introductionManager);
conversationManager.registerConversationClient(introductionManager);
return introductionManager;
}

View File

@@ -0,0 +1,76 @@
package org.briarproject.messaging;
import org.briarproject.api.clients.ContactGroupFactory;
import org.briarproject.api.clients.MessageTracker.GroupCount;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
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.sync.Group;
import org.briarproject.api.sync.GroupId;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import javax.inject.Inject;
class ConversationManagerImpl implements ConversationManager {
private final DatabaseComponent db;
private final ContactGroupFactory contactGroupFactory;
private final Set<ConversationClient> clients;
@Inject
ConversationManagerImpl(DatabaseComponent db,
ContactGroupFactory contactGroupFactory) {
this.db = db;
this.contactGroupFactory = contactGroupFactory;
clients = new CopyOnWriteArraySet<ConversationClient>();
}
@Override
public void registerConversationClient(ConversationClient client) {
clients.add(client);
}
@Override
public GroupId getConversationId(ContactId contactId) throws DbException {
// TODO we should probably transition this to its own group
// and/or work with the ContactId in the UI instead
Contact contact;
Transaction txn = db.startTransaction(true);
try {
contact = db.getContact(txn, contactId);
txn.setComplete();
} finally {
db.endTransaction(txn);
}
Group group = contactGroupFactory
.createContactGroup(MessagingManagerImpl.CLIENT_ID, contact);
return group.getId();
}
@Override
public GroupCount getGroupCount(ContactId contactId)
throws DbException {
long msgCount = 0, unreadCount = 0, latestTime = 0;
Transaction txn = db.startTransaction(true);
try {
for (ConversationClient client : clients) {
GroupCount count = client.getGroupCount(txn, contactId);
msgCount += count.getMsgCount();
unreadCount += count.getUnreadCount();
if (count.getLatestMsgTime() > latestTime)
latestTime = count.getLatestMsgTime();
}
txn.setComplete();
} finally {
db.endTransaction(txn);
}
return new GroupCount(msgCount, unreadCount, latestTime);
}
}

View File

@@ -24,7 +24,7 @@ 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.clients.BdfIncomingMessageHook;
import org.briarproject.clients.ConversationClient;
import org.briarproject.util.StringUtils;
import java.util.ArrayList;
@@ -35,7 +35,7 @@ import javax.inject.Inject;
import static org.briarproject.clients.BdfConstants.MSG_KEY_READ;
class MessagingManagerImpl extends BdfIncomingMessageHook
class MessagingManagerImpl extends ConversationClient
implements MessagingManager, Client, AddContactHook, RemoveContactHook {
static final ClientId CLIENT_ID = new ClientId(StringUtils.fromHexString(
@@ -77,7 +77,8 @@ class MessagingManagerImpl extends BdfIncomingMessageHook
}
}
private Group getContactGroup(Contact c) {
@Override
protected Group getContactGroup(Contact c) {
return contactGroupFactory.createContactGroup(CLIENT_ID, c);
}
@@ -203,4 +204,14 @@ class MessagingManagerImpl extends BdfIncomingMessageHook
}
}
@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

@@ -4,6 +4,7 @@ import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.data.MetadataEncoder;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.messaging.ConversationManager;
import org.briarproject.api.messaging.MessagingManager;
import org.briarproject.api.messaging.PrivateMessageFactory;
import org.briarproject.api.sync.ValidationManager;
@@ -22,6 +23,7 @@ public class MessagingModule {
public static class EagerSingletons {
@Inject MessagingManager messagingManager;
@Inject ConversationManager conversationManager;
@Inject PrivateMessageValidator privateMessageValidator;
}
@@ -46,12 +48,22 @@ public class MessagingModule {
@Singleton
MessagingManager getMessagingManager(LifecycleManager lifecycleManager,
ContactManager contactManager, ValidationManager validationManager,
ConversationManager conversationManager,
MessagingManagerImpl messagingManager) {
lifecycleManager.registerClient(messagingManager);
contactManager.registerAddContactHook(messagingManager);
contactManager.registerRemoveContactHook(messagingManager);
validationManager
.registerIncomingMessageHook(CLIENT_ID, messagingManager);
conversationManager.registerConversationClient(messagingManager);
return messagingManager;
}
@Provides
@Singleton
ConversationManager getConversationManager(
ConversationManagerImpl conversationManager) {
return conversationManager;
}
}

View File

@@ -4,8 +4,8 @@ import org.briarproject.api.Bytes;
import org.briarproject.api.FormatException;
import org.briarproject.api.clients.Client;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.MessageQueueManager;
import org.briarproject.api.clients.ContactGroupFactory;
import org.briarproject.api.clients.MessageQueueManager;
import org.briarproject.api.clients.SessionId;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
@@ -36,7 +36,7 @@ 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.briarproject.clients.BdfIncomingMessageHook;
import org.briarproject.clients.ConversationClient;
import org.briarproject.util.StringUtils;
import java.io.IOException;
@@ -86,7 +86,7 @@ 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>
extends BdfIncomingMessageHook
extends ConversationClient
implements SharingManager<S>, Client, AddContactHook,
RemoveContactHook {
@@ -565,6 +565,16 @@ 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)) {
@@ -922,7 +932,8 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
.sendMessage(txn, group, m.getTime(), body, meta);
}
private Group getContactGroup(Contact c) {
@Override
protected Group getContactGroup(Contact c) {
return contactGroupFactory.createContactGroup(getClientId(), c);
}

View File

@@ -9,6 +9,7 @@ import org.briarproject.api.data.MetadataEncoder;
import org.briarproject.api.forum.ForumManager;
import org.briarproject.api.forum.ForumSharingManager;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.messaging.ConversationManager;
import org.briarproject.api.system.Clock;
import javax.inject.Inject;
@@ -52,6 +53,7 @@ public class SharingModule {
LifecycleManager lifecycleManager,
ContactManager contactManager,
MessageQueueManager messageQueueManager,
ConversationManager conversationManager,
BlogManager blogManager,
BlogSharingManagerImpl blogSharingManager) {
@@ -60,6 +62,7 @@ public class SharingModule {
contactManager.registerRemoveContactHook(blogSharingManager);
messageQueueManager.registerIncomingMessageHook(
BlogSharingManagerImpl.CLIENT_ID, blogSharingManager);
conversationManager.registerConversationClient(blogSharingManager);
blogManager.registerRemoveBlogHook(blogSharingManager);
return blogSharingManager;
@@ -86,6 +89,7 @@ public class SharingModule {
LifecycleManager lifecycleManager,
ContactManager contactManager,
MessageQueueManager messageQueueManager,
ConversationManager conversationManager,
ForumManager forumManager,
ForumSharingManagerImpl forumSharingManager) {
@@ -94,6 +98,7 @@ public class SharingModule {
contactManager.registerRemoveContactHook(forumSharingManager);
messageQueueManager.registerIncomingMessageHook(
ForumSharingManagerImpl.CLIENT_ID, forumSharingManager);
conversationManager.registerConversationClient(forumSharingManager);
forumManager.registerRemoveForumHook(forumSharingManager);
return forumSharingManager;