Move post/message creation into clients

This way the forum and private group client do not need to keep track of
message timestamps themselves and do not need to interact with
post/message factories.
This commit is contained in:
Torsten Grote
2016-10-11 18:28:37 -03:00
parent 6db59ffce5
commit 7bf4aebdaf
12 changed files with 217 additions and 218 deletions

View File

@@ -19,7 +19,6 @@ import org.briarproject.api.db.DatabaseExecutor;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.feed.FeedManager;
import org.briarproject.api.forum.ForumManager;
import org.briarproject.api.forum.ForumPostFactory;
import org.briarproject.api.forum.ForumSharingManager;
import org.briarproject.api.identity.AuthorFactory;
import org.briarproject.api.identity.IdentityManager;
@@ -35,7 +34,6 @@ import org.briarproject.api.messaging.MessagingManager;
import org.briarproject.api.messaging.PrivateMessageFactory;
import org.briarproject.api.plugins.ConnectionRegistry;
import org.briarproject.api.plugins.PluginManager;
import org.briarproject.api.privategroup.GroupMessageFactory;
import org.briarproject.api.privategroup.PrivateGroupManager;
import org.briarproject.api.settings.SettingsManager;
import org.briarproject.plugins.AndroidPluginsModule;
@@ -97,16 +95,12 @@ public interface AndroidComponent extends CoreEagerSingletons {
PrivateGroupManager privateGroupManager();
GroupMessageFactory groupMessageFactory();
ForumManager forumManager();
ForumSharingManager forumSharingManager();
BlogSharingManager blogSharingManager();
ForumPostFactory forumPostFactory();
BlogManager blogManager();
BlogPostFactory blogPostFactory();

View File

@@ -3,13 +3,8 @@ package org.briarproject.android.forum;
import android.support.annotation.Nullable;
import org.briarproject.android.api.AndroidNotificationManager;
import org.briarproject.android.controller.handler.ResultExceptionHandler;
import org.briarproject.android.threaded.ThreadListControllerImpl;
import org.briarproject.api.FormatException;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.CryptoExecutor;
import org.briarproject.api.crypto.KeyParser;
import org.briarproject.api.crypto.PrivateKey;
import org.briarproject.api.db.DatabaseExecutor;
import org.briarproject.api.db.DbException;
import org.briarproject.api.event.Event;
@@ -18,47 +13,36 @@ import org.briarproject.api.event.ForumPostReceivedEvent;
import org.briarproject.api.forum.Forum;
import org.briarproject.api.forum.ForumManager;
import org.briarproject.api.forum.ForumPost;
import org.briarproject.api.forum.ForumPostFactory;
import org.briarproject.api.forum.ForumPostHeader;
import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageId;
import org.briarproject.util.StringUtils;
import java.security.GeneralSecurityException;
import java.util.Collection;
import java.util.concurrent.Executor;
import java.util.logging.Logger;
import javax.inject.Inject;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.api.identity.Author.Status.OURSELVES;
public class ForumControllerImpl
extends ThreadListControllerImpl<Forum, ForumEntry, ForumPostHeader>
extends ThreadListControllerImpl<Forum, ForumEntry, ForumPostHeader, ForumPost>
implements ForumController {
private static final Logger LOG =
Logger.getLogger(ForumControllerImpl.class.getName());
private final ForumPostFactory forumPostFactory;
private final ForumManager forumManager;
@Inject
ForumControllerImpl(@DatabaseExecutor Executor dbExecutor,
LifecycleManager lifecycleManager,
@CryptoExecutor Executor cryptoExecutor,
ForumPostFactory forumPostFactory, CryptoComponent crypto,
ForumManager forumManager, EventBus eventBus,
IdentityManager identityManager,
AndroidNotificationManager notificationManager) {
super(dbExecutor, lifecycleManager, cryptoExecutor, crypto, eventBus,
identityManager, notificationManager);
super(dbExecutor, lifecycleManager, cryptoExecutor, eventBus,
notificationManager);
this.forumManager = forumManager;
this.forumPostFactory = forumPostFactory;
}
@Override
@@ -76,7 +60,6 @@ public class ForumControllerImpl
if (pe.getGroupId().equals(groupId)) {
LOG.info("Forum post received, adding...");
final ForumPostHeader fph = pe.getForumPostHeader();
updateNewestTimestamp(fph.getTimestamp());
listener.runOnUiThreadUnlessDestroyed(new Runnable() {
@Override
public void run() {
@@ -115,65 +98,15 @@ public class ForumControllerImpl
}
@Override
public void send(final String body, @Nullable final MessageId parentId,
final ResultExceptionHandler<ForumEntry, DbException> handler) {
cryptoExecutor.execute(new Runnable() {
@Override
public void run() {
LOG.info("Create post...");
long timestamp = System.currentTimeMillis();
timestamp = Math.max(timestamp, newestTimeStamp.get());
ForumPost p;
try {
LocalAuthor a = identityManager.getLocalAuthor();
KeyParser keyParser = crypto.getSignatureKeyParser();
byte[] k = a.getPrivateKey();
PrivateKey authorKey = keyParser.parsePrivateKey(k);
byte[] b = StringUtils.toUtf8(body);
p = forumPostFactory
.createPseudonymousPost(groupId, timestamp,
parentId, a, "text/plain", b, authorKey);
} catch (GeneralSecurityException | FormatException e) {
throw new RuntimeException(e);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
return;
}
bodyCache.put(p.getMessage().getId(), body);
storePost(p, handler);
}
});
protected ForumPost createLocalMessage(GroupId g, String body,
@Nullable MessageId parentId) throws DbException {
return forumManager.createLocalPost(groupId, body, parentId);
}
private void storePost(final ForumPost p,
final ResultExceptionHandler<ForumEntry, DbException> resultHandler) {
runOnDbThread(new Runnable() {
@Override
public void run() {
try {
LOG.info("Store post...");
long now = System.currentTimeMillis();
forumManager.addLocalPost(p);
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Storing message took " + duration + " ms");
ForumPostHeader h =
new ForumPostHeader(p.getMessage().getId(),
p.getParent(),
p.getMessage().getTimestamp(),
p.getAuthor(), OURSELVES, true);
resultHandler.onResult(buildItem(h));
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
resultHandler.onException(e);
}
}
});
@Override
protected ForumPostHeader addLocalMessage(ForumPost p)
throws DbException {
return forumManager.addLocalPost(p);
}
@Override

View File

@@ -2,45 +2,46 @@ package org.briarproject.android.privategroup.conversation;
import android.support.annotation.Nullable;
import org.briarproject.android.controller.handler.ResultExceptionHandler;
import org.briarproject.android.api.AndroidNotificationManager;
import org.briarproject.android.threaded.ThreadListControllerImpl;
import org.briarproject.api.FormatException;
import org.briarproject.api.crypto.CryptoExecutor;
import org.briarproject.api.db.DatabaseExecutor;
import org.briarproject.api.db.DbException;
import org.briarproject.api.event.Event;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.event.GroupMessageAddedEvent;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.privategroup.GroupMessage;
import org.briarproject.api.privategroup.GroupMessageFactory;
import org.briarproject.api.privategroup.GroupMessageHeader;
import org.briarproject.api.privategroup.PrivateGroup;
import org.briarproject.api.privategroup.PrivateGroupManager;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageId;
import java.security.GeneralSecurityException;
import java.util.Collection;
import java.util.concurrent.Executor;
import java.util.logging.Logger;
import javax.inject.Inject;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.api.identity.Author.Status.OURSELVES;
public class GroupControllerImpl
extends ThreadListControllerImpl<PrivateGroup, GroupMessageItem, GroupMessageHeader>
extends ThreadListControllerImpl<PrivateGroup, GroupMessageItem, GroupMessageHeader, GroupMessage>
implements GroupController {
private static final Logger LOG =
Logger.getLogger(GroupControllerImpl.class.getName());
@Inject
volatile GroupMessageFactory groupMessageFactory;
@Inject
volatile PrivateGroupManager privateGroupManager;
private final PrivateGroupManager privateGroupManager;
@Inject
GroupControllerImpl() {
super();
GroupControllerImpl(@DatabaseExecutor Executor dbExecutor,
LifecycleManager lifecycleManager,
@CryptoExecutor Executor cryptoExecutor,
PrivateGroupManager privateGroupManager, EventBus eventBus,
AndroidNotificationManager notificationManager) {
super(dbExecutor, lifecycleManager, cryptoExecutor, eventBus,
notificationManager);
this.privateGroupManager = privateGroupManager;
}
@Override
@@ -58,7 +59,6 @@ public class GroupControllerImpl
if (!pe.isLocal() && pe.getGroupId().equals(groupId)) {
LOG.info("Group message received, adding...");
final GroupMessageHeader fph = pe.getHeader();
updateNewestTimestamp(fph.getTimestamp());
listener.runOnUiThreadUnlessDestroyed(new Runnable() {
@Override
public void run() {
@@ -97,59 +97,15 @@ public class GroupControllerImpl
}
@Override
public void send(final String body, @Nullable final MessageId parentId,
final ResultExceptionHandler<GroupMessageItem, DbException> handler) {
cryptoExecutor.execute(new Runnable() {
@Override
public void run() {
LOG.info("Create message...");
long timestamp = System.currentTimeMillis();
timestamp = Math.max(timestamp, newestTimeStamp.get());
GroupMessage gm;
try {
LocalAuthor a = identityManager.getLocalAuthor();
gm = groupMessageFactory.createGroupMessage(groupId,
timestamp, parentId, a, body);
} catch (GeneralSecurityException | FormatException e) {
throw new RuntimeException(e);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
return;
}
bodyCache.put(gm.getMessage().getId(), body);
storeMessage(gm, handler);
}
});
protected GroupMessage createLocalMessage(GroupId g, String body,
@Nullable MessageId parentId) throws DbException {
return privateGroupManager.createLocalMessage(groupId, body, parentId);
}
private void storeMessage(final GroupMessage gm,
final ResultExceptionHandler<GroupMessageItem, DbException> handler) {
runOnDbThread(new Runnable() {
@Override
public void run() {
try {
LOG.info("Store message...");
long now = System.currentTimeMillis();
privateGroupManager.addLocalMessage(gm);
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Storing message took " + duration + " ms");
GroupMessageHeader h = new GroupMessageHeader(groupId,
gm.getMessage().getId(), gm.getParent(),
gm.getMessage().getTimestamp(), gm.getAuthor(),
OURSELVES, true);
handler.onResult(buildItem(h));
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
}
}
});
@Override
protected GroupMessageHeader addLocalMessage(GroupMessage message)
throws DbException {
return privateGroupManager.addLocalMessage(message);
}
@Override

View File

@@ -2,13 +2,14 @@ package org.briarproject.android.threaded;
import android.app.Activity;
import android.support.annotation.CallSuper;
import android.support.annotation.Nullable;
import org.briarproject.android.api.AndroidNotificationManager;
import org.briarproject.android.controller.DbControllerImpl;
import org.briarproject.android.controller.handler.ResultExceptionHandler;
import org.briarproject.api.clients.BaseGroup;
import org.briarproject.api.clients.BaseMessage;
import org.briarproject.api.clients.PostHeader;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.CryptoExecutor;
import org.briarproject.api.db.DatabaseExecutor;
import org.briarproject.api.db.DbException;
@@ -16,9 +17,6 @@ import org.briarproject.api.event.Event;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.event.EventListener;
import org.briarproject.api.event.GroupRemovedEvent;
import org.briarproject.api.forum.ForumManager;
import org.briarproject.api.forum.ForumPostFactory;
import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageId;
@@ -30,13 +28,12 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Logger;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
public abstract class ThreadListControllerImpl<G extends BaseGroup, I extends ThreadItem, H extends PostHeader>
public abstract class ThreadListControllerImpl<G extends BaseGroup, I extends ThreadItem, H extends PostHeader, M extends BaseMessage>
extends DbControllerImpl
implements ThreadListController<G, I, H>, EventListener {
@@ -44,14 +41,11 @@ public abstract class ThreadListControllerImpl<G extends BaseGroup, I extends Th
Logger.getLogger(ThreadListControllerImpl.class.getName());
protected final Executor cryptoExecutor;
protected final CryptoComponent crypto;
protected final EventBus eventBus;
protected final IdentityManager identityManager;
protected final AndroidNotificationManager notificationManager;
private final EventBus eventBus;
protected final Map<MessageId, String> bodyCache =
new ConcurrentHashMap<>();
protected final AtomicLong newestTimeStamp = new AtomicLong();
protected volatile GroupId groupId;
@@ -59,14 +53,11 @@ public abstract class ThreadListControllerImpl<G extends BaseGroup, I extends Th
protected ThreadListControllerImpl(@DatabaseExecutor Executor dbExecutor,
LifecycleManager lifecycleManager,
@CryptoExecutor Executor cryptoExecutor, CryptoComponent crypto,
EventBus eventBus, IdentityManager identityManager,
@CryptoExecutor Executor cryptoExecutor, EventBus eventBus,
AndroidNotificationManager notificationManager) {
super(dbExecutor, lifecycleManager);
this.cryptoExecutor = cryptoExecutor;
this.crypto = crypto;
this.eventBus = eventBus;
this.identityManager = identityManager;
this.notificationManager = notificationManager;
}
@@ -164,9 +155,6 @@ public abstract class ThreadListControllerImpl<G extends BaseGroup, I extends Th
if (LOG.isLoggable(INFO))
LOG.info("Loading headers took " + duration + " ms");
// Update timestamp of newest item
updateNewestTimeStamp(headers);
// Load bodies
now = System.currentTimeMillis();
loadBodies(headers);
@@ -259,6 +247,63 @@ public abstract class ThreadListControllerImpl<G extends BaseGroup, I extends Th
send(body, null, resultHandler);
}
@Override
public void send(final String body, @Nullable final MessageId parentId,
final ResultExceptionHandler<I, DbException> handler) {
cryptoExecutor.execute(new Runnable() {
@Override
public void run() {
LOG.info("Creating message...");
try {
M msg = createLocalMessage(groupId, body, parentId);
bodyCache.put(msg.getMessage().getId(), body);
storePost(msg, handler);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
handler.onException(e);
}
}
});
}
/**
* This should only be run from the DbThread.
*
* @throws DbException
*/
protected abstract M createLocalMessage(GroupId g, String body,
@Nullable MessageId parentId) throws DbException;
private void storePost(final M p,
final ResultExceptionHandler<I, DbException> resultHandler) {
runOnDbThread(new Runnable() {
@Override
public void run() {
try {
LOG.info("Store message...");
long now = System.currentTimeMillis();
H h = addLocalMessage(p);
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Storing message took " + duration + " ms");
resultHandler.onResult(buildItem(h));
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
resultHandler.onException(e);
}
}
});
}
/**
* This should only be run from the DbThread.
*
* @throws DbException
*/
protected abstract H addLocalMessage(M message) throws DbException;
@Override
public void deleteGroupItem(
final ResultExceptionHandler<Void, DbException> handler) {
@@ -303,20 +348,6 @@ public abstract class ThreadListControllerImpl<G extends BaseGroup, I extends Th
*/
protected abstract I buildItem(H header);
private void updateNewestTimeStamp(Collection<H> headers) {
for (H h : headers) {
updateNewestTimestamp(h.getTimestamp());
}
}
protected void updateNewestTimestamp(long update) {
long newest = newestTimeStamp.get();
while (newest < update) {
if (newestTimeStamp.compareAndSet(newest, update)) return;
newest = newestTimeStamp.get();
}
}
private void checkGroupId() {
if (groupId == null) {
throw new IllegalStateException(