Merge branch '279-create-client-state' into 'master'

Create local state for clients at startup. #279

Most of the clients we've written so far use private groups shared with individual contacts and/or a local group that's not shared with anyone. To make it easier to ensure that the necessary groups exist when we need them, this patch allows clients to register startup hooks for creating their local state.

Fixes #279.

See merge request !131
This commit is contained in:
akwizgran
2016-04-04 15:07:37 +00:00
20 changed files with 209 additions and 105 deletions

View File

@@ -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;
}
}

View 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;
}

View File

@@ -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);
}

View File

@@ -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.

View File

@@ -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;
}

View File

@@ -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();

View File

@@ -231,6 +231,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();
@@ -345,14 +359,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);

View File

@@ -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(

View File

@@ -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();

View File

@@ -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);
}
}

View File

@@ -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;
}

View File

@@ -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)) {

View File

@@ -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);

View File

@@ -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;

View File

@@ -64,7 +64,7 @@ public class PluginsModule {
@Singleton
PluginManager getPluginManager(LifecycleManager lifecycleManager,
PluginManagerImpl pluginManager) {
lifecycleManager.register(pluginManager);
lifecycleManager.registerService(pluginManager);
return pluginManager;
}
}

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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();
}
}