Skip to content
Snippets Groups Projects
Commit 29b67d2e authored by akwizgran's avatar akwizgran
Browse files

Merge branch 'forum-sharing-hooks' into 'master'

Use message validation hook in forum sharing client

This patch moves the forum sharing client's update handling from an event handler to a hook to ensure the update is handled even if it arrives just before shutdown.

See merge request !99
parents 00beb654 bb11ebd5
No related branches found
No related tags found
No related merge requests found
......@@ -9,7 +9,6 @@ import org.briarproject.api.data.BdfReaderFactory;
import org.briarproject.api.data.BdfWriterFactory;
import org.briarproject.api.data.MetadataEncoder;
import org.briarproject.api.data.ObjectReader;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.forum.ForumManager;
import org.briarproject.api.forum.ForumPostFactory;
import org.briarproject.api.forum.ForumSharingManager;
......@@ -56,10 +55,11 @@ public class ForumModule extends AbstractModule {
@Provides @Singleton
ForumSharingManager getForumSharingManager(ContactManager contactManager,
EventBus eventBus, ForumSharingManagerImpl forumSharingManager) {
ValidationManager validationManager,
ForumSharingManagerImpl forumSharingManager) {
contactManager.registerAddContactHook(forumSharingManager);
contactManager.registerRemoveContactHook(forumSharingManager);
eventBus.addListener(forumSharingManager);
validationManager.registerValidationHook(forumSharingManager);
return forumSharingManager;
}
}
......@@ -16,12 +16,8 @@ import org.briarproject.api.data.BdfWriterFactory;
import org.briarproject.api.data.MetadataEncoder;
import org.briarproject.api.data.MetadataParser;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DatabaseExecutor;
import org.briarproject.api.db.DbException;
import org.briarproject.api.db.Metadata;
import org.briarproject.api.event.Event;
import org.briarproject.api.event.EventListener;
import org.briarproject.api.event.MessageValidatedEvent;
import org.briarproject.api.forum.Forum;
import org.briarproject.api.forum.ForumManager;
import org.briarproject.api.forum.ForumSharingManager;
......@@ -33,6 +29,7 @@ import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageFactory;
import org.briarproject.api.sync.MessageId;
import org.briarproject.api.sync.PrivateGroupFactory;
import org.briarproject.api.sync.ValidationManager.ValidationHook;
import org.briarproject.api.system.Clock;
import org.briarproject.util.StringUtils;
......@@ -48,7 +45,6 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.logging.Logger;
......@@ -58,7 +54,7 @@ import static org.briarproject.api.forum.ForumConstants.MAX_FORUM_NAME_LENGTH;
import static org.briarproject.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
class ForumSharingManagerImpl implements ForumSharingManager, AddContactHook,
RemoveContactHook, EventListener {
RemoveContactHook, ValidationHook {
static final ClientId CLIENT_ID = new ClientId(StringUtils.fromHexString(
"cd11a5d04dccd9e2931d6fc3df456313"
......@@ -70,7 +66,6 @@ class ForumSharingManagerImpl implements ForumSharingManager, AddContactHook,
Logger.getLogger(ForumSharingManagerImpl.class.getName());
private final DatabaseComponent db;
private final Executor dbExecutor;
private final ContactManager contactManager;
private final ForumManager forumManager;
private final GroupFactory groupFactory;
......@@ -89,14 +84,12 @@ class ForumSharingManagerImpl implements ForumSharingManager, AddContactHook,
@Inject
ForumSharingManagerImpl(DatabaseComponent db,
@DatabaseExecutor Executor dbExecutor,
ContactManager contactManager, ForumManager forumManager,
GroupFactory groupFactory, PrivateGroupFactory privateGroupFactory,
MessageFactory messageFactory, BdfReaderFactory bdfReaderFactory,
BdfWriterFactory bdfWriterFactory, MetadataEncoder metadataEncoder,
MetadataParser metadataParser, SecureRandom random, Clock clock) {
this.db = db;
this.dbExecutor = dbExecutor;
this.contactManager = contactManager;
this.forumManager = forumManager;
this.groupFactory = groupFactory;
......@@ -150,12 +143,21 @@ class ForumSharingManagerImpl implements ForumSharingManager, AddContactHook,
}
@Override
public void eventOccurred(Event e) {
if (e instanceof MessageValidatedEvent) {
MessageValidatedEvent m = (MessageValidatedEvent) e;
ClientId c = m.getClientId();
if (m.isValid() && !m.isLocal() && c.equals(CLIENT_ID))
remoteForumsUpdated(m.getMessage().getGroupId());
public void validatingMessage(Message m, ClientId c, Metadata meta) {
if (c.equals(CLIENT_ID)) {
lock.writeLock().lock();
try {
ContactId contactId = getContactId(m.getGroupId());
setForumVisibility(contactId, getVisibleForums(m));
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
} catch (FormatException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
} finally {
lock.writeLock().unlock();
}
}
}
......@@ -416,47 +418,25 @@ class ForumSharingManagerImpl implements ForumSharingManager, AddContactHook,
return out.toByteArray();
}
private void remoteForumsUpdated(final GroupId g) {
dbExecutor.execute(new Runnable() {
public void run() {
lock.writeLock().lock();
try {
setForumVisibility(getContactId(g), getVisibleForums(g));
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
} catch (FormatException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
} finally {
lock.writeLock().unlock();
}
}
});
}
// Locking: lock.readLock
private ContactId getContactId(GroupId contactGroupId) throws DbException,
FormatException {
Metadata meta = db.getGroupMetadata(contactGroupId);
BdfDictionary d = metadataParser.parse(meta);
int id = d.getInteger("contactId").intValue();
return new ContactId(id);
return new ContactId(d.getInteger("contactId").intValue());
}
// Locking: lock.readLock
private Set<GroupId> getVisibleForums(GroupId contactGroupId)
private Set<GroupId> getVisibleForums(Message remoteUpdate)
throws DbException, FormatException {
// Get the latest local and remote updates
LatestUpdate local = findLatest(contactGroupId, true);
LatestUpdate remote = findLatest(contactGroupId, false);
// If there's no local and/or remote update, no forums are visible
if (local == null || remote == null) return Collections.emptySet();
// Get the latest local update
LatestUpdate local = findLatest(remoteUpdate.getGroupId(), true);
// If there's no local update, no forums are visible
if (local == null) return Collections.emptySet();
// Intersect the sets of shared forums
byte[] localRaw = db.getRawMessage(local.messageId);
Set<Forum> shared = new HashSet<Forum>(parseForumList(localRaw));
byte[] remoteRaw = db.getRawMessage(remote.messageId);
shared.retainAll(parseForumList(remoteRaw));
shared.retainAll(parseForumList(remoteUpdate.getRaw()));
// Forums in the intersection should be visible
Set<GroupId> visible = new HashSet<GroupId>(shared.size());
for (Forum f : shared) visible.add(f.getId());
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment