Replaced Timer with ScheduledExecutorService. #258

This commit is contained in:
akwizgran
2016-05-05 11:07:58 +01:00
parent 036c5d6753
commit ff8301521c
26 changed files with 201 additions and 212 deletions

View File

@@ -42,6 +42,7 @@ import org.briarproject.introduction.MessageSender;
import org.briarproject.lifecycle.LifecycleModule; import org.briarproject.lifecycle.LifecycleModule;
import org.briarproject.properties.PropertiesModule; import org.briarproject.properties.PropertiesModule;
import org.briarproject.sync.SyncModule; import org.briarproject.sync.SyncModule;
import org.briarproject.system.SystemModule;
import org.briarproject.transport.TransportModule; import org.briarproject.transport.TransportModule;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
@@ -944,6 +945,7 @@ public class IntroductionIntegrationTest extends BriarTestCase {
this.accept = accept; this.accept = accept;
} }
@Override
public void eventOccurred(Event e) { public void eventOccurred(Event e) {
if (e instanceof MessageValidatedEvent) { if (e instanceof MessageValidatedEvent) {
MessageValidatedEvent event = (MessageValidatedEvent) e; MessageValidatedEvent event = (MessageValidatedEvent) e;
@@ -1010,6 +1012,7 @@ public class IntroductionIntegrationTest extends BriarTestCase {
public volatile boolean response2Received = false; public volatile boolean response2Received = false;
public volatile boolean aborted = false; public volatile boolean aborted = false;
@Override
public void eventOccurred(Event e) { public void eventOccurred(Event e) {
if (e instanceof MessageValidatedEvent) { if (e instanceof MessageValidatedEvent) {
MessageValidatedEvent event = (MessageValidatedEvent) e; MessageValidatedEvent event = (MessageValidatedEvent) e;
@@ -1050,7 +1053,7 @@ public class IntroductionIntegrationTest extends BriarTestCase {
component.inject(new ContactModule.EagerSingletons()); component.inject(new ContactModule.EagerSingletons());
component.inject(new TransportModule.EagerSingletons()); component.inject(new TransportModule.EagerSingletons());
component.inject(new SyncModule.EagerSingletons()); component.inject(new SyncModule.EagerSingletons());
component.inject(new SystemModule.EagerSingletons());
component.inject(new PropertiesModule.EagerSingletons()); component.inject(new PropertiesModule.EagerSingletons());
} }
} }

View File

@@ -21,6 +21,7 @@ import org.briarproject.introduction.MessageSender;
import org.briarproject.lifecycle.LifecycleModule; import org.briarproject.lifecycle.LifecycleModule;
import org.briarproject.properties.PropertiesModule; import org.briarproject.properties.PropertiesModule;
import org.briarproject.sync.SyncModule; import org.briarproject.sync.SyncModule;
import org.briarproject.system.SystemModule;
import org.briarproject.transport.TransportModule; import org.briarproject.transport.TransportModule;
import javax.inject.Singleton; import javax.inject.Singleton;
@@ -29,9 +30,9 @@ import dagger.Component;
@Singleton @Singleton
@Component(modules = { @Component(modules = {
TestSystemModule.class,
TestDatabaseModule.class, TestDatabaseModule.class,
TestPluginsModule.class, TestPluginsModule.class,
TestSeedProviderModule.class,
LifecycleModule.class, LifecycleModule.class,
IntroductionModule.class, IntroductionModule.class,
DatabaseModule.class, DatabaseModule.class,
@@ -42,6 +43,7 @@ import dagger.Component;
TransportModule.class, TransportModule.class,
ClientsModule.class, ClientsModule.class,
SyncModule.class, SyncModule.class,
SystemModule.class,
DataModule.class, DataModule.class,
PropertiesModule.class PropertiesModule.class
}) })
@@ -61,6 +63,8 @@ public interface IntroductionIntegrationTestComponent {
void inject(SyncModule.EagerSingletons init); void inject(SyncModule.EagerSingletons init);
void inject(SystemModule.EagerSingletons init);
void inject(TransportModule.EagerSingletons init); void inject(TransportModule.EagerSingletons init);
LifecycleManager getLifecycleManager(); LifecycleManager getLifecycleManager();
@@ -84,5 +88,4 @@ public interface IntroductionIntegrationTestComponent {
MessageSender getMessageSender(); MessageSender getMessageSender();
IntroductionGroupFactory getIntroductionGroupFactory(); IntroductionGroupFactory getIntroductionGroupFactory();
} }

View File

@@ -13,6 +13,7 @@ import org.briarproject.api.messaging.PrivateMessage;
import org.briarproject.api.messaging.PrivateMessageFactory; import org.briarproject.api.messaging.PrivateMessageFactory;
import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageId; import org.briarproject.api.sync.MessageId;
import org.briarproject.system.SystemModule;
import org.junit.Test; import org.junit.Test;
import javax.inject.Inject; import javax.inject.Inject;
@@ -39,6 +40,7 @@ public class MessageSizeIntegrationTest extends BriarTestCase {
MessageSizeIntegrationTestComponent component = MessageSizeIntegrationTestComponent component =
DaggerMessageSizeIntegrationTestComponent.builder().build(); DaggerMessageSizeIntegrationTestComponent.builder().build();
component.inject(this); component.inject(this);
component.inject(new SystemModule.EagerSingletons());
} }
@Test @Test

View File

@@ -9,6 +9,7 @@ import org.briarproject.forum.ForumModule;
import org.briarproject.identity.IdentityModule; import org.briarproject.identity.IdentityModule;
import org.briarproject.messaging.MessagingModule; import org.briarproject.messaging.MessagingModule;
import org.briarproject.sync.SyncModule; import org.briarproject.sync.SyncModule;
import org.briarproject.system.SystemModule;
import javax.inject.Singleton; import javax.inject.Singleton;
@@ -18,7 +19,7 @@ import dagger.Component;
@Component(modules = { @Component(modules = {
TestDatabaseModule.class, TestDatabaseModule.class,
TestLifecycleModule.class, TestLifecycleModule.class,
TestSystemModule.class, TestSeedProviderModule.class,
ClientsModule.class, ClientsModule.class,
CryptoModule.class, CryptoModule.class,
DataModule.class, DataModule.class,
@@ -27,8 +28,12 @@ import dagger.Component;
ForumModule.class, ForumModule.class,
IdentityModule.class, IdentityModule.class,
MessagingModule.class, MessagingModule.class,
SyncModule.class SyncModule.class,
SystemModule.class
}) })
public interface MessageSizeIntegrationTestComponent { public interface MessageSizeIntegrationTestComponent {
void inject(MessageSizeIntegrationTest testCase); void inject(MessageSizeIntegrationTest testCase);
void inject(SystemModule.EagerSingletons init);
} }

View File

@@ -21,6 +21,7 @@ import org.briarproject.api.transport.KeyManager;
import org.briarproject.api.transport.StreamContext; import org.briarproject.api.transport.StreamContext;
import org.briarproject.api.transport.StreamReaderFactory; import org.briarproject.api.transport.StreamReaderFactory;
import org.briarproject.api.transport.StreamWriterFactory; import org.briarproject.api.transport.StreamWriterFactory;
import org.briarproject.system.SystemModule;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@@ -57,8 +58,10 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
assertTrue(testDir.mkdirs()); assertTrue(testDir.mkdirs());
alice = DaggerSimplexMessagingIntegrationTestComponent.builder() alice = DaggerSimplexMessagingIntegrationTestComponent.builder()
.testDatabaseModule(new TestDatabaseModule(aliceDir)).build(); .testDatabaseModule(new TestDatabaseModule(aliceDir)).build();
alice.inject(new SystemModule.EagerSingletons());
bob = DaggerSimplexMessagingIntegrationTestComponent.builder() bob = DaggerSimplexMessagingIntegrationTestComponent.builder()
.testDatabaseModule(new TestDatabaseModule(bobDir)).build(); .testDatabaseModule(new TestDatabaseModule(bobDir)).build();
bob.inject(new SystemModule.EagerSingletons());
} }
@Test @Test
@@ -183,6 +186,7 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
private volatile boolean messageAdded = false; private volatile boolean messageAdded = false;
@Override
public void eventOccurred(Event e) { public void eventOccurred(Event e) {
if (e instanceof MessageAddedEvent) messageAdded = true; if (e instanceof MessageAddedEvent) messageAdded = true;
} }

View File

@@ -21,6 +21,7 @@ import org.briarproject.lifecycle.LifecycleModule;
import org.briarproject.messaging.MessagingModule; import org.briarproject.messaging.MessagingModule;
import org.briarproject.plugins.PluginsModule; import org.briarproject.plugins.PluginsModule;
import org.briarproject.sync.SyncModule; import org.briarproject.sync.SyncModule;
import org.briarproject.system.SystemModule;
import org.briarproject.transport.TransportModule; import org.briarproject.transport.TransportModule;
import javax.inject.Singleton; import javax.inject.Singleton;
@@ -31,7 +32,7 @@ import dagger.Component;
@Component(modules = { @Component(modules = {
TestDatabaseModule.class, TestDatabaseModule.class,
TestPluginsModule.class, TestPluginsModule.class,
TestSystemModule.class, TestSeedProviderModule.class,
ClientsModule.class, ClientsModule.class,
ContactModule.class, ContactModule.class,
CryptoModule.class, CryptoModule.class,
@@ -43,11 +44,12 @@ import dagger.Component;
MessagingModule.class, MessagingModule.class,
PluginsModule.class, PluginsModule.class,
SyncModule.class, SyncModule.class,
SystemModule.class,
TransportModule.class TransportModule.class
}) })
public interface SimplexMessagingIntegrationTestComponent { public interface SimplexMessagingIntegrationTestComponent {
void inject(SimplexMessagingIntegrationTest testCase); void inject(SystemModule.EagerSingletons init);
LifecycleManager getLifecycleManager(); LifecycleManager getLifecycleManager();

View File

@@ -10,7 +10,7 @@ import dagger.Component;
@Singleton @Singleton
@Component(modules = { @Component(modules = {
TestSystemModule.class, TestSeedProviderModule.class,
CryptoModule.class, CryptoModule.class,
SyncModule.class, SyncModule.class,
TransportModule.class TransportModule.class

View File

@@ -15,6 +15,7 @@ import dagger.Provides;
public class AndroidSystemModule { public class AndroidSystemModule {
@Provides @Provides
@Singleton
public SeedProvider provideSeedProvider(Application app) { public SeedProvider provideSeedProvider(Application app) {
return new AndroidSeedProvider(app); return new AndroidSeedProvider(app);
} }

View File

@@ -1,27 +0,0 @@
package org.briarproject.api.system;
import java.util.TimerTask;
/**
* A wrapper around a {@link java.util.Timer} that allows it to be replaced for
* testing.
*/
public interface Timer {
/** @see {@link java.util.Timer#cancel()} */
void cancel();
/** @see {@link java.util.Timer#purge()} */
int purge();
/** @see {@link java.util.Timer#schedule(TimerTask, long)} */
void schedule(TimerTask task, long delay);
/** @see {@link java.util.Timer#schedule(TimerTask, long, long)} */
void schedule(TimerTask task, long delay, long period);
/**
* @see {@link java.util.Timer#scheduleAtFixedRate(TimerTask, long, long)}
*/
void scheduleAtFixedRate(TimerTask task, long delay, long period);
}

View File

@@ -10,6 +10,7 @@ import org.briarproject.messaging.MessagingModule;
import org.briarproject.plugins.PluginsModule; import org.briarproject.plugins.PluginsModule;
import org.briarproject.properties.PropertiesModule; import org.briarproject.properties.PropertiesModule;
import org.briarproject.sync.SyncModule; import org.briarproject.sync.SyncModule;
import org.briarproject.system.SystemModule;
import org.briarproject.transport.TransportModule; import org.briarproject.transport.TransportModule;
public interface CoreEagerSingletons { public interface CoreEagerSingletons {
@@ -34,5 +35,7 @@ public interface CoreEagerSingletons {
void inject(SyncModule.EagerSingletons init); void inject(SyncModule.EagerSingletons init);
void inject(SystemModule.EagerSingletons init);
void inject(TransportModule.EagerSingletons init); void inject(TransportModule.EagerSingletons init);
} }

View File

@@ -61,6 +61,7 @@ public class CoreModule {
c.inject(new PluginsModule.EagerSingletons()); c.inject(new PluginsModule.EagerSingletons());
c.inject(new PropertiesModule.EagerSingletons()); c.inject(new PropertiesModule.EagerSingletons());
c.inject(new SyncModule.EagerSingletons()); c.inject(new SyncModule.EagerSingletons());
c.inject(new SystemModule.EagerSingletons());
c.inject(new TransportModule.EagerSingletons()); c.inject(new TransportModule.EagerSingletons());
c.inject(new IntroductionModule.EagerSingletons()); c.inject(new IntroductionModule.EagerSingletons());
} }

View File

@@ -122,9 +122,6 @@ class PluginManagerImpl implements PluginManager, Service, EventListener {
public void stopService() throws ServiceException { public void stopService() throws ServiceException {
// Stop listening for events // Stop listening for events
eventBus.removeListener(this); eventBus.removeListener(this);
// Stop the poller
LOG.info("Stopping poller");
poller.stop();
final CountDownLatch latch = new CountDownLatch(plugins.size()); final CountDownLatch latch = new CountDownLatch(plugins.size());
// Stop the simplex plugins // Stop the simplex plugins
LOG.info("Stopping simplex plugins"); LOG.info("Stopping simplex plugins");
@@ -432,7 +429,7 @@ class PluginManagerImpl implements PluginManager, Service, EventListener {
public void transportEnabled() { public void transportEnabled() {
eventBus.broadcast(new TransportEnabledEvent(id)); eventBus.broadcast(new TransportEnabledEvent(id));
Plugin p = plugins.get(id); Plugin p = plugins.get(id);
if (p != null) poller.pollNow(p); if (p != null && p.shouldPoll()) poller.pollNow(p);
} }
@Override @Override

View File

@@ -8,12 +8,10 @@ import org.briarproject.api.plugins.ConnectionManager;
import org.briarproject.api.plugins.ConnectionRegistry; import org.briarproject.api.plugins.ConnectionRegistry;
import org.briarproject.api.plugins.PluginManager; import org.briarproject.api.plugins.PluginManager;
import org.briarproject.api.sync.SyncSessionFactory; import org.briarproject.api.sync.SyncSessionFactory;
import org.briarproject.api.system.Timer;
import org.briarproject.api.transport.KeyManager; import org.briarproject.api.transport.KeyManager;
import org.briarproject.api.transport.StreamReaderFactory; import org.briarproject.api.transport.StreamReaderFactory;
import org.briarproject.api.transport.StreamWriterFactory; import org.briarproject.api.transport.StreamWriterFactory;
import java.security.SecureRandom;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import javax.inject.Inject; import javax.inject.Inject;
@@ -36,10 +34,9 @@ public class PluginsModule {
} }
@Provides @Provides
Poller providePoller(@IoExecutor Executor ioExecutor, @Singleton
ConnectionRegistry connectionRegistry, SecureRandom random, Poller providePoller(PollerImpl poller) {
Timer timer) { return poller;
return new PollerImpl(ioExecutor, connectionRegistry, random, timer);
} }
@Provides @Provides

View File

@@ -6,7 +6,4 @@ interface Poller {
/** Tells the poller to poll the given plugin immediately. */ /** Tells the poller to poll the given plugin immediately. */
void pollNow(Plugin p); void pollNow(Plugin p);
/** Stops the poller. */
void stop();
} }

View File

@@ -4,17 +4,17 @@ import org.briarproject.api.TransportId;
import org.briarproject.api.lifecycle.IoExecutor; import org.briarproject.api.lifecycle.IoExecutor;
import org.briarproject.api.plugins.ConnectionRegistry; import org.briarproject.api.plugins.ConnectionRegistry;
import org.briarproject.api.plugins.Plugin; import org.briarproject.api.plugins.Plugin;
import org.briarproject.api.system.Timer;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.util.Map; import java.util.Map;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.inject.Inject; import javax.inject.Inject;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.logging.Level.INFO; import static java.util.logging.Level.INFO;
class PollerImpl implements Poller { class PollerImpl implements Poller {
@@ -23,31 +23,26 @@ class PollerImpl implements Poller {
Logger.getLogger(PollerImpl.class.getName()); Logger.getLogger(PollerImpl.class.getName());
private final Executor ioExecutor; private final Executor ioExecutor;
private final ScheduledExecutorService scheduler;
private final ConnectionRegistry connectionRegistry; private final ConnectionRegistry connectionRegistry;
private final SecureRandom random; private final SecureRandom random;
private final Timer timer;
private final Map<TransportId, PollTask> tasks; private final Map<TransportId, PollTask> tasks;
@Inject @Inject
PollerImpl(@IoExecutor Executor ioExecutor, PollerImpl(@IoExecutor Executor ioExecutor,
ConnectionRegistry connectionRegistry, SecureRandom random, ScheduledExecutorService scheduler,
Timer timer) { ConnectionRegistry connectionRegistry, SecureRandom random) {
this.ioExecutor = ioExecutor; this.ioExecutor = ioExecutor;
this.connectionRegistry = connectionRegistry; this.connectionRegistry = connectionRegistry;
this.random = random; this.random = random;
this.timer = timer; this.scheduler = scheduler;
tasks = new ConcurrentHashMap<TransportId, PollTask>(); tasks = new ConcurrentHashMap<TransportId, PollTask>();
} }
@Override
public void stop() {
timer.cancel();
}
@Override @Override
public void pollNow(Plugin p) { public void pollNow(Plugin p) {
// Randomise next polling interval // Randomise next polling interval
if (p.shouldPoll()) schedule(p, 0, true); schedule(p, 0, true);
} }
private void schedule(Plugin p, int interval, boolean randomiseNext) { private void schedule(Plugin p, int interval, boolean randomiseNext) {
@@ -55,7 +50,7 @@ class PollerImpl implements Poller {
PollTask task = new PollTask(p, randomiseNext); PollTask task = new PollTask(p, randomiseNext);
PollTask replaced = tasks.put(p.getId(), task); PollTask replaced = tasks.put(p.getId(), task);
if (replaced != null) replaced.cancel(); if (replaced != null) replaced.cancel();
timer.schedule(task, interval); scheduler.schedule(task, interval, MILLISECONDS);
} }
private void poll(final Plugin p) { private void poll(final Plugin p) {
@@ -69,18 +64,25 @@ class PollerImpl implements Poller {
}); });
} }
private class PollTask extends TimerTask { private class PollTask implements Runnable {
private final Plugin plugin; private final Plugin plugin;
private final boolean randomiseNext; private final boolean randomiseNext;
private volatile boolean cancelled = false;
private PollTask(Plugin plugin, boolean randomiseNext) { private PollTask(Plugin plugin, boolean randomiseNext) {
this.plugin = plugin; this.plugin = plugin;
this.randomiseNext = randomiseNext; this.randomiseNext = randomiseNext;
} }
private void cancel() {
cancelled = true;
}
@Override @Override
public void run() { public void run() {
if (cancelled) return;
tasks.remove(plugin.getId()); tasks.remove(plugin.getId());
int interval = plugin.getPollingInterval(); int interval = plugin.getPollingInterval();
if (randomiseNext) if (randomiseNext)

View File

@@ -1,23 +1,41 @@
package org.briarproject.system; package org.briarproject.system;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.system.Clock; import org.briarproject.api.system.Clock;
import org.briarproject.api.system.LocationUtils;
import org.briarproject.api.system.SeedProvider; import java.util.concurrent.Executors;
import org.briarproject.api.system.Timer; import java.util.concurrent.ScheduledExecutorService;
import javax.inject.Inject;
import javax.inject.Singleton;
import dagger.Module; import dagger.Module;
import dagger.Provides; import dagger.Provides;
@Module @Module
public class SystemModule { public class SystemModule {
public static class EagerSingletons {
@Inject
ScheduledExecutorService scheduledExecutorService;
}
private final ScheduledExecutorService scheduler;
public SystemModule() {
scheduler = Executors.newSingleThreadScheduledExecutor();
}
@Provides @Provides
Clock provideClock() { Clock provideClock() {
return new SystemClock(); return new SystemClock();
} }
@Provides @Provides
Timer provideTimer() { @Singleton
return new SystemTimer(); ScheduledExecutorService provideScheduledExecutorService(
LifecycleManager lifecycleManager) {
lifecycleManager.registerForShutdown(scheduler);
return scheduler;
} }
} }

View File

@@ -1,31 +0,0 @@
package org.briarproject.system;
import java.util.TimerTask;
import org.briarproject.api.system.Timer;
/** Default timer implementation. */
public class SystemTimer implements Timer {
private final java.util.Timer timer = new java.util.Timer(true);
public void cancel() {
timer.cancel();
}
public int purge() {
return timer.purge();
}
public void schedule(TimerTask task, long delay) {
timer.schedule(task, delay);
}
public void schedule(TimerTask task, long delay, long period) {
timer.schedule(task, delay, period);
}
public void scheduleAtFixedRate(TimerTask task, long delay, long period) {
timer.scheduleAtFixedRate(task, delay, period);
}
}

View File

@@ -19,7 +19,6 @@ import org.briarproject.api.plugins.PluginConfig;
import org.briarproject.api.plugins.duplex.DuplexPluginFactory; import org.briarproject.api.plugins.duplex.DuplexPluginFactory;
import org.briarproject.api.plugins.simplex.SimplexPluginFactory; import org.briarproject.api.plugins.simplex.SimplexPluginFactory;
import org.briarproject.api.system.Clock; import org.briarproject.api.system.Clock;
import org.briarproject.api.system.Timer;
import org.briarproject.api.transport.KeyManager; import org.briarproject.api.transport.KeyManager;
import org.briarproject.api.transport.StreamContext; import org.briarproject.api.transport.StreamContext;
@@ -28,6 +27,7 @@ import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.inject.Inject; import javax.inject.Inject;
@@ -42,21 +42,22 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
private final DatabaseComponent db; private final DatabaseComponent db;
private final CryptoComponent crypto; private final CryptoComponent crypto;
private final Executor dbExecutor; private final Executor dbExecutor;
private final ScheduledExecutorService scheduler;
private final PluginConfig pluginConfig; private final PluginConfig pluginConfig;
private final Timer timer;
private final Clock clock; private final Clock clock;
private final Map<ContactId, Boolean> activeContacts; private final Map<ContactId, Boolean> activeContacts;
private final ConcurrentHashMap<TransportId, TransportKeyManager> managers; private final ConcurrentHashMap<TransportId, TransportKeyManager> managers;
@Inject @Inject
KeyManagerImpl(DatabaseComponent db, CryptoComponent crypto, KeyManagerImpl(DatabaseComponent db, CryptoComponent crypto,
@DatabaseExecutor Executor dbExecutor, PluginConfig pluginConfig, @DatabaseExecutor Executor dbExecutor,
Timer timer, Clock clock) { ScheduledExecutorService scheduler, PluginConfig pluginConfig,
Clock clock) {
this.db = db; this.db = db;
this.crypto = crypto; this.crypto = crypto;
this.dbExecutor = dbExecutor; this.dbExecutor = dbExecutor;
this.scheduler = scheduler;
this.pluginConfig = pluginConfig; this.pluginConfig = pluginConfig;
this.timer = timer;
this.clock = clock; this.clock = clock;
// Use a ConcurrentHashMap as a thread-safe set // Use a ConcurrentHashMap as a thread-safe set
activeContacts = new ConcurrentHashMap<ContactId, Boolean>(); activeContacts = new ConcurrentHashMap<ContactId, Boolean>();
@@ -80,7 +81,8 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
db.addTransport(txn, e.getKey(), e.getValue()); db.addTransport(txn, e.getKey(), e.getValue());
for (Entry<TransportId, Integer> e : transports.entrySet()) { for (Entry<TransportId, Integer> e : transports.entrySet()) {
TransportKeyManager m = new TransportKeyManager(db, crypto, TransportKeyManager m = new TransportKeyManager(db, crypto,
timer, clock, e.getKey(), e.getValue()); dbExecutor, scheduler, clock, e.getKey(),
e.getValue());
managers.put(e.getKey(), m); managers.put(e.getKey(), m);
m.start(txn); m.start(txn);
} }
@@ -97,12 +99,14 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
public void stopService() { public void stopService() {
} }
@Override
public void addContact(Transaction txn, ContactId c, SecretKey master, public void addContact(Transaction txn, ContactId c, SecretKey master,
long timestamp, boolean alice) throws DbException { long timestamp, boolean alice) throws DbException {
for (TransportKeyManager m : managers.values()) for (TransportKeyManager m : managers.values())
m.addContact(txn, c, master, timestamp, alice); m.addContact(txn, c, master, timestamp, alice);
} }
@Override
public StreamContext getStreamContext(ContactId c, TransportId t) public StreamContext getStreamContext(ContactId c, TransportId t)
throws DbException { throws DbException {
// Don't allow outgoing streams to inactive contacts // Don't allow outgoing streams to inactive contacts
@@ -123,6 +127,7 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
return ctx; return ctx;
} }
@Override
public StreamContext getStreamContext(TransportId t, byte[] tag) public StreamContext getStreamContext(TransportId t, byte[] tag)
throws DbException { throws DbException {
TransportKeyManager m = managers.get(t); TransportKeyManager m = managers.get(t);
@@ -141,6 +146,7 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
return ctx; return ctx;
} }
@Override
public void eventOccurred(Event e) { public void eventOccurred(Event e) {
if (e instanceof ContactRemovedEvent) { if (e instanceof ContactRemovedEvent) {
removeContact(((ContactRemovedEvent) e).getContactId()); removeContact(((ContactRemovedEvent) e).getContactId());
@@ -154,6 +160,7 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
private void removeContact(final ContactId c) { private void removeContact(final ContactId c) {
activeContacts.remove(c); activeContacts.remove(c);
dbExecutor.execute(new Runnable() { dbExecutor.execute(new Runnable() {
@Override
public void run() { public void run() {
for (TransportKeyManager m : managers.values()) for (TransportKeyManager m : managers.values())
m.removeContact(c); m.removeContact(c);

View File

@@ -9,7 +9,6 @@ import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException; import org.briarproject.api.db.DbException;
import org.briarproject.api.db.Transaction; import org.briarproject.api.db.Transaction;
import org.briarproject.api.system.Clock; import org.briarproject.api.system.Clock;
import org.briarproject.api.system.Timer;
import org.briarproject.api.transport.StreamContext; import org.briarproject.api.transport.StreamContext;
import org.briarproject.api.transport.TransportKeys; import org.briarproject.api.transport.TransportKeys;
import org.briarproject.transport.ReorderingWindow.Change; import org.briarproject.transport.ReorderingWindow.Change;
@@ -18,10 +17,12 @@ import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.TimerTask; import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Logger; import java.util.logging.Logger;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE; import static org.briarproject.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE;
import static org.briarproject.api.transport.TransportConstants.TAG_LENGTH; import static org.briarproject.api.transport.TransportConstants.TAG_LENGTH;
@@ -34,7 +35,8 @@ class TransportKeyManager {
private final DatabaseComponent db; private final DatabaseComponent db;
private final CryptoComponent crypto; private final CryptoComponent crypto;
private final Timer timer; private final Executor dbExecutor;
private final ScheduledExecutorService scheduler;
private final Clock clock; private final Clock clock;
private final TransportId transportId; private final TransportId transportId;
private final long rotationPeriodLength; private final long rotationPeriodLength;
@@ -46,11 +48,12 @@ class TransportKeyManager {
private final Map<ContactId, MutableTransportKeys> keys; private final Map<ContactId, MutableTransportKeys> keys;
TransportKeyManager(DatabaseComponent db, CryptoComponent crypto, TransportKeyManager(DatabaseComponent db, CryptoComponent crypto,
Timer timer, Clock clock, TransportId transportId, Executor dbExecutor, ScheduledExecutorService scheduler,
long maxLatency) { Clock clock, TransportId transportId, long maxLatency) {
this.db = db; this.db = db;
this.crypto = crypto; this.crypto = crypto;
this.timer = timer; this.dbExecutor = dbExecutor;
this.scheduler = scheduler;
this.clock = clock; this.clock = clock;
this.transportId = transportId; this.transportId = transportId;
rotationPeriodLength = maxLatency + MAX_CLOCK_DIFFERENCE; rotationPeriodLength = maxLatency + MAX_CLOCK_DIFFERENCE;
@@ -122,7 +125,19 @@ class TransportKeyManager {
} }
private void scheduleKeyRotation(long now) { private void scheduleKeyRotation(long now) {
TimerTask task = new TimerTask() { Runnable task = new Runnable() {
@Override
public void run() {
rotateKeys();
}
};
long delay = rotationPeriodLength - now % rotationPeriodLength;
scheduler.schedule(task, delay, MILLISECONDS);
}
private void rotateKeys() {
dbExecutor.execute(new Runnable() {
@Override
public void run() { public void run() {
try { try {
Transaction txn = db.startTransaction(false); Transaction txn = db.startTransaction(false);
@@ -137,9 +152,7 @@ class TransportKeyManager {
LOG.log(WARNING, e.toString(), e); LOG.log(WARNING, e.toString(), e);
} }
} }
}; });
long delay = rotationPeriodLength - now % rotationPeriodLength;
timer.schedule(task, delay);
} }
void addContact(Transaction txn, ContactId c, SecretKey master, void addContact(Transaction txn, ContactId c, SecretKey master,

View File

@@ -18,7 +18,8 @@ import dagger.Provides;
public class TransportModule { public class TransportModule {
public static class EagerSingletons { public static class EagerSingletons {
@Inject KeyManager keyManager; @Inject
KeyManager keyManager;
} }
@Provides @Provides
@@ -35,7 +36,7 @@ public class TransportModule {
@Provides @Provides
@Singleton @Singleton
KeyManager getKeyManager(LifecycleManager lifecycleManager, KeyManager provideKeyManager(LifecycleManager lifecycleManager,
EventBus eventBus, KeyManagerImpl keyManager) { EventBus eventBus, KeyManagerImpl keyManager) {
lifecycleManager.registerService(keyManager); lifecycleManager.registerService(keyManager);
eventBus.addListener(keyManager); eventBus.addListener(keyManager);

View File

@@ -0,0 +1,19 @@
package org.briarproject.system;
import org.briarproject.api.system.SeedProvider;
import org.briarproject.util.OsUtils;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
@Module
public class DesktopSeedProviderModule {
@Provides
@Singleton
SeedProvider provideSeedProvider() {
return OsUtils.isLinux() ? new LinuxSeedProvider() : null;
}
}

View File

@@ -1,31 +0,0 @@
package org.briarproject.system;
import org.briarproject.api.system.Clock;
import org.briarproject.api.system.SeedProvider;
import org.briarproject.api.system.Timer;
import org.briarproject.util.OsUtils;
import dagger.Module;
import dagger.Provides;
@Module
public class DesktopSystemModule {
@Provides
Clock provideClock() {
return new SystemClock();
}
@Provides
Timer provideTimer() {
return new SystemTimer();
}
@Provides
SeedProvider provideSeedProvider() {
if (OsUtils.isLinux()) {
return new LinuxSeedProvider();
}
return null;
}
}

View File

@@ -0,0 +1,18 @@
package org.briarproject;
import org.briarproject.api.system.SeedProvider;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
@Module
public class TestSeedProviderModule {
@Provides
@Singleton
SeedProvider provideSeedProvider() {
return new TestSeedProvider();
}
}

View File

@@ -1,29 +0,0 @@
package org.briarproject;
import org.briarproject.api.system.Clock;
import org.briarproject.api.system.SeedProvider;
import org.briarproject.api.system.Timer;
import org.briarproject.system.SystemClock;
import org.briarproject.system.SystemTimer;
import dagger.Module;
import dagger.Provides;
@Module
public class TestSystemModule {
@Provides
Clock provideClock() {
return new SystemClock();
}
@Provides
Timer provideSystemTimer() {
return new SystemTimer();
}
@Provides
SeedProvider provideSeedProvider() {
return new TestSeedProvider();
}
}

View File

@@ -113,8 +113,6 @@ public class PluginManagerImplTest extends BriarTestCase {
// stop() // stop()
// Stop listening for events // Stop listening for events
oneOf(eventBus).removeListener(with(any(EventListener.class))); oneOf(eventBus).removeListener(with(any(EventListener.class)));
// Stop the poller
oneOf(poller).stop();
// Stop the plugins // Stop the plugins
oneOf(simplexPlugin).stop(); oneOf(simplexPlugin).stop();
oneOf(duplexPlugin).stop(); oneOf(duplexPlugin).stop();
@@ -248,8 +246,6 @@ public class PluginManagerImplTest extends BriarTestCase {
// stop() // stop()
// Stop listening for events // Stop listening for events
oneOf(eventBus).removeListener(with(any(EventListener.class))); oneOf(eventBus).removeListener(with(any(EventListener.class)));
// Stop the poller
oneOf(poller).stop();
// Stop the plugins // Stop the plugins
oneOf(simplexPlugin).stop(); oneOf(simplexPlugin).stop();
oneOf(simplexPlugin1).stop(); oneOf(simplexPlugin1).stop();

View File

@@ -9,7 +9,6 @@ import org.briarproject.api.crypto.SecretKey;
import org.briarproject.api.db.DatabaseComponent; import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.Transaction; import org.briarproject.api.db.Transaction;
import org.briarproject.api.system.Clock; import org.briarproject.api.system.Clock;
import org.briarproject.api.system.Timer;
import org.briarproject.api.transport.IncomingKeys; import org.briarproject.api.transport.IncomingKeys;
import org.briarproject.api.transport.OutgoingKeys; import org.briarproject.api.transport.OutgoingKeys;
import org.briarproject.api.transport.StreamContext; import org.briarproject.api.transport.StreamContext;
@@ -28,8 +27,10 @@ import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.TimerTask; import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.briarproject.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE; import static org.briarproject.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE;
import static org.briarproject.api.transport.TransportConstants.REORDERING_WINDOW_SIZE; import static org.briarproject.api.transport.TransportConstants.REORDERING_WINDOW_SIZE;
import static org.briarproject.api.transport.TransportConstants.TAG_LENGTH; import static org.briarproject.api.transport.TransportConstants.TAG_LENGTH;
@@ -56,11 +57,12 @@ public class TransportKeyManagerTest extends BriarTestCase {
Mockery context = new Mockery(); Mockery context = new Mockery();
final DatabaseComponent db = context.mock(DatabaseComponent.class); final DatabaseComponent db = context.mock(DatabaseComponent.class);
final CryptoComponent crypto = context.mock(CryptoComponent.class); final CryptoComponent crypto = context.mock(CryptoComponent.class);
final Timer timer = context.mock(Timer.class); final Executor dbExecutor = context.mock(Executor.class);
final ScheduledExecutorService scheduler =
context.mock(ScheduledExecutorService.class);
final Clock clock = context.mock(Clock.class); final Clock clock = context.mock(Clock.class);
final Map<ContactId, TransportKeys> loaded = final Map<ContactId, TransportKeys> loaded = new LinkedHashMap<>();
new LinkedHashMap<ContactId, TransportKeys>();
final TransportKeys shouldRotate = createTransportKeys(900, 0); final TransportKeys shouldRotate = createTransportKeys(900, 0);
final TransportKeys shouldNotRotate = createTransportKeys(1000, 0); final TransportKeys shouldNotRotate = createTransportKeys(1000, 0);
loaded.put(contactId, shouldRotate); loaded.put(contactId, shouldRotate);
@@ -90,12 +92,12 @@ public class TransportKeyManagerTest extends BriarTestCase {
oneOf(db).updateTransportKeys(txn, oneOf(db).updateTransportKeys(txn,
Collections.singletonMap(contactId, rotated)); Collections.singletonMap(contactId, rotated));
// Schedule key rotation at the start of the next rotation period // Schedule key rotation at the start of the next rotation period
oneOf(timer).schedule(with(any(TimerTask.class)), oneOf(scheduler).schedule(with(any(Runnable.class)),
with(rotationPeriodLength - 1)); with(rotationPeriodLength - 1), with(MILLISECONDS));
}}); }});
TransportKeyManager transportKeyManager = new TransportKeyManager(db, TransportKeyManager transportKeyManager = new TransportKeyManager(db,
crypto, timer, clock, transportId, maxLatency); crypto, dbExecutor, scheduler, clock, transportId, maxLatency);
transportKeyManager.start(txn); transportKeyManager.start(txn);
context.assertIsSatisfied(); context.assertIsSatisfied();
@@ -106,7 +108,9 @@ public class TransportKeyManagerTest extends BriarTestCase {
Mockery context = new Mockery(); Mockery context = new Mockery();
final DatabaseComponent db = context.mock(DatabaseComponent.class); final DatabaseComponent db = context.mock(DatabaseComponent.class);
final CryptoComponent crypto = context.mock(CryptoComponent.class); final CryptoComponent crypto = context.mock(CryptoComponent.class);
final Timer timer = context.mock(Timer.class); final Executor dbExecutor = context.mock(Executor.class);
final ScheduledExecutorService scheduler =
context.mock(ScheduledExecutorService.class);
final Clock clock = context.mock(Clock.class); final Clock clock = context.mock(Clock.class);
final boolean alice = true; final boolean alice = true;
@@ -135,7 +139,7 @@ public class TransportKeyManagerTest extends BriarTestCase {
}}); }});
TransportKeyManager transportKeyManager = new TransportKeyManager(db, TransportKeyManager transportKeyManager = new TransportKeyManager(db,
crypto, timer, clock, transportId, maxLatency); crypto, dbExecutor, scheduler, clock, transportId, maxLatency);
// The timestamp is 1 ms before the start of rotation period 1000 // The timestamp is 1 ms before the start of rotation period 1000
long timestamp = rotationPeriodLength * 1000 - 1; long timestamp = rotationPeriodLength * 1000 - 1;
transportKeyManager.addContact(txn, contactId, masterKey, timestamp, transportKeyManager.addContact(txn, contactId, masterKey, timestamp,
@@ -150,13 +154,15 @@ public class TransportKeyManagerTest extends BriarTestCase {
Mockery context = new Mockery(); Mockery context = new Mockery();
final DatabaseComponent db = context.mock(DatabaseComponent.class); final DatabaseComponent db = context.mock(DatabaseComponent.class);
final CryptoComponent crypto = context.mock(CryptoComponent.class); final CryptoComponent crypto = context.mock(CryptoComponent.class);
final Timer timer = context.mock(Timer.class); final Executor dbExecutor = context.mock(Executor.class);
final ScheduledExecutorService scheduler =
context.mock(ScheduledExecutorService.class);
final Clock clock = context.mock(Clock.class); final Clock clock = context.mock(Clock.class);
final Transaction txn = new Transaction(null, false); final Transaction txn = new Transaction(null, false);
TransportKeyManager transportKeyManager = new TransportKeyManager(db, TransportKeyManager transportKeyManager = new TransportKeyManager(db,
crypto, timer, clock, transportId, maxLatency); crypto, dbExecutor, scheduler, clock, transportId, maxLatency);
assertNull(transportKeyManager.getStreamContext(txn, contactId)); assertNull(transportKeyManager.getStreamContext(txn, contactId));
context.assertIsSatisfied(); context.assertIsSatisfied();
@@ -168,7 +174,9 @@ public class TransportKeyManagerTest extends BriarTestCase {
Mockery context = new Mockery(); Mockery context = new Mockery();
final DatabaseComponent db = context.mock(DatabaseComponent.class); final DatabaseComponent db = context.mock(DatabaseComponent.class);
final CryptoComponent crypto = context.mock(CryptoComponent.class); final CryptoComponent crypto = context.mock(CryptoComponent.class);
final Timer timer = context.mock(Timer.class); final Executor dbExecutor = context.mock(Executor.class);
final ScheduledExecutorService scheduler =
context.mock(ScheduledExecutorService.class);
final Clock clock = context.mock(Clock.class); final Clock clock = context.mock(Clock.class);
final boolean alice = true; final boolean alice = true;
@@ -198,7 +206,7 @@ public class TransportKeyManagerTest extends BriarTestCase {
}}); }});
TransportKeyManager transportKeyManager = new TransportKeyManager(db, TransportKeyManager transportKeyManager = new TransportKeyManager(db,
crypto, timer, clock, transportId, maxLatency); crypto, dbExecutor, scheduler, clock, transportId, maxLatency);
// The timestamp is at the start of rotation period 1000 // The timestamp is at the start of rotation period 1000
long timestamp = rotationPeriodLength * 1000; long timestamp = rotationPeriodLength * 1000;
transportKeyManager.addContact(txn, contactId, masterKey, timestamp, transportKeyManager.addContact(txn, contactId, masterKey, timestamp,
@@ -213,7 +221,9 @@ public class TransportKeyManagerTest extends BriarTestCase {
Mockery context = new Mockery(); Mockery context = new Mockery();
final DatabaseComponent db = context.mock(DatabaseComponent.class); final DatabaseComponent db = context.mock(DatabaseComponent.class);
final CryptoComponent crypto = context.mock(CryptoComponent.class); final CryptoComponent crypto = context.mock(CryptoComponent.class);
final Timer timer = context.mock(Timer.class); final Executor dbExecutor = context.mock(Executor.class);
final ScheduledExecutorService scheduler =
context.mock(ScheduledExecutorService.class);
final Clock clock = context.mock(Clock.class); final Clock clock = context.mock(Clock.class);
final boolean alice = true; final boolean alice = true;
@@ -245,7 +255,7 @@ public class TransportKeyManagerTest extends BriarTestCase {
}}); }});
TransportKeyManager transportKeyManager = new TransportKeyManager(db, TransportKeyManager transportKeyManager = new TransportKeyManager(db,
crypto, timer, clock, transportId, maxLatency); crypto, dbExecutor, scheduler, clock, transportId, maxLatency);
// The timestamp is at the start of rotation period 1000 // The timestamp is at the start of rotation period 1000
long timestamp = rotationPeriodLength * 1000; long timestamp = rotationPeriodLength * 1000;
transportKeyManager.addContact(txn, contactId, masterKey, timestamp, transportKeyManager.addContact(txn, contactId, masterKey, timestamp,
@@ -271,7 +281,9 @@ public class TransportKeyManagerTest extends BriarTestCase {
Mockery context = new Mockery(); Mockery context = new Mockery();
final DatabaseComponent db = context.mock(DatabaseComponent.class); final DatabaseComponent db = context.mock(DatabaseComponent.class);
final CryptoComponent crypto = context.mock(CryptoComponent.class); final CryptoComponent crypto = context.mock(CryptoComponent.class);
final Timer timer = context.mock(Timer.class); final Executor dbExecutor = context.mock(Executor.class);
final ScheduledExecutorService scheduler =
context.mock(ScheduledExecutorService.class);
final Clock clock = context.mock(Clock.class); final Clock clock = context.mock(Clock.class);
final boolean alice = true; final boolean alice = true;
@@ -299,7 +311,7 @@ public class TransportKeyManagerTest extends BriarTestCase {
}}); }});
TransportKeyManager transportKeyManager = new TransportKeyManager(db, TransportKeyManager transportKeyManager = new TransportKeyManager(db,
crypto, timer, clock, transportId, maxLatency); crypto, dbExecutor, scheduler, clock, transportId, maxLatency);
// The timestamp is at the start of rotation period 1000 // The timestamp is at the start of rotation period 1000
long timestamp = rotationPeriodLength * 1000; long timestamp = rotationPeriodLength * 1000;
transportKeyManager.addContact(txn, contactId, masterKey, timestamp, transportKeyManager.addContact(txn, contactId, masterKey, timestamp,
@@ -315,13 +327,15 @@ public class TransportKeyManagerTest extends BriarTestCase {
Mockery context = new Mockery(); Mockery context = new Mockery();
final DatabaseComponent db = context.mock(DatabaseComponent.class); final DatabaseComponent db = context.mock(DatabaseComponent.class);
final CryptoComponent crypto = context.mock(CryptoComponent.class); final CryptoComponent crypto = context.mock(CryptoComponent.class);
final Timer timer = context.mock(Timer.class); final Executor dbExecutor = context.mock(Executor.class);
final ScheduledExecutorService scheduler =
context.mock(ScheduledExecutorService.class);
final Clock clock = context.mock(Clock.class); final Clock clock = context.mock(Clock.class);
final boolean alice = true; final boolean alice = true;
final TransportKeys transportKeys = createTransportKeys(1000, 0); final TransportKeys transportKeys = createTransportKeys(1000, 0);
// Keep a copy of the tags // Keep a copy of the tags
final List<byte[]> tags = new ArrayList<byte[]>(); final List<byte[]> tags = new ArrayList<>();
final Transaction txn = new Transaction(null, false); final Transaction txn = new Transaction(null, false);
context.checking(new Expectations() {{ context.checking(new Expectations() {{
@@ -352,7 +366,7 @@ public class TransportKeyManagerTest extends BriarTestCase {
}}); }});
TransportKeyManager transportKeyManager = new TransportKeyManager(db, TransportKeyManager transportKeyManager = new TransportKeyManager(db,
crypto, timer, clock, transportId, maxLatency); crypto, dbExecutor, scheduler, clock, transportId, maxLatency);
// The timestamp is at the start of rotation period 1000 // The timestamp is at the start of rotation period 1000
long timestamp = rotationPeriodLength * 1000; long timestamp = rotationPeriodLength * 1000;
transportKeyManager.addContact(txn, contactId, masterKey, timestamp, transportKeyManager.addContact(txn, contactId, masterKey, timestamp,
@@ -381,7 +395,9 @@ public class TransportKeyManagerTest extends BriarTestCase {
Mockery context = new Mockery(); Mockery context = new Mockery();
final DatabaseComponent db = context.mock(DatabaseComponent.class); final DatabaseComponent db = context.mock(DatabaseComponent.class);
final CryptoComponent crypto = context.mock(CryptoComponent.class); final CryptoComponent crypto = context.mock(CryptoComponent.class);
final Timer timer = context.mock(Timer.class); final Executor dbExecutor = context.mock(Executor.class);
final ScheduledExecutorService scheduler =
context.mock(ScheduledExecutorService.class);
final Clock clock = context.mock(Clock.class); final Clock clock = context.mock(Clock.class);
final TransportKeys transportKeys = createTransportKeys(1000, 0); final TransportKeys transportKeys = createTransportKeys(1000, 0);
@@ -408,9 +424,11 @@ public class TransportKeyManagerTest extends BriarTestCase {
will(new EncodeTagAction()); will(new EncodeTagAction());
} }
// Schedule key rotation at the start of the next rotation period // Schedule key rotation at the start of the next rotation period
oneOf(timer).schedule(with(any(TimerTask.class)), oneOf(scheduler).schedule(with(any(Runnable.class)),
with(rotationPeriodLength)); with(rotationPeriodLength), with(MILLISECONDS));
will(new RunTimerTaskAction()); will(new RunAction());
oneOf(dbExecutor).execute(with(any(Runnable.class)));
will(new RunAction());
// Start a transaction for key rotation // Start a transaction for key rotation
oneOf(db).startTransaction(false); oneOf(db).startTransaction(false);
will(returnValue(txn1)); will(returnValue(txn1));
@@ -431,14 +449,14 @@ public class TransportKeyManagerTest extends BriarTestCase {
oneOf(db).updateTransportKeys(txn1, oneOf(db).updateTransportKeys(txn1,
Collections.singletonMap(contactId, rotated)); Collections.singletonMap(contactId, rotated));
// Schedule key rotation at the start of the next rotation period // Schedule key rotation at the start of the next rotation period
oneOf(timer).schedule(with(any(TimerTask.class)), oneOf(scheduler).schedule(with(any(Runnable.class)),
with(rotationPeriodLength)); with(rotationPeriodLength), with(MILLISECONDS));
// Commit the key rotation transaction // Commit the key rotation transaction
oneOf(db).endTransaction(txn1); oneOf(db).endTransaction(txn1);
}}); }});
TransportKeyManager transportKeyManager = new TransportKeyManager(db, TransportKeyManager transportKeyManager = new TransportKeyManager(db,
crypto, timer, clock, transportId, maxLatency); crypto, dbExecutor, scheduler, clock, transportId, maxLatency);
transportKeyManager.start(txn); transportKeyManager.start(txn);
assertTrue(txn1.isComplete()); assertTrue(txn1.isComplete());
@@ -484,18 +502,18 @@ public class TransportKeyManagerTest extends BriarTestCase {
} }
} }
private static class RunTimerTaskAction implements Action { private static class RunAction implements Action {
@Override @Override
public Object invoke(Invocation invocation) throws Throwable { public Object invoke(Invocation invocation) throws Throwable {
TimerTask task = (TimerTask) invocation.getParameter(0); Runnable task = (Runnable) invocation.getParameter(0);
task.run(); task.run();
return null; return null;
} }
@Override @Override
public void describeTo(Description description) { public void describeTo(Description description) {
description.appendText("schedules a timer task"); description.appendText("runs a runnable");
} }
} }
} }