mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-13 03:09:04 +01:00
Create local state for clients at startup. #279
This commit is contained in:
@@ -93,10 +93,8 @@ public class AndroidModule {
|
||||
AndroidNotificationManager provideAndroidNotificationManager(
|
||||
LifecycleManager lifecycleManager, EventBus eventBus,
|
||||
AndroidNotificationManagerImpl notificationManager) {
|
||||
lifecycleManager.register(notificationManager);
|
||||
lifecycleManager.registerService(notificationManager);
|
||||
eventBus.addListener(notificationManager);
|
||||
|
||||
return notificationManager;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
12
briar-api/src/org/briarproject/api/clients/Client.java
Normal file
12
briar-api/src/org/briarproject/api/clients/Client.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package org.briarproject.api.clients;
|
||||
|
||||
import org.briarproject.api.db.DbException;
|
||||
import org.briarproject.api.db.Transaction;
|
||||
|
||||
public interface Client {
|
||||
|
||||
/**
|
||||
* Called at startup to create any local state needed by the client.
|
||||
*/
|
||||
void createLocalState(Transaction txn) throws DbException;
|
||||
}
|
||||
@@ -6,6 +6,9 @@ import org.briarproject.api.sync.Group;
|
||||
|
||||
public interface PrivateGroupFactory {
|
||||
|
||||
/** Creates a group that is not shared with any contacts. */
|
||||
Group createLocalGroup(ClientId clientId);
|
||||
|
||||
/** Creates a group for the given client to share with the given contact. */
|
||||
Group createPrivateGroup(ClientId clientId, Contact contact);
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ public interface DatabaseComponent {
|
||||
* <p/>
|
||||
* This method acquires locks, so it must not be called while holding a
|
||||
* lock.
|
||||
*
|
||||
* @param readOnly true if the transaction will only be used for reading.
|
||||
*/
|
||||
Transaction startTransaction(boolean readOnly) throws DbException;
|
||||
@@ -90,13 +91,27 @@ public interface DatabaseComponent {
|
||||
void addTransportKeys(Transaction txn, ContactId c, TransportKeys k)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Returns true if the database contains the given contact for the given
|
||||
* local pseudonym.
|
||||
*/
|
||||
boolean containsContact(Transaction txn, AuthorId remote, AuthorId local)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Returns true if the database contains the given group.
|
||||
*/
|
||||
boolean containsGroup(Transaction txn, GroupId g) throws DbException;
|
||||
|
||||
/**
|
||||
* Deletes the message with the given ID. The message ID and any other
|
||||
* associated data are not deleted.
|
||||
*/
|
||||
void deleteMessage(Transaction txn, MessageId m) throws DbException;
|
||||
|
||||
/** Deletes any metadata associated with the given message. */
|
||||
/**
|
||||
* Deletes any metadata associated with the given message.
|
||||
*/
|
||||
void deleteMessageMetadata(Transaction txn, MessageId m) throws DbException;
|
||||
|
||||
/**
|
||||
@@ -162,13 +177,6 @@ public interface DatabaseComponent {
|
||||
Collection<ContactId> getContacts(Transaction txn, AuthorId a)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Returns true if the database contains the given contact for the given
|
||||
* local pseudonym.
|
||||
*/
|
||||
boolean containsContact(Transaction txn, AuthorId remote, AuthorId local)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Returns the unique ID for this device.
|
||||
* <p/>
|
||||
@@ -359,7 +367,7 @@ public interface DatabaseComponent {
|
||||
* Marks the given contact as active or inactive.
|
||||
*/
|
||||
void setContactActive(Transaction txn, ContactId c, boolean active)
|
||||
throws DbException;
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Marks the given message as shared or unshared.
|
||||
|
||||
@@ -1,32 +1,49 @@
|
||||
package org.briarproject.api.lifecycle;
|
||||
|
||||
import org.briarproject.api.clients.Client;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
/**
|
||||
* Manages the lifecycle of the app, starting and stopping {@link Service
|
||||
* Services}, shutting down {@link java.util.concurrent.ExecutorService
|
||||
* Manages the lifecycle of the app, starting {@link
|
||||
* org.briarproject.api.clients.Client Clients}, starting and stopping {@link
|
||||
* Service Services}, shutting down {@link java.util.concurrent.ExecutorService
|
||||
* ExecutorServices}, and opening and closing the {@link
|
||||
* org.briarproject.api.db.DatabaseComponent DatabaseComponent}.
|
||||
*/
|
||||
public interface LifecycleManager {
|
||||
|
||||
/** The result of calling {@link LifecycleManager#startServices()}. */
|
||||
enum StartResult { ALREADY_RUNNING, DB_ERROR, SERVICE_ERROR, SUCCESS }
|
||||
/**
|
||||
* The result of calling {@link LifecycleManager#startServices()}.
|
||||
*/
|
||||
enum StartResult {
|
||||
ALREADY_RUNNING, DB_ERROR, SERVICE_ERROR, SUCCESS
|
||||
}
|
||||
|
||||
/** Registers a {@link Service} to be started and stopped. */
|
||||
public void register(Service s);
|
||||
/**
|
||||
* Registers a {@link Service} to be started and stopped.
|
||||
*/
|
||||
void registerService(Service s);
|
||||
|
||||
/**
|
||||
* Registers a {@link org.briarproject.api.clients.Client Client} to be
|
||||
* started.
|
||||
*/
|
||||
void registerClient(Client c);
|
||||
|
||||
/**
|
||||
* Registers an {@link java.util.concurrent.ExecutorService ExecutorService}
|
||||
* to be shut down.
|
||||
*/
|
||||
public void registerForShutdown(ExecutorService e);
|
||||
void registerForShutdown(ExecutorService e);
|
||||
|
||||
/**
|
||||
* Starts any registered {@link Service Services} and opens the {@link
|
||||
* org.briarproject.api.db.DatabaseComponent DatabaseComponent}.
|
||||
* Opens the {@link org.briarproject.api.db.DatabaseComponent
|
||||
* DatabaseComponent} and starts any registered {@link
|
||||
* org.briarproject.api.clients.Client Clients} and {@link Service
|
||||
* Services}.
|
||||
*/
|
||||
public StartResult startServices();
|
||||
StartResult startServices();
|
||||
|
||||
/**
|
||||
* Stops any registered {@link Service Services}, shuts down any
|
||||
@@ -34,20 +51,21 @@ public interface LifecycleManager {
|
||||
* and closes the {@link org.briarproject.api.db.DatabaseComponent
|
||||
* DatabaseComponent}.
|
||||
*/
|
||||
public void stopServices();
|
||||
void stopServices();
|
||||
|
||||
/**
|
||||
* Waits for the {@link org.briarproject.api.db.DatabaseComponent
|
||||
* DatabaseComponent} to be opened before returning.
|
||||
*/
|
||||
public void waitForDatabase() throws InterruptedException;
|
||||
void waitForDatabase() throws InterruptedException;
|
||||
|
||||
/**
|
||||
* Waits for the {@link org.briarproject.api.db.DatabaseComponent
|
||||
* DatabaseComponent} to be opened and all registered {@link Service
|
||||
* DatabaseComponent} to be opened and all registered {@link
|
||||
* org.briarproject.api.clients.Client Clients} and {@link Service
|
||||
* Services} to start before returning.
|
||||
*/
|
||||
public void waitForStartup() throws InterruptedException;
|
||||
void waitForStartup() throws InterruptedException;
|
||||
|
||||
/**
|
||||
* Waits for all registered {@link Service Services} to stop, all
|
||||
@@ -55,5 +73,5 @@ public interface LifecycleManager {
|
||||
* to shut down, and the {@link org.briarproject.api.db.DatabaseComponent
|
||||
* DatabaseComponent} to be closed before returning.
|
||||
*/
|
||||
public void waitForShutdown() throws InterruptedException;
|
||||
void waitForShutdown() throws InterruptedException;
|
||||
}
|
||||
@@ -16,6 +16,8 @@ import javax.inject.Inject;
|
||||
|
||||
class PrivateGroupFactoryImpl implements PrivateGroupFactory {
|
||||
|
||||
private static final byte[] LOCAL_GROUP_DESCRIPTOR = new byte[0];
|
||||
|
||||
private final GroupFactory groupFactory;
|
||||
private final ClientHelper clientHelper;
|
||||
|
||||
@@ -26,6 +28,11 @@ class PrivateGroupFactoryImpl implements PrivateGroupFactory {
|
||||
this.clientHelper = clientHelper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Group createLocalGroup(ClientId clientId) {
|
||||
return groupFactory.createGroup(clientId, LOCAL_GROUP_DESCRIPTOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Group createPrivateGroup(ClientId clientId, Contact contact) {
|
||||
AuthorId local = contact.getLocalAuthorId();
|
||||
|
||||
@@ -228,6 +228,20 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
||||
db.addTransportKeys(txn, c, k);
|
||||
}
|
||||
|
||||
public boolean containsContact(Transaction transaction, AuthorId remote,
|
||||
AuthorId local) throws DbException {
|
||||
T txn = unbox(transaction);
|
||||
if (!db.containsLocalAuthor(txn, local))
|
||||
throw new NoSuchLocalAuthorException();
|
||||
return db.containsContact(txn, remote, local);
|
||||
}
|
||||
|
||||
public boolean containsGroup(Transaction transaction, GroupId g)
|
||||
throws DbException {
|
||||
T txn = unbox(transaction);
|
||||
return db.containsGroup(txn, g);
|
||||
}
|
||||
|
||||
public void deleteMessage(Transaction transaction, MessageId m)
|
||||
throws DbException {
|
||||
if (transaction.isReadOnly()) throw new IllegalArgumentException();
|
||||
@@ -342,14 +356,6 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
||||
return db.getContacts(txn, a);
|
||||
}
|
||||
|
||||
public boolean containsContact(Transaction transaction, AuthorId remote,
|
||||
AuthorId local) throws DbException {
|
||||
T txn = unbox(transaction);
|
||||
if (!db.containsLocalAuthor(txn, local))
|
||||
throw new NoSuchLocalAuthorException();
|
||||
return db.containsContact(txn, remote, local);
|
||||
}
|
||||
|
||||
public DeviceId getDeviceId(Transaction transaction) throws DbException {
|
||||
T txn = unbox(transaction);
|
||||
return db.getDeviceId(txn);
|
||||
|
||||
@@ -3,14 +3,13 @@ package org.briarproject.forum;
|
||||
import org.briarproject.api.clients.ClientHelper;
|
||||
import org.briarproject.api.contact.ContactManager;
|
||||
import org.briarproject.api.crypto.CryptoComponent;
|
||||
import org.briarproject.api.data.BdfReaderFactory;
|
||||
import org.briarproject.api.data.MetadataEncoder;
|
||||
import org.briarproject.api.data.MetadataParser;
|
||||
import org.briarproject.api.db.DatabaseComponent;
|
||||
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.lifecycle.LifecycleManager;
|
||||
import org.briarproject.api.sync.ValidationManager;
|
||||
import org.briarproject.api.system.Clock;
|
||||
|
||||
@@ -73,9 +72,11 @@ public class ForumModule {
|
||||
@Provides
|
||||
@Singleton
|
||||
ForumSharingManager provideForumSharingManager(
|
||||
LifecycleManager lifecycleManager,
|
||||
ContactManager contactManager,
|
||||
ValidationManager validationManager,
|
||||
ForumSharingManagerImpl forumSharingManager) {
|
||||
lifecycleManager.registerClient(forumSharingManager);
|
||||
contactManager.registerAddContactHook(forumSharingManager);
|
||||
contactManager.registerRemoveContactHook(forumSharingManager);
|
||||
validationManager.registerIncomingMessageHook(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.briarproject.forum;
|
||||
|
||||
import org.briarproject.api.FormatException;
|
||||
import org.briarproject.api.clients.Client;
|
||||
import org.briarproject.api.clients.ClientHelper;
|
||||
import org.briarproject.api.clients.PrivateGroupFactory;
|
||||
import org.briarproject.api.contact.Contact;
|
||||
@@ -43,15 +44,13 @@ import static org.briarproject.api.forum.ForumConstants.FORUM_SALT_LENGTH;
|
||||
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, IncomingMessageHook {
|
||||
class ForumSharingManagerImpl implements ForumSharingManager, Client,
|
||||
AddContactHook, RemoveContactHook, IncomingMessageHook {
|
||||
|
||||
static final ClientId CLIENT_ID = new ClientId(StringUtils.fromHexString(
|
||||
"cd11a5d04dccd9e2931d6fc3df456313"
|
||||
+ "63bb3e9d9d0e9405fccdb051f41f5449"));
|
||||
|
||||
private static final byte[] LOCAL_GROUP_DESCRIPTOR = new byte[0];
|
||||
|
||||
private final DatabaseComponent db;
|
||||
private final ForumManager forumManager;
|
||||
private final ClientHelper clientHelper;
|
||||
@@ -73,8 +72,14 @@ class ForumSharingManagerImpl implements ForumSharingManager, AddContactHook,
|
||||
this.privateGroupFactory = privateGroupFactory;
|
||||
this.random = random;
|
||||
this.clock = clock;
|
||||
localGroup = groupFactory.createGroup(CLIENT_ID,
|
||||
LOCAL_GROUP_DESCRIPTOR);
|
||||
localGroup = privateGroupFactory.createLocalGroup(CLIENT_ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createLocalState(Transaction txn) throws DbException {
|
||||
db.addGroup(txn, localGroup);
|
||||
// Ensure we've set things up for any pre-existing contacts
|
||||
for (Contact c : db.getContacts(txn)) addingContact(txn, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -82,6 +87,8 @@ class ForumSharingManagerImpl implements ForumSharingManager, AddContactHook,
|
||||
try {
|
||||
// Create a group to share with the contact
|
||||
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
|
||||
db.addGroup(txn, g);
|
||||
db.setVisibleToContact(txn, c.getId(), g.getId(), true);
|
||||
@@ -297,8 +304,6 @@ class ForumSharingManagerImpl implements ForumSharingManager, AddContactHook,
|
||||
|
||||
private List<Forum> getForumsSharedWithAllContacts(Transaction txn)
|
||||
throws DbException, FormatException {
|
||||
// Ensure the local group exists
|
||||
db.addGroup(txn, localGroup);
|
||||
// Find the latest update in the local group
|
||||
LatestUpdate latest = findLatest(txn, localGroup.getId(), true);
|
||||
if (latest == null) return Collections.emptyList();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.briarproject.introduction;
|
||||
|
||||
import org.briarproject.api.FormatException;
|
||||
import org.briarproject.api.clients.Client;
|
||||
import org.briarproject.api.clients.ClientHelper;
|
||||
import org.briarproject.api.clients.MessageQueueManager;
|
||||
import org.briarproject.api.clients.PrivateGroupFactory;
|
||||
@@ -31,7 +32,6 @@ import org.briarproject.api.introduction.SessionId;
|
||||
import org.briarproject.api.properties.TransportPropertyManager;
|
||||
import org.briarproject.api.sync.ClientId;
|
||||
import org.briarproject.api.sync.Group;
|
||||
import org.briarproject.api.sync.GroupFactory;
|
||||
import org.briarproject.api.sync.GroupId;
|
||||
import org.briarproject.api.sync.Message;
|
||||
import org.briarproject.api.sync.MessageId;
|
||||
@@ -82,14 +82,13 @@ import static org.briarproject.api.introduction.IntroductionConstants.TYPE_REQUE
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TYPE_RESPONSE;
|
||||
|
||||
class IntroductionManagerImpl extends BdfIncomingMessageHook
|
||||
implements IntroductionManager, AddContactHook, RemoveContactHook {
|
||||
implements IntroductionManager, Client, AddContactHook,
|
||||
RemoveContactHook {
|
||||
|
||||
static final ClientId CLIENT_ID = new ClientId(StringUtils.fromHexString(
|
||||
"23b1897c198a90ae75b976ac023d0f32"
|
||||
+ "80ca67b12f2346b2c23a34f34e2434c3"));
|
||||
|
||||
private static final byte[] LOCAL_GROUP_DESCRIPTOR = new byte[0];
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(IntroductionManagerImpl.class.getName());
|
||||
|
||||
@@ -104,8 +103,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
|
||||
@Inject
|
||||
IntroductionManagerImpl(DatabaseComponent db,
|
||||
MessageQueueManager messageQueueManager,
|
||||
ClientHelper clientHelper, GroupFactory groupFactory,
|
||||
PrivateGroupFactory privateGroupFactory,
|
||||
ClientHelper clientHelper, PrivateGroupFactory privateGroupFactory,
|
||||
MetadataEncoder metadataEncoder, MetadataParser metadataParser,
|
||||
CryptoComponent cryptoComponent,
|
||||
TransportPropertyManager transportPropertyManager,
|
||||
@@ -117,6 +115,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
|
||||
this.messageQueueManager = messageQueueManager;
|
||||
this.privateGroupFactory = privateGroupFactory;
|
||||
this.metadataEncoder = metadataEncoder;
|
||||
// TODO: Inject these dependencies for easier testing
|
||||
this.introducerManager =
|
||||
new IntroducerManager(this, clientHelper, clock,
|
||||
cryptoComponent);
|
||||
@@ -124,8 +123,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
|
||||
new IntroduceeManager(db, this, clientHelper, clock,
|
||||
cryptoComponent, transportPropertyManager,
|
||||
authorFactory, contactManager);
|
||||
localGroup =
|
||||
groupFactory.createGroup(CLIENT_ID, LOCAL_GROUP_DESCRIPTOR);
|
||||
localGroup = privateGroupFactory.createLocalGroup(CLIENT_ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -133,11 +131,21 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
|
||||
return CLIENT_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createLocalState(Transaction txn) throws DbException {
|
||||
db.addGroup(txn, localGroup);
|
||||
// Ensure we've set things up for any pre-existing contacts
|
||||
for (Contact c : db.getContacts(txn)) addingContact(txn, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addingContact(Transaction txn, Contact c) throws DbException {
|
||||
try {
|
||||
// create an introduction group for sending introduction messages
|
||||
// Create an introduction group for sending introduction messages
|
||||
Group g = getIntroductionGroup(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
|
||||
db.addGroup(txn, g);
|
||||
db.setVisibleToContact(txn, c.getId(), g.getId(), true);
|
||||
// Attach the contact ID to the group
|
||||
@@ -169,7 +177,6 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
|
||||
introducerManager.abort(txn, d);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} catch (FormatException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
@@ -189,9 +196,6 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
|
||||
protected void incomingMessage(Transaction txn, Message m, BdfList body,
|
||||
BdfDictionary message) throws DbException {
|
||||
|
||||
// add local group for engine states to make sure it exists
|
||||
db.addGroup(txn, localGroup);
|
||||
|
||||
// Get message data and type
|
||||
GroupId groupId = m.getGroupId();
|
||||
message.put(GROUP_ID, groupId);
|
||||
@@ -265,15 +269,13 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
|
||||
public void makeIntroduction(Contact c1, Contact c2, String msg)
|
||||
throws DbException, FormatException {
|
||||
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
// add local group for session states to make sure it exists
|
||||
db.addGroup(txn, getLocalGroup());
|
||||
introducerManager.makeIntroduction(txn, c1, c2, msg);
|
||||
txn.setComplete();
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
introducerManager.makeIntroduction(txn, c1, c2, msg);
|
||||
txn.setComplete();
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -468,7 +470,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
|
||||
}
|
||||
if (LOG.isLoggable(WARNING)) {
|
||||
LOG.warning(
|
||||
"No session state found for this message with session ID " +
|
||||
"No session state found for message with session ID " +
|
||||
Arrays.hashCode(sessionId));
|
||||
}
|
||||
throw new FormatException();
|
||||
@@ -505,5 +507,4 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
|
||||
db.deleteMessage(txn, messageId);
|
||||
db.deleteMessageMetadata(txn, messageId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import org.briarproject.api.clients.MessageQueueManager;
|
||||
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.system.Clock;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@@ -41,15 +42,17 @@ public class IntroductionModule {
|
||||
@Provides
|
||||
@Singleton
|
||||
IntroductionManager getIntroductionManager(
|
||||
LifecycleManager lifecycleManager,
|
||||
ContactManager contactManager,
|
||||
MessageQueueManager messageQueueManager,
|
||||
IntroductionManagerImpl introductionManager) {
|
||||
|
||||
lifecycleManager.registerClient(introductionManager);
|
||||
contactManager.registerAddContactHook(introductionManager);
|
||||
contactManager.registerRemoveContactHook(introductionManager);
|
||||
messageQueueManager
|
||||
.registerIncomingMessageHook(introductionManager.getClientId(),
|
||||
introductionManager);
|
||||
messageQueueManager.registerIncomingMessageHook(
|
||||
introductionManager.getClientId(),
|
||||
introductionManager);
|
||||
|
||||
return introductionManager;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
package org.briarproject.lifecycle;
|
||||
|
||||
import org.briarproject.api.clients.Client;
|
||||
import org.briarproject.api.db.DatabaseComponent;
|
||||
import org.briarproject.api.db.DbException;
|
||||
import org.briarproject.api.db.Transaction;
|
||||
import org.briarproject.api.event.EventBus;
|
||||
import org.briarproject.api.event.ShutdownEvent;
|
||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||
import org.briarproject.api.lifecycle.Service;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
@@ -31,8 +33,9 @@ class LifecycleManagerImpl implements LifecycleManager {
|
||||
|
||||
private final DatabaseComponent db;
|
||||
private final EventBus eventBus;
|
||||
private final Collection<Service> services;
|
||||
private final Collection<ExecutorService> executors;
|
||||
private final List<Service> services;
|
||||
private final List<Client> clients;
|
||||
private final List<ExecutorService> executors;
|
||||
private final Semaphore startStopSemaphore = new Semaphore(1);
|
||||
private final CountDownLatch dbLatch = new CountDownLatch(1);
|
||||
private final CountDownLatch startupLatch = new CountDownLatch(1);
|
||||
@@ -43,15 +46,22 @@ class LifecycleManagerImpl implements LifecycleManager {
|
||||
this.db = db;
|
||||
this.eventBus = eventBus;
|
||||
services = new CopyOnWriteArrayList<Service>();
|
||||
clients = new CopyOnWriteArrayList<Client>();
|
||||
executors = new CopyOnWriteArrayList<ExecutorService>();
|
||||
}
|
||||
|
||||
public void register(Service s) {
|
||||
public void registerService(Service s) {
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Registering service " + s.getClass().getName());
|
||||
services.add(s);
|
||||
}
|
||||
|
||||
public void registerClient(Client c) {
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Registering client " + c.getClass().getName());
|
||||
clients.add(c);
|
||||
}
|
||||
|
||||
public void registerForShutdown(ExecutorService e) {
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Registering executor " + e.getClass().getName());
|
||||
@@ -74,15 +84,28 @@ class LifecycleManagerImpl implements LifecycleManager {
|
||||
else LOG.info("Creating database took " + duration + " ms");
|
||||
}
|
||||
dbLatch.countDown();
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
for (Client c : clients) {
|
||||
start = System.currentTimeMillis();
|
||||
c.createLocalState(txn);
|
||||
duration = System.currentTimeMillis() - start;
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
LOG.info("Starting " + c.getClass().getName()
|
||||
+ " took " + duration + " ms");
|
||||
}
|
||||
}
|
||||
txn.setComplete();
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
for (Service s : services) {
|
||||
start = System.currentTimeMillis();
|
||||
boolean started = s.start();
|
||||
duration = System.currentTimeMillis() - start;
|
||||
if (!started) {
|
||||
if (LOG.isLoggable(WARNING)) {
|
||||
String name = s.getClass().getName();
|
||||
LOG.warning(name + " did not start");
|
||||
}
|
||||
if (LOG.isLoggable(WARNING))
|
||||
LOG.warning(s.getClass().getName() + " did not start");
|
||||
return SERVICE_ERROR;
|
||||
}
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.briarproject.messaging;
|
||||
|
||||
import org.briarproject.api.FormatException;
|
||||
import org.briarproject.api.clients.Client;
|
||||
import org.briarproject.api.clients.ClientHelper;
|
||||
import org.briarproject.api.clients.PrivateGroupFactory;
|
||||
import org.briarproject.api.contact.Contact;
|
||||
@@ -28,7 +29,7 @@ import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
class MessagingManagerImpl implements MessagingManager, AddContactHook,
|
||||
class MessagingManagerImpl implements MessagingManager, Client, AddContactHook,
|
||||
RemoveContactHook {
|
||||
|
||||
static final ClientId CLIENT_ID = new ClientId(StringUtils.fromHexString(
|
||||
@@ -47,11 +48,19 @@ class MessagingManagerImpl implements MessagingManager, AddContactHook,
|
||||
this.privateGroupFactory = privateGroupFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createLocalState(Transaction txn) throws DbException {
|
||||
// Ensure we've set things up for any pre-existing contacts
|
||||
for (Contact c : db.getContacts(txn)) addingContact(txn, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addingContact(Transaction txn, Contact c) throws DbException {
|
||||
try {
|
||||
// Create a group to share with the contact
|
||||
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
|
||||
db.addGroup(txn, g);
|
||||
db.setVisibleToContact(txn, c.getId(), g.getId(), true);
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.briarproject.messaging;
|
||||
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.MessagingManager;
|
||||
import org.briarproject.api.messaging.PrivateMessageFactory;
|
||||
import org.briarproject.api.sync.ValidationManager;
|
||||
@@ -43,8 +44,10 @@ public class MessagingModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
MessagingManager getMessagingManager(ContactManager contactManager,
|
||||
MessagingManager getMessagingManager(LifecycleManager lifecycleManager,
|
||||
ContactManager contactManager,
|
||||
MessagingManagerImpl messagingManager) {
|
||||
lifecycleManager.registerClient(messagingManager);
|
||||
contactManager.registerAddContactHook(messagingManager);
|
||||
contactManager.registerRemoveContactHook(messagingManager);
|
||||
return messagingManager;
|
||||
|
||||
@@ -64,7 +64,7 @@ public class PluginsModule {
|
||||
@Singleton
|
||||
PluginManager getPluginManager(LifecycleManager lifecycleManager,
|
||||
PluginManagerImpl pluginManager) {
|
||||
lifecycleManager.register(pluginManager);
|
||||
lifecycleManager.registerService(pluginManager);
|
||||
return pluginManager;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.briarproject.properties;
|
||||
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.properties.TransportPropertyManager;
|
||||
import org.briarproject.api.sync.ValidationManager;
|
||||
import org.briarproject.api.system.Clock;
|
||||
@@ -36,8 +37,10 @@ public class PropertiesModule {
|
||||
|
||||
@Provides @Singleton
|
||||
TransportPropertyManager getTransportPropertyManager(
|
||||
LifecycleManager lifecycleManager,
|
||||
ContactManager contactManager,
|
||||
TransportPropertyManagerImpl transportPropertyManager) {
|
||||
lifecycleManager.registerClient(transportPropertyManager);
|
||||
contactManager.registerAddContactHook(transportPropertyManager);
|
||||
contactManager.registerRemoveContactHook(transportPropertyManager);
|
||||
return transportPropertyManager;
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.briarproject.properties;
|
||||
import org.briarproject.api.DeviceId;
|
||||
import org.briarproject.api.FormatException;
|
||||
import org.briarproject.api.TransportId;
|
||||
import org.briarproject.api.clients.Client;
|
||||
import org.briarproject.api.clients.ClientHelper;
|
||||
import org.briarproject.api.clients.PrivateGroupFactory;
|
||||
import org.briarproject.api.contact.Contact;
|
||||
@@ -13,13 +14,11 @@ import org.briarproject.api.data.BdfDictionary;
|
||||
import org.briarproject.api.data.BdfList;
|
||||
import org.briarproject.api.db.DatabaseComponent;
|
||||
import org.briarproject.api.db.DbException;
|
||||
import org.briarproject.api.db.NoSuchGroupException;
|
||||
import org.briarproject.api.db.Transaction;
|
||||
import org.briarproject.api.properties.TransportProperties;
|
||||
import org.briarproject.api.properties.TransportPropertyManager;
|
||||
import org.briarproject.api.sync.ClientId;
|
||||
import org.briarproject.api.sync.Group;
|
||||
import org.briarproject.api.sync.GroupFactory;
|
||||
import org.briarproject.api.sync.GroupId;
|
||||
import org.briarproject.api.sync.Message;
|
||||
import org.briarproject.api.sync.MessageId;
|
||||
@@ -34,14 +33,12 @@ import java.util.Map.Entry;
|
||||
import javax.inject.Inject;
|
||||
|
||||
class TransportPropertyManagerImpl implements TransportPropertyManager,
|
||||
AddContactHook, RemoveContactHook {
|
||||
Client, AddContactHook, RemoveContactHook {
|
||||
|
||||
static final ClientId CLIENT_ID = new ClientId(StringUtils.fromHexString(
|
||||
"673ea091673561e28f70122f6a8ea8f4"
|
||||
+ "97c3624b86fa07f785bb15f09fb87b4b"));
|
||||
|
||||
private static final byte[] LOCAL_GROUP_DESCRIPTOR = new byte[0];
|
||||
|
||||
private final DatabaseComponent db;
|
||||
private final ClientHelper clientHelper;
|
||||
private final PrivateGroupFactory privateGroupFactory;
|
||||
@@ -50,20 +47,28 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
||||
|
||||
@Inject
|
||||
TransportPropertyManagerImpl(DatabaseComponent db,
|
||||
ClientHelper clientHelper, GroupFactory groupFactory,
|
||||
PrivateGroupFactory privateGroupFactory, Clock clock) {
|
||||
ClientHelper clientHelper, PrivateGroupFactory privateGroupFactory,
|
||||
Clock clock) {
|
||||
this.db = db;
|
||||
this.clientHelper = clientHelper;
|
||||
this.privateGroupFactory = privateGroupFactory;
|
||||
this.clock = clock;
|
||||
localGroup = groupFactory.createGroup(CLIENT_ID,
|
||||
LOCAL_GROUP_DESCRIPTOR);
|
||||
localGroup = privateGroupFactory.createLocalGroup(CLIENT_ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createLocalState(Transaction txn) throws DbException {
|
||||
db.addGroup(txn, localGroup);
|
||||
// Ensure we've set things up for any pre-existing contacts
|
||||
for (Contact c : db.getContacts(txn)) addingContact(txn, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addingContact(Transaction txn, Contact c) throws DbException {
|
||||
// Create a group to share with the contact
|
||||
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
|
||||
db.addGroup(txn, g);
|
||||
db.setVisibleToContact(txn, c.getId(), g.getId(), true);
|
||||
@@ -126,9 +131,6 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
return p;
|
||||
} catch (NoSuchGroupException e) {
|
||||
// Local group doesn't exist - there are no local properties
|
||||
return null;
|
||||
} catch (FormatException e) {
|
||||
throw new DbException(e);
|
||||
}
|
||||
@@ -169,8 +171,6 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
||||
try {
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
// Create the local group if necessary
|
||||
db.addGroup(txn, localGroup);
|
||||
// Merge the new properties with any existing properties
|
||||
TransportProperties merged;
|
||||
boolean changed;
|
||||
@@ -230,9 +230,6 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
||||
local.put(e.getKey(), parseProperties(message));
|
||||
}
|
||||
return local;
|
||||
} catch (NoSuchGroupException e) {
|
||||
// Local group doesn't exist - there are no local properties
|
||||
return Collections.emptyMap();
|
||||
} catch (FormatException e) {
|
||||
throw new DbException(e);
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ public class SyncModule {
|
||||
@Singleton
|
||||
ValidationManager getValidationManager(LifecycleManager lifecycleManager,
|
||||
EventBus eventBus, ValidationManagerImpl validationManager) {
|
||||
lifecycleManager.register(validationManager);
|
||||
lifecycleManager.registerService(validationManager);
|
||||
eventBus.addListener(validationManager);
|
||||
return validationManager;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public class TransportModule {
|
||||
@Singleton
|
||||
KeyManager getKeyManager(LifecycleManager lifecycleManager,
|
||||
EventBus eventBus, KeyManagerImpl keyManager) {
|
||||
lifecycleManager.register(keyManager);
|
||||
lifecycleManager.registerService(keyManager);
|
||||
eventBus.addListener(keyManager);
|
||||
return keyManager;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.briarproject;
|
||||
|
||||
import org.briarproject.api.clients.Client;
|
||||
import org.briarproject.api.lifecycle.IoExecutor;
|
||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||
import org.briarproject.api.lifecycle.Service;
|
||||
@@ -20,8 +21,14 @@ public class TestLifecycleModule {
|
||||
@Provides
|
||||
LifecycleManager provideLifecycleManager() {
|
||||
return new LifecycleManager() {
|
||||
|
||||
@Override
|
||||
public void register(Service s) {
|
||||
public void registerService(Service s) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerClient(Client c) {
|
||||
|
||||
}
|
||||
|
||||
@@ -60,6 +67,7 @@ public class TestLifecycleModule {
|
||||
@Provides
|
||||
ShutdownManager provideShutdownManager() {
|
||||
return new ShutdownManager() {
|
||||
|
||||
@Override
|
||||
public int addShutdownHook(Runnable hook) {
|
||||
return 0;
|
||||
@@ -75,8 +83,7 @@ public class TestLifecycleModule {
|
||||
@Provides
|
||||
@IoExecutor
|
||||
@Singleton
|
||||
Executor provideExecutor() {
|
||||
Executor provideIoExecutor() {
|
||||
return Executors.newCachedThreadPool();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user