From a0772852de6c44e6eea0ffc797822d1c1e9fb4e6 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Tue, 14 May 2019 17:51:54 +0100 Subject: [PATCH 1/4] Decouple poller from plugin manager. --- .../bramble/plugin/PluginManagerImpl.java | 32 +-- .../bramble/plugin/PluginModule.java | 12 + .../briarproject/bramble/plugin/Poller.java | 260 +---------------- .../bramble/plugin/PollerImpl.java | 264 ++++++++++++++++++ .../bramble/plugin/PluginManagerImplTest.java | 16 +- .../{PollerTest.java => PollerImplTest.java} | 68 ++--- 6 files changed, 310 insertions(+), 342 deletions(-) create mode 100644 bramble-core/src/main/java/org/briarproject/bramble/plugin/PollerImpl.java rename bramble-core/src/test/java/org/briarproject/bramble/plugin/{PollerTest.java => PollerImplTest.java} (88%) diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginManagerImpl.java index 34fecf711..7df91a487 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginManagerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginManagerImpl.java @@ -8,7 +8,6 @@ import org.briarproject.bramble.api.lifecycle.Service; import org.briarproject.bramble.api.lifecycle.ServiceException; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.plugin.ConnectionManager; -import org.briarproject.bramble.api.plugin.ConnectionRegistry; import org.briarproject.bramble.api.plugin.Plugin; import org.briarproject.bramble.api.plugin.PluginCallback; import org.briarproject.bramble.api.plugin.PluginConfig; @@ -30,10 +29,7 @@ import org.briarproject.bramble.api.properties.TransportProperties; import org.briarproject.bramble.api.properties.TransportPropertyManager; import org.briarproject.bramble.api.settings.Settings; import org.briarproject.bramble.api.settings.SettingsManager; -import org.briarproject.bramble.api.system.Clock; -import org.briarproject.bramble.api.system.Scheduler; -import java.security.SecureRandom; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -42,7 +38,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; -import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Logger; @@ -52,6 +47,7 @@ import javax.inject.Inject; import static java.util.logging.Level.FINE; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; +import static java.util.logging.Logger.getLogger; import static org.briarproject.bramble.util.LogUtils.logDuration; import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.bramble.util.LogUtils.now; @@ -61,18 +57,14 @@ import static org.briarproject.bramble.util.LogUtils.now; class PluginManagerImpl implements PluginManager, Service { private static final Logger LOG = - Logger.getLogger(PluginManagerImpl.class.getName()); + getLogger(PluginManagerImpl.class.getName()); private final Executor ioExecutor; - private final ScheduledExecutorService scheduler; private final EventBus eventBus; private final PluginConfig pluginConfig; private final ConnectionManager connectionManager; - private final ConnectionRegistry connectionRegistry; private final SettingsManager settingsManager; private final TransportPropertyManager transportPropertyManager; - private final SecureRandom random; - private final Clock clock; private final Map plugins; private final List simplexPlugins; private final List duplexPlugins; @@ -80,41 +72,25 @@ class PluginManagerImpl implements PluginManager, Service { private final AtomicBoolean used = new AtomicBoolean(false); @Inject - PluginManagerImpl(@IoExecutor Executor ioExecutor, - @Scheduler ScheduledExecutorService scheduler, EventBus eventBus, + PluginManagerImpl(@IoExecutor Executor ioExecutor, EventBus eventBus, PluginConfig pluginConfig, ConnectionManager connectionManager, - ConnectionRegistry connectionRegistry, SettingsManager settingsManager, - TransportPropertyManager transportPropertyManager, - SecureRandom random, Clock clock) { + TransportPropertyManager transportPropertyManager) { this.ioExecutor = ioExecutor; - this.scheduler = scheduler; this.eventBus = eventBus; this.pluginConfig = pluginConfig; this.connectionManager = connectionManager; - this.connectionRegistry = connectionRegistry; this.settingsManager = settingsManager; this.transportPropertyManager = transportPropertyManager; - this.random = random; - this.clock = clock; plugins = new ConcurrentHashMap<>(); simplexPlugins = new CopyOnWriteArrayList<>(); duplexPlugins = new CopyOnWriteArrayList<>(); startLatches = new ConcurrentHashMap<>(); - } @Override public void startService() { if (used.getAndSet(true)) throw new IllegalStateException(); - // Instantiate the poller - if (pluginConfig.shouldPoll()) { - LOG.info("Starting poller"); - Poller poller = new Poller(ioExecutor, scheduler, connectionManager, - connectionRegistry, this, transportPropertyManager, random, - clock); - eventBus.addListener(poller); - } // Instantiate the simplex plugins and start them asynchronously LOG.info("Starting simplex plugins"); for (SimplexPluginFactory f : pluginConfig.getSimplexFactories()) { diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginModule.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginModule.java index 499da88b9..bca57cc1e 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginModule.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginModule.java @@ -1,9 +1,11 @@ package org.briarproject.bramble.plugin; +import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.lifecycle.LifecycleManager; import org.briarproject.bramble.api.plugin.BackoffFactory; import org.briarproject.bramble.api.plugin.ConnectionManager; import org.briarproject.bramble.api.plugin.ConnectionRegistry; +import org.briarproject.bramble.api.plugin.PluginConfig; import org.briarproject.bramble.api.plugin.PluginManager; import javax.inject.Inject; @@ -18,6 +20,8 @@ public class PluginModule { public static class EagerSingletons { @Inject PluginManager pluginManager; + @Inject + Poller poller; } @Provides @@ -46,4 +50,12 @@ public class PluginModule { lifecycleManager.registerService(pluginManager); return pluginManager; } + + @Provides + @Singleton + Poller providePoller(PluginConfig config, EventBus eventBus, + PollerImpl poller) { + if (config.shouldPoll()) eventBus.addListener(poller); + return poller; + } } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/Poller.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/Poller.java index 6d758f1c9..ede44cb48 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/Poller.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/Poller.java @@ -1,259 +1,7 @@ package org.briarproject.bramble.plugin; -import org.briarproject.bramble.api.contact.ContactId; -import org.briarproject.bramble.api.contact.event.ContactAddedEvent; -import org.briarproject.bramble.api.db.DbException; -import org.briarproject.bramble.api.event.Event; -import org.briarproject.bramble.api.event.EventListener; -import org.briarproject.bramble.api.lifecycle.IoExecutor; -import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.plugin.ConnectionManager; -import org.briarproject.bramble.api.plugin.ConnectionRegistry; -import org.briarproject.bramble.api.plugin.Plugin; -import org.briarproject.bramble.api.plugin.PluginManager; -import org.briarproject.bramble.api.plugin.TransportConnectionWriter; -import org.briarproject.bramble.api.plugin.TransportId; -import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; -import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; -import org.briarproject.bramble.api.plugin.event.ConnectionClosedEvent; -import org.briarproject.bramble.api.plugin.event.ConnectionOpenedEvent; -import org.briarproject.bramble.api.plugin.event.TransportDisabledEvent; -import org.briarproject.bramble.api.plugin.event.TransportEnabledEvent; -import org.briarproject.bramble.api.plugin.simplex.SimplexPlugin; -import org.briarproject.bramble.api.properties.TransportProperties; -import org.briarproject.bramble.api.properties.TransportPropertyManager; -import org.briarproject.bramble.api.system.Clock; -import org.briarproject.bramble.api.system.Scheduler; - -import java.security.SecureRandom; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.Executor; -import java.util.concurrent.Future; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; -import java.util.logging.Logger; - -import javax.annotation.concurrent.ThreadSafe; - -import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static java.util.logging.Level.INFO; -import static java.util.logging.Level.WARNING; -import static org.briarproject.bramble.util.LogUtils.logException; - -@ThreadSafe -@NotNullByDefault -class Poller implements EventListener { - - private static final Logger LOG = Logger.getLogger(Poller.class.getName()); - - private final Executor ioExecutor; - private final ScheduledExecutorService scheduler; - private final ConnectionManager connectionManager; - private final ConnectionRegistry connectionRegistry; - private final PluginManager pluginManager; - private final TransportPropertyManager transportPropertyManager; - private final SecureRandom random; - private final Clock clock; - private final Lock lock; - private final Map tasks; // Locking: lock - - Poller(@IoExecutor Executor ioExecutor, - @Scheduler ScheduledExecutorService scheduler, - ConnectionManager connectionManager, - ConnectionRegistry connectionRegistry, PluginManager pluginManager, - TransportPropertyManager transportPropertyManager, - SecureRandom random, Clock clock) { - this.ioExecutor = ioExecutor; - this.scheduler = scheduler; - this.connectionManager = connectionManager; - this.connectionRegistry = connectionRegistry; - this.pluginManager = pluginManager; - this.transportPropertyManager = transportPropertyManager; - this.random = random; - this.clock = clock; - lock = new ReentrantLock(); - tasks = new HashMap<>(); - } - - @Override - public void eventOccurred(Event e) { - if (e instanceof ContactAddedEvent) { - ContactAddedEvent c = (ContactAddedEvent) e; - // Connect to the newly activated contact - connectToContact(c.getContactId()); - } else if (e instanceof ConnectionClosedEvent) { - ConnectionClosedEvent c = (ConnectionClosedEvent) e; - // Reschedule polling, the polling interval may have decreased - reschedule(c.getTransportId()); - if (!c.isIncoming()) { - // Connect to the disconnected contact - connectToContact(c.getContactId(), c.getTransportId()); - } - } else if (e instanceof ConnectionOpenedEvent) { - ConnectionOpenedEvent c = (ConnectionOpenedEvent) e; - // Reschedule polling, the polling interval may have decreased - reschedule(c.getTransportId()); - } else if (e instanceof TransportEnabledEvent) { - TransportEnabledEvent t = (TransportEnabledEvent) e; - // Poll the newly enabled transport - pollNow(t.getTransportId()); - } else if (e instanceof TransportDisabledEvent) { - TransportDisabledEvent t = (TransportDisabledEvent) e; - // Cancel polling for the disabled transport - cancel(t.getTransportId()); - } - } - - private void connectToContact(ContactId c) { - for (SimplexPlugin s : pluginManager.getSimplexPlugins()) - if (s.shouldPoll()) connectToContact(c, s); - for (DuplexPlugin d : pluginManager.getDuplexPlugins()) - if (d.shouldPoll()) connectToContact(c, d); - } - - private void connectToContact(ContactId c, TransportId t) { - Plugin p = pluginManager.getPlugin(t); - if (p instanceof SimplexPlugin && p.shouldPoll()) - connectToContact(c, (SimplexPlugin) p); - else if (p instanceof DuplexPlugin && p.shouldPoll()) - connectToContact(c, (DuplexPlugin) p); - } - - private void connectToContact(ContactId c, SimplexPlugin p) { - ioExecutor.execute(() -> { - TransportId t = p.getId(); - if (connectionRegistry.isConnected(c, t)) return; - try { - TransportProperties props = - transportPropertyManager.getRemoteProperties(c, t); - TransportConnectionWriter w = p.createWriter(props); - if (w != null) - connectionManager.manageOutgoingConnection(c, t, w); - } catch (DbException e) { - logException(LOG, WARNING, e); - } - }); - } - - private void connectToContact(ContactId c, DuplexPlugin p) { - ioExecutor.execute(() -> { - TransportId t = p.getId(); - if (connectionRegistry.isConnected(c, t)) return; - try { - TransportProperties props = - transportPropertyManager.getRemoteProperties(c, t); - DuplexTransportConnection d = p.createConnection(props); - if (d != null) - connectionManager.manageOutgoingConnection(c, t, d); - } catch (DbException e) { - logException(LOG, WARNING, e); - } - }); - } - - private void reschedule(TransportId t) { - Plugin p = pluginManager.getPlugin(t); - if (p != null && p.shouldPoll()) - schedule(p, p.getPollingInterval(), false); - } - - private void pollNow(TransportId t) { - Plugin p = pluginManager.getPlugin(t); - // Randomise next polling interval - if (p != null && p.shouldPoll()) schedule(p, 0, true); - } - - private void schedule(Plugin p, int delay, boolean randomiseNext) { - // Replace any later scheduled task for this plugin - long due = clock.currentTimeMillis() + delay; - TransportId t = p.getId(); - lock.lock(); - try { - ScheduledPollTask scheduled = tasks.get(t); - if (scheduled == null || due < scheduled.task.due) { - // If a later task exists, cancel it. If it's already started - // it will abort safely when it finds it's been replaced - if (scheduled != null) scheduled.future.cancel(false); - PollTask task = new PollTask(p, due, randomiseNext); - Future future = scheduler.schedule( - () -> ioExecutor.execute(task), delay, MILLISECONDS); - tasks.put(t, new ScheduledPollTask(task, future)); - } - } finally { - lock.unlock(); - } - } - - private void cancel(TransportId t) { - lock.lock(); - try { - ScheduledPollTask scheduled = tasks.remove(t); - if (scheduled != null) scheduled.future.cancel(false); - } finally { - lock.unlock(); - } - } - - @IoExecutor - private void poll(Plugin p) { - TransportId t = p.getId(); - if (LOG.isLoggable(INFO)) LOG.info("Polling plugin " + t); - try { - Map remote = - transportPropertyManager.getRemoteProperties(t); - Collection connected = - connectionRegistry.getConnectedContacts(t); - remote = new HashMap<>(remote); - remote.keySet().removeAll(connected); - if (!remote.isEmpty()) p.poll(remote); - } catch (DbException e) { - logException(LOG, WARNING, e); - } - } - - private class ScheduledPollTask { - - private final PollTask task; - private final Future future; - - private ScheduledPollTask(PollTask task, Future future) { - this.task = task; - this.future = future; - } - } - - private class PollTask implements Runnable { - - private final Plugin plugin; - private final long due; - private final boolean randomiseNext; - - private PollTask(Plugin plugin, long due, boolean randomiseNext) { - this.plugin = plugin; - this.due = due; - this.randomiseNext = randomiseNext; - } - - @Override - @IoExecutor - public void run() { - lock.lock(); - try { - TransportId t = plugin.getId(); - ScheduledPollTask scheduled = tasks.get(t); - if (scheduled != null && scheduled.task != this) - return; // Replaced by another task - tasks.remove(t); - } finally { - lock.unlock(); - } - int delay = plugin.getPollingInterval(); - if (randomiseNext) delay = (int) (delay * random.nextDouble()); - schedule(plugin, delay, false); - poll(plugin); - } - } +/** + * Empty interface used for injecting the poller. + */ +interface Poller { } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/PollerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/PollerImpl.java new file mode 100644 index 000000000..d807f6044 --- /dev/null +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/PollerImpl.java @@ -0,0 +1,264 @@ +package org.briarproject.bramble.plugin; + +import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.bramble.api.contact.event.ContactAddedEvent; +import org.briarproject.bramble.api.db.DbException; +import org.briarproject.bramble.api.event.Event; +import org.briarproject.bramble.api.event.EventListener; +import org.briarproject.bramble.api.lifecycle.IoExecutor; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.plugin.ConnectionManager; +import org.briarproject.bramble.api.plugin.ConnectionRegistry; +import org.briarproject.bramble.api.plugin.Plugin; +import org.briarproject.bramble.api.plugin.PluginManager; +import org.briarproject.bramble.api.plugin.TransportConnectionWriter; +import org.briarproject.bramble.api.plugin.TransportId; +import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; +import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; +import org.briarproject.bramble.api.plugin.event.ConnectionClosedEvent; +import org.briarproject.bramble.api.plugin.event.ConnectionOpenedEvent; +import org.briarproject.bramble.api.plugin.event.TransportDisabledEvent; +import org.briarproject.bramble.api.plugin.event.TransportEnabledEvent; +import org.briarproject.bramble.api.plugin.simplex.SimplexPlugin; +import org.briarproject.bramble.api.properties.TransportProperties; +import org.briarproject.bramble.api.properties.TransportPropertyManager; +import org.briarproject.bramble.api.system.Clock; +import org.briarproject.bramble.api.system.Scheduler; + +import java.security.SecureRandom; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.Executor; +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; +import java.util.logging.Logger; + +import javax.annotation.concurrent.GuardedBy; +import javax.annotation.concurrent.ThreadSafe; +import javax.inject.Inject; + +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.logging.Level.INFO; +import static java.util.logging.Level.WARNING; +import static java.util.logging.Logger.getLogger; +import static org.briarproject.bramble.util.LogUtils.logException; + +@ThreadSafe +@NotNullByDefault +class PollerImpl implements Poller, EventListener { + + private static final Logger LOG = getLogger(PollerImpl.class.getName()); + + private final Executor ioExecutor; + private final ScheduledExecutorService scheduler; + private final ConnectionManager connectionManager; + private final ConnectionRegistry connectionRegistry; + private final PluginManager pluginManager; + private final TransportPropertyManager transportPropertyManager; + private final SecureRandom random; + private final Clock clock; + private final Lock lock; + @GuardedBy("lock") + private final Map tasks; + + @Inject + PollerImpl(@IoExecutor Executor ioExecutor, + @Scheduler ScheduledExecutorService scheduler, + ConnectionManager connectionManager, + ConnectionRegistry connectionRegistry, PluginManager pluginManager, + TransportPropertyManager transportPropertyManager, + SecureRandom random, Clock clock) { + this.ioExecutor = ioExecutor; + this.scheduler = scheduler; + this.connectionManager = connectionManager; + this.connectionRegistry = connectionRegistry; + this.pluginManager = pluginManager; + this.transportPropertyManager = transportPropertyManager; + this.random = random; + this.clock = clock; + lock = new ReentrantLock(); + tasks = new HashMap<>(); + } + + @Override + public void eventOccurred(Event e) { + if (e instanceof ContactAddedEvent) { + ContactAddedEvent c = (ContactAddedEvent) e; + // Connect to the newly added contact + connectToContact(c.getContactId()); + } else if (e instanceof ConnectionClosedEvent) { + ConnectionClosedEvent c = (ConnectionClosedEvent) e; + // Reschedule polling, the polling interval may have decreased + reschedule(c.getTransportId()); + if (!c.isIncoming()) { + // Connect to the disconnected contact + connectToContact(c.getContactId(), c.getTransportId()); + } + } else if (e instanceof ConnectionOpenedEvent) { + ConnectionOpenedEvent c = (ConnectionOpenedEvent) e; + // Reschedule polling, the polling interval may have decreased + reschedule(c.getTransportId()); + } else if (e instanceof TransportEnabledEvent) { + TransportEnabledEvent t = (TransportEnabledEvent) e; + // Poll the newly enabled transport + pollNow(t.getTransportId()); + } else if (e instanceof TransportDisabledEvent) { + TransportDisabledEvent t = (TransportDisabledEvent) e; + // Cancel polling for the disabled transport + cancel(t.getTransportId()); + } + } + + private void connectToContact(ContactId c) { + for (SimplexPlugin s : pluginManager.getSimplexPlugins()) + if (s.shouldPoll()) connectToContact(c, s); + for (DuplexPlugin d : pluginManager.getDuplexPlugins()) + if (d.shouldPoll()) connectToContact(c, d); + } + + private void connectToContact(ContactId c, TransportId t) { + Plugin p = pluginManager.getPlugin(t); + if (p instanceof SimplexPlugin && p.shouldPoll()) + connectToContact(c, (SimplexPlugin) p); + else if (p instanceof DuplexPlugin && p.shouldPoll()) + connectToContact(c, (DuplexPlugin) p); + } + + private void connectToContact(ContactId c, SimplexPlugin p) { + ioExecutor.execute(() -> { + TransportId t = p.getId(); + if (connectionRegistry.isConnected(c, t)) return; + try { + TransportProperties props = + transportPropertyManager.getRemoteProperties(c, t); + TransportConnectionWriter w = p.createWriter(props); + if (w != null) + connectionManager.manageOutgoingConnection(c, t, w); + } catch (DbException e) { + logException(LOG, WARNING, e); + } + }); + } + + private void connectToContact(ContactId c, DuplexPlugin p) { + ioExecutor.execute(() -> { + TransportId t = p.getId(); + if (connectionRegistry.isConnected(c, t)) return; + try { + TransportProperties props = + transportPropertyManager.getRemoteProperties(c, t); + DuplexTransportConnection d = p.createConnection(props); + if (d != null) + connectionManager.manageOutgoingConnection(c, t, d); + } catch (DbException e) { + logException(LOG, WARNING, e); + } + }); + } + + private void reschedule(TransportId t) { + Plugin p = pluginManager.getPlugin(t); + if (p != null && p.shouldPoll()) + schedule(p, p.getPollingInterval(), false); + } + + private void pollNow(TransportId t) { + Plugin p = pluginManager.getPlugin(t); + // Randomise next polling interval + if (p != null && p.shouldPoll()) schedule(p, 0, true); + } + + private void schedule(Plugin p, int delay, boolean randomiseNext) { + // Replace any later scheduled task for this plugin + long due = clock.currentTimeMillis() + delay; + TransportId t = p.getId(); + lock.lock(); + try { + ScheduledPollTask scheduled = tasks.get(t); + if (scheduled == null || due < scheduled.task.due) { + // If a later task exists, cancel it. If it's already started + // it will abort safely when it finds it's been replaced + if (scheduled != null) scheduled.future.cancel(false); + PollTask task = new PollTask(p, due, randomiseNext); + Future future = scheduler.schedule(() -> + ioExecutor.execute(task), delay, MILLISECONDS); + tasks.put(t, new ScheduledPollTask(task, future)); + } + } finally { + lock.unlock(); + } + } + + private void cancel(TransportId t) { + lock.lock(); + try { + ScheduledPollTask scheduled = tasks.remove(t); + if (scheduled != null) scheduled.future.cancel(false); + } finally { + lock.unlock(); + } + } + + @IoExecutor + private void poll(Plugin p) { + TransportId t = p.getId(); + if (LOG.isLoggable(INFO)) LOG.info("Polling plugin " + t); + try { + Map remote = + transportPropertyManager.getRemoteProperties(t); + Collection connected = + connectionRegistry.getConnectedContacts(t); + remote = new HashMap<>(remote); + remote.keySet().removeAll(connected); + if (!remote.isEmpty()) p.poll(remote); + } catch (DbException e) { + logException(LOG, WARNING, e); + } + } + + private class ScheduledPollTask { + + private final PollTask task; + private final Future future; + + private ScheduledPollTask(PollTask task, Future future) { + this.task = task; + this.future = future; + } + } + + private class PollTask implements Runnable { + + private final Plugin plugin; + private final long due; + private final boolean randomiseNext; + + private PollTask(Plugin plugin, long due, boolean randomiseNext) { + this.plugin = plugin; + this.due = due; + this.randomiseNext = randomiseNext; + } + + @Override + @IoExecutor + public void run() { + lock.lock(); + try { + TransportId t = plugin.getId(); + ScheduledPollTask scheduled = tasks.get(t); + if (scheduled != null && scheduled.task != this) + return; // Replaced by another task + tasks.remove(t); + } finally { + lock.unlock(); + } + int delay = plugin.getPollingInterval(); + if (randomiseNext) delay = (int) (delay * random.nextDouble()); + schedule(plugin, delay, false); + poll(plugin); + } + } +} diff --git a/bramble-core/src/test/java/org/briarproject/bramble/plugin/PluginManagerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/plugin/PluginManagerImplTest.java index 0cd09917d..55ad46757 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/plugin/PluginManagerImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/plugin/PluginManagerImplTest.java @@ -2,7 +2,6 @@ package org.briarproject.bramble.plugin; import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.plugin.ConnectionManager; -import org.briarproject.bramble.api.plugin.ConnectionRegistry; import org.briarproject.bramble.api.plugin.PluginConfig; import org.briarproject.bramble.api.plugin.PluginException; import org.briarproject.bramble.api.plugin.TransportId; @@ -14,18 +13,15 @@ import org.briarproject.bramble.api.plugin.simplex.SimplexPluginCallback; import org.briarproject.bramble.api.plugin.simplex.SimplexPluginFactory; import org.briarproject.bramble.api.properties.TransportPropertyManager; import org.briarproject.bramble.api.settings.SettingsManager; -import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.test.BrambleTestCase; import org.jmock.Expectations; import org.jmock.Mockery; import org.jmock.lib.concurrent.Synchroniser; import org.junit.Test; -import java.security.SecureRandom; import java.util.Arrays; import java.util.concurrent.Executor; import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; import static org.briarproject.bramble.test.TestUtils.getTransportId; @@ -37,16 +33,10 @@ public class PluginManagerImplTest extends BrambleTestCase { setThreadingPolicy(new Synchroniser()); }}; Executor ioExecutor = Executors.newSingleThreadExecutor(); - ScheduledExecutorService scheduler = - context.mock(ScheduledExecutorService.class); - SecureRandom random = new SecureRandom(); - Clock clock = context.mock(Clock.class); EventBus eventBus = context.mock(EventBus.class); PluginConfig pluginConfig = context.mock(PluginConfig.class); ConnectionManager connectionManager = context.mock(ConnectionManager.class); - ConnectionRegistry connectionRegistry = - context.mock(ConnectionRegistry.class); SettingsManager settingsManager = context.mock(SettingsManager.class); TransportPropertyManager transportPropertyManager = @@ -122,9 +112,9 @@ public class PluginManagerImplTest extends BrambleTestCase { oneOf(duplexPlugin).stop(); }}); - PluginManagerImpl p = new PluginManagerImpl(ioExecutor, scheduler, - eventBus, pluginConfig, connectionManager, connectionRegistry, - settingsManager, transportPropertyManager, random, clock); + PluginManagerImpl p = new PluginManagerImpl(ioExecutor, eventBus, + pluginConfig, connectionManager, settingsManager, + transportPropertyManager); // Two plugins should be started and stopped p.startService(); diff --git a/bramble-core/src/test/java/org/briarproject/bramble/plugin/PollerTest.java b/bramble-core/src/test/java/org/briarproject/bramble/plugin/PollerImplTest.java similarity index 88% rename from bramble-core/src/test/java/org/briarproject/bramble/plugin/PollerTest.java rename to bramble-core/src/test/java/org/briarproject/bramble/plugin/PollerImplTest.java index 2fca78405..9b038ef0a 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/plugin/PollerTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/plugin/PollerImplTest.java @@ -23,6 +23,7 @@ import org.briarproject.bramble.test.ImmediateExecutor; import org.briarproject.bramble.test.RunAction; import org.jmock.Expectations; import org.jmock.lib.legacy.ClassImposteriser; +import org.junit.Before; import org.junit.Test; import java.security.SecureRandom; @@ -39,7 +40,7 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS; import static org.briarproject.bramble.test.TestUtils.getContactId; import static org.briarproject.bramble.test.TestUtils.getTransportId; -public class PollerTest extends BrambleMockTestCase { +public class PollerImplTest extends BrambleMockTestCase { private final ScheduledExecutorService scheduler = context.mock(ScheduledExecutorService.class); @@ -62,11 +63,20 @@ public class PollerTest extends BrambleMockTestCase { private final int pollingInterval = 60 * 1000; private final long now = System.currentTimeMillis(); - public PollerTest() { + private PollerImpl poller; + + public PollerImplTest() { context.setImposteriser(ClassImposteriser.INSTANCE); random = context.mock(SecureRandom.class); } + @Before + public void setUp() { + poller = new PollerImpl(ioExecutor, scheduler, connectionManager, + connectionRegistry, pluginManager, transportPropertyManager, + random, clock); + } + @Test public void testConnectOnContactAdded() throws Exception { // Two simplex plugins: one supports polling, the other doesn't @@ -140,11 +150,7 @@ public class PollerTest extends BrambleMockTestCase { will(returnValue(false)); }}); - Poller p = new Poller(ioExecutor, scheduler, connectionManager, - connectionRegistry, pluginManager, transportPropertyManager, - random, clock); - - p.eventOccurred(new ContactAddedEvent(contactId)); + poller.eventOccurred(new ContactAddedEvent(contactId)); } @Test @@ -194,11 +200,7 @@ public class PollerTest extends BrambleMockTestCase { transportId, duplexConnection); }}); - Poller p = new Poller(ioExecutor, scheduler, connectionManager, - connectionRegistry, pluginManager, transportPropertyManager, - random, clock); - - p.eventOccurred(new ConnectionClosedEvent(contactId, transportId, + poller.eventOccurred(new ConnectionClosedEvent(contactId, transportId, false)); } @@ -225,11 +227,7 @@ public class PollerTest extends BrambleMockTestCase { will(returnValue(future)); }}); - Poller p = new Poller(ioExecutor, scheduler, connectionManager, - connectionRegistry, pluginManager, transportPropertyManager, - random, clock); - - p.eventOccurred(new ConnectionOpenedEvent(contactId, transportId, + poller.eventOccurred(new ConnectionOpenedEvent(contactId, transportId, false)); } @@ -269,13 +267,9 @@ public class PollerTest extends BrambleMockTestCase { will(returnValue(now + 1)); }}); - Poller p = new Poller(ioExecutor, scheduler, connectionManager, - connectionRegistry, pluginManager, transportPropertyManager, - random, clock); - - p.eventOccurred(new ConnectionOpenedEvent(contactId, transportId, + poller.eventOccurred(new ConnectionOpenedEvent(contactId, transportId, false)); - p.eventOccurred(new ConnectionOpenedEvent(contactId, transportId, + poller.eventOccurred(new ConnectionOpenedEvent(contactId, transportId, false)); } @@ -318,13 +312,9 @@ public class PollerTest extends BrambleMockTestCase { with((long) pollingInterval - 2), with(MILLISECONDS)); }}); - Poller p = new Poller(ioExecutor, scheduler, connectionManager, - connectionRegistry, pluginManager, transportPropertyManager, - random, clock); - - p.eventOccurred(new ConnectionOpenedEvent(contactId, transportId, + poller.eventOccurred(new ConnectionOpenedEvent(contactId, transportId, false)); - p.eventOccurred(new ConnectionOpenedEvent(contactId, transportId, + poller.eventOccurred(new ConnectionOpenedEvent(contactId, transportId, false)); } @@ -367,11 +357,7 @@ public class PollerTest extends BrambleMockTestCase { oneOf(plugin).poll(singletonMap(contactId, properties)); }}); - Poller p = new Poller(ioExecutor, scheduler, connectionManager, - connectionRegistry, pluginManager, transportPropertyManager, - random, clock); - - p.eventOccurred(new TransportEnabledEvent(transportId)); + poller.eventOccurred(new TransportEnabledEvent(transportId)); } @Test @@ -412,11 +398,7 @@ public class PollerTest extends BrambleMockTestCase { // All contacts are connected, so don't poll the plugin }}); - Poller p = new Poller(ioExecutor, scheduler, connectionManager, - connectionRegistry, pluginManager, transportPropertyManager, - random, clock); - - p.eventOccurred(new TransportEnabledEvent(transportId)); + poller.eventOccurred(new TransportEnabledEvent(transportId)); } @Test @@ -442,11 +424,7 @@ public class PollerTest extends BrambleMockTestCase { oneOf(future).cancel(false); }}); - Poller p = new Poller(ioExecutor, scheduler, connectionManager, - connectionRegistry, pluginManager, transportPropertyManager, - random, clock); - - p.eventOccurred(new TransportEnabledEvent(transportId)); - p.eventOccurred(new TransportDisabledEvent(transportId)); + poller.eventOccurred(new TransportEnabledEvent(transportId)); + poller.eventOccurred(new TransportDisabledEvent(transportId)); } } From 668433dd62d0f2a6eed85e42016bef15543b2384 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Fri, 17 May 2019 13:58:18 +0100 Subject: [PATCH 2/4] Pass a connection handler to plugins when polling. --- .../bluetooth/AndroidBluetoothPlugin.java | 7 +- .../AndroidBluetoothPluginFactory.java | 4 +- .../plugin/tcp/AndroidLanTcpPlugin.java | 11 +-- .../tcp/AndroidLanTcpPluginFactory.java | 4 +- .../bramble/plugin/tor/AndroidTorPlugin.java | 4 +- .../plugin/tor/AndroidTorPluginFactory.java | 4 +- .../bramble/api/plugin/ConnectionHandler.java | 17 +++++ .../bramble/api/plugin/Plugin.java | 11 +-- .../bramble/api/plugin/PluginCallback.java | 2 +- .../plugin/duplex/DuplexPluginCallback.java | 17 ----- .../plugin/duplex/DuplexPluginFactory.java | 3 +- .../plugin/simplex/SimplexPluginCallback.java | 19 ----- .../plugin/simplex/SimplexPluginFactory.java | 3 +- .../bramble/plugin/PluginManagerImpl.java | 55 ++++---------- .../bramble/plugin/PollerImpl.java | 45 ++++++++++- .../plugin/bluetooth/BluetoothPlugin.java | 56 +++++++------- .../bramble/plugin/file/FilePlugin.java | 9 ++- .../bramble/plugin/tcp/LanTcpPlugin.java | 31 ++++---- .../plugin/tcp/LanTcpPluginFactory.java | 4 +- .../bramble/plugin/tcp/TcpPlugin.java | 36 ++++----- .../bramble/plugin/tcp/WanTcpPlugin.java | 11 +-- .../plugin/tcp/WanTcpPluginFactory.java | 4 +- .../bramble/plugin/tor/TorPlugin.java | 28 +++---- .../bramble/plugin/PluginManagerImplTest.java | 13 ++-- .../bramble/plugin/PollerImplTest.java | 6 +- .../bramble/plugin/tcp/LanTcpPluginTest.java | 59 +++++++------- .../bramble/test/CollectionMatcher.java | 39 ++++++++++ .../bramble/test/PairMatcher.java | 38 ++++++++++ .../bramble/test/TestPluginConfigModule.java | 4 +- .../plugin/bluetooth/JavaBluetoothPlugin.java | 7 +- .../bluetooth/JavaBluetoothPluginFactory.java | 4 +- .../bramble/plugin/modem/ModemPlugin.java | 27 ++++--- .../plugin/modem/ModemPluginFactory.java | 4 +- .../bramble/plugin/tor/JavaTorPlugin.java | 4 +- .../bramble/plugin/tor/UnixTorPlugin.java | 6 +- .../plugin/tor/UnixTorPluginFactory.java | 4 +- .../bramble/plugin/modem/ModemPluginTest.java | 76 +++++++------------ .../bramble/plugin/tor/BridgeTest.java | 2 +- ...nCallBack.java => TestPluginCallback.java} | 33 ++++---- 39 files changed, 391 insertions(+), 320 deletions(-) create mode 100644 bramble-api/src/main/java/org/briarproject/bramble/api/plugin/ConnectionHandler.java delete mode 100644 bramble-api/src/main/java/org/briarproject/bramble/api/plugin/duplex/DuplexPluginCallback.java delete mode 100644 bramble-api/src/main/java/org/briarproject/bramble/api/plugin/simplex/SimplexPluginCallback.java create mode 100644 bramble-core/src/test/java/org/briarproject/bramble/test/CollectionMatcher.java create mode 100644 bramble-core/src/test/java/org/briarproject/bramble/test/PairMatcher.java rename bramble-java/src/test/java/org/briarproject/bramble/plugin/tor/{TorPluginCallBack.java => TestPluginCallback.java} (63%) diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/bluetooth/AndroidBluetoothPlugin.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/bluetooth/AndroidBluetoothPlugin.java index 95e082001..839dee2c6 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/bluetooth/AndroidBluetoothPlugin.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/bluetooth/AndroidBluetoothPlugin.java @@ -12,8 +12,8 @@ import android.content.IntentFilter; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; import org.briarproject.bramble.api.plugin.Backoff; +import org.briarproject.bramble.api.plugin.PluginCallback; import org.briarproject.bramble.api.plugin.PluginException; -import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback; import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; import org.briarproject.bramble.api.system.AndroidExecutor; import org.briarproject.bramble.api.system.Clock; @@ -51,6 +51,7 @@ import static android.bluetooth.BluetoothDevice.EXTRA_DEVICE; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; +import static java.util.logging.Logger.getLogger; import static org.briarproject.bramble.util.PrivacyUtils.scrubMacAddress; @MethodsNotNullByDefault @@ -58,7 +59,7 @@ import static org.briarproject.bramble.util.PrivacyUtils.scrubMacAddress; class AndroidBluetoothPlugin extends BluetoothPlugin { private static final Logger LOG = - Logger.getLogger(AndroidBluetoothPlugin.class.getName()); + getLogger(AndroidBluetoothPlugin.class.getName()); private static final int MAX_DISCOVERY_MS = 10_000; @@ -75,7 +76,7 @@ class AndroidBluetoothPlugin extends BluetoothPlugin { AndroidBluetoothPlugin(BluetoothConnectionLimiter connectionLimiter, Executor ioExecutor, AndroidExecutor androidExecutor, Context appContext, SecureRandom secureRandom, Clock clock, - Backoff backoff, DuplexPluginCallback callback, int maxLatency) { + Backoff backoff, PluginCallback callback, int maxLatency) { super(connectionLimiter, ioExecutor, secureRandom, backoff, callback, maxLatency); this.androidExecutor = androidExecutor; diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/bluetooth/AndroidBluetoothPluginFactory.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/bluetooth/AndroidBluetoothPluginFactory.java index 53a127caa..6dd5c094f 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/bluetooth/AndroidBluetoothPluginFactory.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/bluetooth/AndroidBluetoothPluginFactory.java @@ -6,9 +6,9 @@ import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.plugin.Backoff; import org.briarproject.bramble.api.plugin.BackoffFactory; +import org.briarproject.bramble.api.plugin.PluginCallback; import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; -import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback; import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory; import org.briarproject.bramble.api.system.AndroidExecutor; import org.briarproject.bramble.api.system.Clock; @@ -61,7 +61,7 @@ public class AndroidBluetoothPluginFactory implements DuplexPluginFactory { } @Override - public DuplexPlugin createPlugin(DuplexPluginCallback callback) { + public DuplexPlugin createPlugin(PluginCallback callback) { BluetoothConnectionLimiter connectionLimiter = new BluetoothConnectionLimiterImpl(); Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL, diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tcp/AndroidLanTcpPlugin.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tcp/AndroidLanTcpPlugin.java index b3c3a98ae..ef6cb8efa 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tcp/AndroidLanTcpPlugin.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tcp/AndroidLanTcpPlugin.java @@ -13,7 +13,7 @@ import org.briarproject.bramble.api.event.EventListener; import org.briarproject.bramble.api.network.event.NetworkStatusEvent; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.plugin.Backoff; -import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback; +import org.briarproject.bramble.api.plugin.PluginCallback; import java.io.IOException; import java.net.InetAddress; @@ -32,17 +32,18 @@ import static android.net.ConnectivityManager.TYPE_WIFI; import static android.os.Build.VERSION.SDK_INT; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; +import static java.util.logging.Logger.getLogger; @NotNullByDefault class AndroidLanTcpPlugin extends LanTcpPlugin implements EventListener { + private static final Logger LOG = + getLogger(AndroidLanTcpPlugin.class.getName()); + private static final byte[] WIFI_AP_ADDRESS_BYTES = {(byte) 192, (byte) 168, 43, 1}; private static final InetAddress WIFI_AP_ADDRESS; - private static final Logger LOG = - Logger.getLogger(AndroidLanTcpPlugin.class.getName()); - static { try { WIFI_AP_ADDRESS = InetAddress.getByAddress(WIFI_AP_ADDRESS_BYTES); @@ -60,7 +61,7 @@ class AndroidLanTcpPlugin extends LanTcpPlugin implements EventListener { private volatile SocketFactory socketFactory; AndroidLanTcpPlugin(Executor ioExecutor, Context appContext, - Backoff backoff, DuplexPluginCallback callback, int maxLatency, + Backoff backoff, PluginCallback callback, int maxLatency, int maxIdleTime) { super(ioExecutor, backoff, callback, maxLatency, maxIdleTime); // Don't execute more than one connection status check at a time diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tcp/AndroidLanTcpPluginFactory.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tcp/AndroidLanTcpPluginFactory.java index f8db864a0..9562af560 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tcp/AndroidLanTcpPluginFactory.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tcp/AndroidLanTcpPluginFactory.java @@ -6,9 +6,9 @@ import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.plugin.Backoff; import org.briarproject.bramble.api.plugin.BackoffFactory; +import org.briarproject.bramble.api.plugin.PluginCallback; import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; -import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback; import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory; import java.util.concurrent.Executor; @@ -51,7 +51,7 @@ public class AndroidLanTcpPluginFactory implements DuplexPluginFactory { } @Override - public DuplexPlugin createPlugin(DuplexPluginCallback callback) { + public DuplexPlugin createPlugin(PluginCallback callback) { Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL, MAX_POLLING_INTERVAL, BACKOFF_BASE); AndroidLanTcpPlugin plugin = new AndroidLanTcpPlugin(ioExecutor, diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/AndroidTorPlugin.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/AndroidTorPlugin.java index 14114cdfc..ae68db6e1 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/AndroidTorPlugin.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/AndroidTorPlugin.java @@ -11,7 +11,7 @@ import org.briarproject.bramble.api.network.NetworkManager; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; import org.briarproject.bramble.api.plugin.Backoff; -import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback; +import org.briarproject.bramble.api.plugin.PluginCallback; import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.LocationUtils; import org.briarproject.bramble.api.system.ResourceProvider; @@ -41,7 +41,7 @@ class AndroidTorPlugin extends TorPlugin { Clock clock, ResourceProvider resourceProvider, CircumventionProvider circumventionProvider, BatteryManager batteryManager, Backoff backoff, - DuplexPluginCallback callback, String architecture, int maxLatency, + PluginCallback callback, String architecture, int maxLatency, int maxIdleTime) { super(ioExecutor, networkManager, locationUtils, torSocketFactory, clock, resourceProvider, circumventionProvider, batteryManager, diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/AndroidTorPluginFactory.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/AndroidTorPluginFactory.java index df3de1c77..560072343 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/AndroidTorPluginFactory.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/AndroidTorPluginFactory.java @@ -9,10 +9,10 @@ import org.briarproject.bramble.api.network.NetworkManager; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.plugin.Backoff; import org.briarproject.bramble.api.plugin.BackoffFactory; +import org.briarproject.bramble.api.plugin.PluginCallback; import org.briarproject.bramble.api.plugin.TorConstants; import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; -import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback; import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory; import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.LocationUtils; @@ -84,7 +84,7 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory { } @Override - public DuplexPlugin createPlugin(DuplexPluginCallback callback) { + public DuplexPlugin createPlugin(PluginCallback callback) { // Check that we have a Tor binary for this architecture String architecture = null; diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/ConnectionHandler.java b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/ConnectionHandler.java new file mode 100644 index 000000000..7255d03a1 --- /dev/null +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/ConnectionHandler.java @@ -0,0 +1,17 @@ +package org.briarproject.bramble.api.plugin; + +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; + +/** + * An interface for handling connections created by transport plugins. + */ +@NotNullByDefault +public interface ConnectionHandler { + + void handleConnection(DuplexTransportConnection c); + + void handleReader(TransportConnectionReader r); + + void handleWriter(TransportConnectionWriter w); +} diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/Plugin.java b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/Plugin.java index 9e3fdd466..84872dfed 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/Plugin.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/Plugin.java @@ -1,10 +1,10 @@ package org.briarproject.bramble.api.plugin; -import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.bramble.api.Pair; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.properties.TransportProperties; -import java.util.Map; +import java.util.Collection; @NotNullByDefault public interface Plugin { @@ -51,8 +51,9 @@ public interface Plugin { int getPollingInterval(); /** - * Attempts to establish connections to the given contacts, passing any - * created connections to the callback. + * Attempts to create connections using the given transport properties, + * passing any created connections to the corresponding handlers. */ - void poll(Map contacts); + void poll(Collection> + properties); } diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/PluginCallback.java b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/PluginCallback.java index f2d5e8f79..b9cbd450b 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/PluginCallback.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/PluginCallback.java @@ -9,7 +9,7 @@ import org.briarproject.bramble.api.settings.Settings; * the application. */ @NotNullByDefault -public interface PluginCallback { +public interface PluginCallback extends ConnectionHandler { /** * Returns the plugin's settings diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/duplex/DuplexPluginCallback.java b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/duplex/DuplexPluginCallback.java deleted file mode 100644 index 8a97cf7fb..000000000 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/duplex/DuplexPluginCallback.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.briarproject.bramble.api.plugin.duplex; - -import org.briarproject.bramble.api.contact.ContactId; -import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.plugin.PluginCallback; - -/** - * An interface through which a duplex plugin interacts with the rest of the - * application. - */ -@NotNullByDefault -public interface DuplexPluginCallback extends PluginCallback { - - void incomingConnectionCreated(DuplexTransportConnection d); - - void outgoingConnectionCreated(ContactId c, DuplexTransportConnection d); -} diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/duplex/DuplexPluginFactory.java b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/duplex/DuplexPluginFactory.java index 9a3aa28b2..ef6560d54 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/duplex/DuplexPluginFactory.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/duplex/DuplexPluginFactory.java @@ -1,6 +1,7 @@ package org.briarproject.bramble.api.plugin.duplex; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.plugin.PluginCallback; import org.briarproject.bramble.api.plugin.TransportId; import javax.annotation.Nullable; @@ -25,5 +26,5 @@ public interface DuplexPluginFactory { * Creates and returns a plugin, or null if no plugin can be created. */ @Nullable - DuplexPlugin createPlugin(DuplexPluginCallback callback); + DuplexPlugin createPlugin(PluginCallback callback); } diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/simplex/SimplexPluginCallback.java b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/simplex/SimplexPluginCallback.java deleted file mode 100644 index 1f07ec25a..000000000 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/simplex/SimplexPluginCallback.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.briarproject.bramble.api.plugin.simplex; - -import org.briarproject.bramble.api.contact.ContactId; -import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.plugin.PluginCallback; -import org.briarproject.bramble.api.plugin.TransportConnectionReader; -import org.briarproject.bramble.api.plugin.TransportConnectionWriter; - -/** - * An interface through which a simplex plugin interacts with the rest of the - * application. - */ -@NotNullByDefault -public interface SimplexPluginCallback extends PluginCallback { - - void readerCreated(TransportConnectionReader r); - - void writerCreated(ContactId c, TransportConnectionWriter w); -} diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/simplex/SimplexPluginFactory.java b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/simplex/SimplexPluginFactory.java index a2c12b5f7..4a96ee3f1 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/simplex/SimplexPluginFactory.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/simplex/SimplexPluginFactory.java @@ -1,6 +1,7 @@ package org.briarproject.bramble.api.plugin.simplex; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.plugin.PluginCallback; import org.briarproject.bramble.api.plugin.TransportId; import javax.annotation.Nullable; @@ -25,5 +26,5 @@ public interface SimplexPluginFactory { * Creates and returns a plugin, or null if no plugin can be created. */ @Nullable - SimplexPlugin createPlugin(SimplexPluginCallback callback); + SimplexPlugin createPlugin(PluginCallback callback); } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginManagerImpl.java index 7df91a487..682b7fde2 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginManagerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/PluginManagerImpl.java @@ -1,6 +1,5 @@ package org.briarproject.bramble.plugin; -import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.lifecycle.IoExecutor; @@ -17,13 +16,11 @@ import org.briarproject.bramble.api.plugin.TransportConnectionReader; import org.briarproject.bramble.api.plugin.TransportConnectionWriter; import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; -import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback; import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory; import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; import org.briarproject.bramble.api.plugin.event.TransportDisabledEvent; import org.briarproject.bramble.api.plugin.event.TransportEnabledEvent; import org.briarproject.bramble.api.plugin.simplex.SimplexPlugin; -import org.briarproject.bramble.api.plugin.simplex.SimplexPluginCallback; import org.briarproject.bramble.api.plugin.simplex.SimplexPluginFactory; import org.briarproject.bramble.api.properties.TransportProperties; import org.briarproject.bramble.api.properties.TransportPropertyManager; @@ -95,7 +92,7 @@ class PluginManagerImpl implements PluginManager, Service { LOG.info("Starting simplex plugins"); for (SimplexPluginFactory f : pluginConfig.getSimplexFactories()) { TransportId t = f.getId(); - SimplexPlugin s = f.createPlugin(new SimplexCallback(t)); + SimplexPlugin s = f.createPlugin(new Callback(t)); if (s == null) { if (LOG.isLoggable(WARNING)) LOG.warning("Could not create plugin for " + t); @@ -111,7 +108,7 @@ class PluginManagerImpl implements PluginManager, Service { LOG.info("Starting duplex plugins"); for (DuplexPluginFactory f : pluginConfig.getDuplexFactories()) { TransportId t = f.getId(); - DuplexPlugin d = f.createPlugin(new DuplexCallback(t)); + DuplexPlugin d = f.createPlugin(new Callback(t)); if (d == null) { if (LOG.isLoggable(WARNING)) LOG.warning("Could not create plugin for " + t); @@ -242,12 +239,11 @@ class PluginManagerImpl implements PluginManager, Service { } } - @NotNullByDefault - private abstract class PluginCallbackImpl implements PluginCallback { + private class Callback implements PluginCallback { - protected final TransportId id; + private final TransportId id; - PluginCallbackImpl(TransportId id) { + private Callback(TransportId id) { this.id = id; } @@ -298,44 +294,21 @@ class PluginManagerImpl implements PluginManager, Service { public void transportDisabled() { eventBus.broadcast(new TransportDisabledEvent(id)); } - } - - @NotNullByDefault - private class SimplexCallback extends PluginCallbackImpl - implements SimplexPluginCallback { - - private SimplexCallback(TransportId id) { - super(id); - } @Override - public void readerCreated(TransportConnectionReader r) { - connectionManager.manageIncomingConnection(id, r); - } - - @Override - public void writerCreated(ContactId c, TransportConnectionWriter w) { - connectionManager.manageOutgoingConnection(c, id, w); - } - } - - @NotNullByDefault - private class DuplexCallback extends PluginCallbackImpl - implements DuplexPluginCallback { - - private DuplexCallback(TransportId id) { - super(id); - } - - @Override - public void incomingConnectionCreated(DuplexTransportConnection d) { + public void handleConnection(DuplexTransportConnection d) { connectionManager.manageIncomingConnection(id, d); } @Override - public void outgoingConnectionCreated(ContactId c, - DuplexTransportConnection d) { - connectionManager.manageOutgoingConnection(c, id, d); + public void handleReader(TransportConnectionReader r) { + connectionManager.manageIncomingConnection(id, r); + } + + @Override + public void handleWriter(TransportConnectionWriter w) { + // TODO: Support simplex plugins that write to incoming connections + throw new UnsupportedOperationException(); } } } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/PollerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/PollerImpl.java index d807f6044..256bf215e 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/PollerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/PollerImpl.java @@ -1,5 +1,6 @@ package org.briarproject.bramble.plugin; +import org.briarproject.bramble.api.Pair; import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.event.ContactAddedEvent; import org.briarproject.bramble.api.db.DbException; @@ -7,10 +8,12 @@ import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.event.EventListener; import org.briarproject.bramble.api.lifecycle.IoExecutor; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.plugin.ConnectionHandler; import org.briarproject.bramble.api.plugin.ConnectionManager; import org.briarproject.bramble.api.plugin.ConnectionRegistry; import org.briarproject.bramble.api.plugin.Plugin; import org.briarproject.bramble.api.plugin.PluginManager; +import org.briarproject.bramble.api.plugin.TransportConnectionReader; import org.briarproject.bramble.api.plugin.TransportConnectionWriter; import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; @@ -26,9 +29,11 @@ import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.Scheduler; import java.security.SecureRandom; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Map; +import java.util.Map.Entry; import java.util.concurrent.Executor; import java.util.concurrent.Future; import java.util.concurrent.ScheduledExecutorService; @@ -211,9 +216,14 @@ class PollerImpl implements Poller, EventListener { transportPropertyManager.getRemoteProperties(t); Collection connected = connectionRegistry.getConnectedContacts(t); - remote = new HashMap<>(remote); - remote.keySet().removeAll(connected); - if (!remote.isEmpty()) p.poll(remote); + Collection> + properties = new ArrayList<>(); + for (Entry e : remote.entrySet()) { + ContactId c = e.getKey(); + if (!connected.contains(c)) + properties.add(new Pair<>(e.getValue(), new Handler(c, t))); + } + if (!properties.isEmpty()) p.poll(properties); } catch (DbException e) { logException(LOG, WARNING, e); } @@ -261,4 +271,33 @@ class PollerImpl implements Poller, EventListener { poll(plugin); } } + + private class Handler implements ConnectionHandler { + + private final ContactId contactId; + private final TransportId transportId; + + private Handler(ContactId contactId, TransportId transportId) { + this.contactId = contactId; + this.transportId = transportId; + } + + @Override + public void handleConnection(DuplexTransportConnection c) { + connectionManager.manageOutgoingConnection(contactId, + transportId, c); + } + + @Override + public void handleReader(TransportConnectionReader r) { + // TODO: Support simplex plugins that read from outgoing connections + throw new UnsupportedOperationException(); + } + + @Override + public void handleWriter(TransportConnectionWriter w) { + connectionManager.manageOutgoingConnection(contactId, + transportId, w); + } + } } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java index 0fdc03cee..4cb3fecdc 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java @@ -1,7 +1,7 @@ package org.briarproject.bramble.plugin.bluetooth; import org.briarproject.bramble.api.FormatException; -import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.bramble.api.Pair; import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.event.EventListener; @@ -12,10 +12,11 @@ import org.briarproject.bramble.api.keyagreement.event.KeyAgreementStoppedListen import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; import org.briarproject.bramble.api.plugin.Backoff; +import org.briarproject.bramble.api.plugin.ConnectionHandler; +import org.briarproject.bramble.api.plugin.PluginCallback; import org.briarproject.bramble.api.plugin.PluginException; import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; -import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback; import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; import org.briarproject.bramble.api.plugin.event.BluetoothEnabledEvent; import org.briarproject.bramble.api.plugin.event.DisableBluetoothEvent; @@ -26,8 +27,7 @@ import org.briarproject.bramble.api.settings.event.SettingsUpdatedEvent; import java.io.IOException; import java.security.SecureRandom; -import java.util.Map; -import java.util.Map.Entry; +import java.util.Collection; import java.util.UUID; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicBoolean; @@ -37,6 +37,7 @@ import javax.annotation.Nullable; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; +import static java.util.logging.Logger.getLogger; import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.TRANSPORT_ID_BLUETOOTH; import static org.briarproject.bramble.api.plugin.BluetoothConstants.ID; import static org.briarproject.bramble.api.plugin.BluetoothConstants.PREF_BT_ENABLE; @@ -54,14 +55,14 @@ import static org.briarproject.bramble.util.StringUtils.macToString; abstract class BluetoothPlugin implements DuplexPlugin, EventListener { private static final Logger LOG = - Logger.getLogger(BluetoothPlugin.class.getName()); + getLogger(BluetoothPlugin.class.getName()); final BluetoothConnectionLimiter connectionLimiter; private final Executor ioExecutor; private final SecureRandom secureRandom; private final Backoff backoff; - private final DuplexPluginCallback callback; + private final PluginCallback callback; private final int maxLatency; private final AtomicBoolean used = new AtomicBoolean(false); @@ -103,7 +104,7 @@ abstract class BluetoothPlugin implements DuplexPlugin, EventListener { BluetoothPlugin(BluetoothConnectionLimiter connectionLimiter, Executor ioExecutor, SecureRandom secureRandom, - Backoff backoff, DuplexPluginCallback callback, int maxLatency) { + Backoff backoff, PluginCallback callback, int maxLatency) { this.connectionLimiter = connectionLimiter; this.ioExecutor = ioExecutor; this.secureRandom = secureRandom; @@ -226,7 +227,7 @@ abstract class BluetoothPlugin implements DuplexPlugin, EventListener { } backoff.reset(); if (connectionLimiter.contactConnectionOpened(conn)) - callback.incomingConnectionCreated(conn); + callback.handleConnection(conn); if (!running) return; } } @@ -255,29 +256,32 @@ abstract class BluetoothPlugin implements DuplexPlugin, EventListener { } @Override - public void poll(Map contacts) { + public void poll(Collection> + properties) { if (!isRunning() || !shouldAllowContactConnections()) return; backoff.increment(); - // Try to connect to known devices in parallel - for (Entry e : contacts.entrySet()) { - String address = e.getValue().get(PROP_ADDRESS); - if (isNullOrEmpty(address)) continue; - String uuid = e.getValue().get(PROP_UUID); - if (isNullOrEmpty(uuid)) continue; - ContactId c = e.getKey(); - ioExecutor.execute(() -> { - if (!isRunning() || !shouldAllowContactConnections()) return; - if (!connectionLimiter.canOpenContactConnection()) return; - DuplexTransportConnection conn = connect(address, uuid); - if (conn != null) { - backoff.reset(); - if (connectionLimiter.contactConnectionOpened(conn)) - callback.outgoingConnectionCreated(c, conn); - } - }); + for (Pair p : properties) { + connect(p.getFirst(), p.getSecond()); } } + private void connect(TransportProperties p, ConnectionHandler h) { + String address = p.get(PROP_ADDRESS); + if (isNullOrEmpty(address)) return; + String uuid = p.get(PROP_UUID); + if (isNullOrEmpty(uuid)) return; + ioExecutor.execute(() -> { + if (!isRunning() || !shouldAllowContactConnections()) return; + if (!connectionLimiter.canOpenContactConnection()) return; + DuplexTransportConnection d = createConnection(p); + if (d != null) { + backoff.reset(); + if (connectionLimiter.contactConnectionOpened(d)) + h.handleConnection(d); + } + }); + } + @Nullable private DuplexTransportConnection connect(String address, String uuid) { // Validate the address diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/FilePlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/FilePlugin.java index 57e353866..0d4f56618 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/FilePlugin.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/file/FilePlugin.java @@ -1,10 +1,10 @@ package org.briarproject.bramble.plugin.file; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.plugin.PluginCallback; import org.briarproject.bramble.api.plugin.TransportConnectionReader; import org.briarproject.bramble.api.plugin.TransportConnectionWriter; import org.briarproject.bramble.api.plugin.simplex.SimplexPlugin; -import org.briarproject.bramble.api.plugin.simplex.SimplexPluginCallback; import org.briarproject.bramble.api.properties.TransportProperties; import java.io.File; @@ -14,6 +14,7 @@ import java.io.IOException; import java.util.logging.Logger; import static java.util.logging.Level.WARNING; +import static java.util.logging.Logger.getLogger; import static org.briarproject.bramble.api.plugin.FileConstants.PROP_PATH; import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty; @@ -22,9 +23,9 @@ import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty; abstract class FilePlugin implements SimplexPlugin { private static final Logger LOG = - Logger.getLogger(FilePlugin.class.getName()); + getLogger(FilePlugin.class.getName()); - protected final SimplexPluginCallback callback; + protected final PluginCallback callback; protected final int maxLatency; protected abstract void writerFinished(File f, boolean exception); @@ -32,7 +33,7 @@ abstract class FilePlugin implements SimplexPlugin { protected abstract void readerFinished(File f, boolean exception, boolean recognised); - FilePlugin(SimplexPluginCallback callback, int maxLatency) { + FilePlugin(PluginCallback callback, int maxLatency) { this.callback = callback; this.maxLatency = maxLatency; } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPlugin.java index 1cc581cc5..5d1575eaf 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPlugin.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPlugin.java @@ -6,13 +6,12 @@ import org.briarproject.bramble.api.keyagreement.KeyAgreementConnection; import org.briarproject.bramble.api.keyagreement.KeyAgreementListener; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.plugin.Backoff; +import org.briarproject.bramble.api.plugin.PluginCallback; import org.briarproject.bramble.api.plugin.TransportId; -import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback; import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; import org.briarproject.bramble.api.properties.TransportProperties; import org.briarproject.bramble.api.settings.Settings; import org.briarproject.bramble.util.IoUtils; -import org.briarproject.bramble.util.StringUtils; import java.io.IOException; import java.net.Inet4Address; @@ -29,20 +28,24 @@ import java.util.List; import java.util.concurrent.Executor; import java.util.logging.Logger; +import static java.util.Collections.addAll; +import static java.util.Collections.sort; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; +import static java.util.logging.Logger.getLogger; import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.TRANSPORT_ID_LAN; import static org.briarproject.bramble.api.plugin.LanTcpConstants.ID; import static org.briarproject.bramble.api.plugin.LanTcpConstants.PREF_LAN_IP_PORTS; import static org.briarproject.bramble.api.plugin.LanTcpConstants.PROP_IP_PORTS; import static org.briarproject.bramble.util.ByteUtils.MAX_16_BIT_UNSIGNED; import static org.briarproject.bramble.util.PrivacyUtils.scrubSocketAddress; +import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty; +import static org.briarproject.bramble.util.StringUtils.join; @NotNullByDefault class LanTcpPlugin extends TcpPlugin { - private static final Logger LOG = - Logger.getLogger(LanTcpPlugin.class.getName()); + private static final Logger LOG = getLogger(LanTcpPlugin.class.getName()); private static final LanAddressComparator ADDRESS_COMPARATOR = new LanAddressComparator(); @@ -50,8 +53,8 @@ class LanTcpPlugin extends TcpPlugin { private static final int MAX_ADDRESSES = 4; private static final String SEPARATOR = ","; - LanTcpPlugin(Executor ioExecutor, Backoff backoff, - DuplexPluginCallback callback, int maxLatency, int maxIdleTime) { + LanTcpPlugin(Executor ioExecutor, Backoff backoff, PluginCallback callback, + int maxLatency, int maxIdleTime) { super(ioExecutor, backoff, callback, maxLatency, maxIdleTime); } @@ -77,12 +80,12 @@ class LanTcpPlugin extends TcpPlugin { locals.add(new InetSocketAddress(local, 0)); } } - Collections.sort(locals, ADDRESS_COMPARATOR); + sort(locals, ADDRESS_COMPARATOR); return locals; } private List parseSocketAddresses(String ipPorts) { - if (StringUtils.isNullOrEmpty(ipPorts)) return Collections.emptyList(); + if (isNullOrEmpty(ipPorts)) return Collections.emptyList(); String[] split = ipPorts.split(SEPARATOR); List addresses = new ArrayList<>(); for (String ipPort : split) { @@ -98,24 +101,24 @@ class LanTcpPlugin extends TcpPlugin { // Get the list of recently used addresses String setting = callback.getSettings().get(PREF_LAN_IP_PORTS); List recent = new ArrayList<>(); - if (!StringUtils.isNullOrEmpty(setting)) - Collections.addAll(recent, setting.split(SEPARATOR)); + if (!isNullOrEmpty(setting)) + addAll(recent, setting.split(SEPARATOR)); // Is the address already in the list? if (recent.remove(ipPort)) { // Move the address to the start of the list recent.add(0, ipPort); - setting = StringUtils.join(recent, SEPARATOR); + setting = join(recent, SEPARATOR); } else { // Add the address to the start of the list recent.add(0, ipPort); // Drop the least recently used address if the list is full if (recent.size() > MAX_ADDRESSES) recent = recent.subList(0, MAX_ADDRESSES); - setting = StringUtils.join(recent, SEPARATOR); + setting = join(recent, SEPARATOR); // Update the list of addresses shared with contacts List shared = new ArrayList<>(recent); - Collections.sort(shared); - String property = StringUtils.join(shared, SEPARATOR); + sort(shared); + String property = join(shared, SEPARATOR); TransportProperties properties = new TransportProperties(); properties.put(PROP_IP_PORTS, property); callback.mergeLocalProperties(properties); diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPluginFactory.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPluginFactory.java index a15277c22..caa4c6a2e 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPluginFactory.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPluginFactory.java @@ -3,9 +3,9 @@ package org.briarproject.bramble.plugin.tcp; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.plugin.Backoff; import org.briarproject.bramble.api.plugin.BackoffFactory; +import org.briarproject.bramble.api.plugin.PluginCallback; import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; -import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback; import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory; import java.util.concurrent.Executor; @@ -44,7 +44,7 @@ public class LanTcpPluginFactory implements DuplexPluginFactory { } @Override - public DuplexPlugin createPlugin(DuplexPluginCallback callback) { + public DuplexPlugin createPlugin(PluginCallback callback) { Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL, MAX_POLLING_INTERVAL, BACKOFF_BASE); return new LanTcpPlugin(ioExecutor, backoff, callback, MAX_LATENCY, diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/TcpPlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/TcpPlugin.java index 3e8a008be..aa35274d7 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/TcpPlugin.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/TcpPlugin.java @@ -1,18 +1,18 @@ package org.briarproject.bramble.plugin.tcp; import org.briarproject.bramble.PoliteExecutor; -import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.bramble.api.Pair; import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.keyagreement.KeyAgreementListener; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; import org.briarproject.bramble.api.plugin.Backoff; +import org.briarproject.bramble.api.plugin.ConnectionHandler; +import org.briarproject.bramble.api.plugin.PluginCallback; import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; -import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback; import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; import org.briarproject.bramble.api.properties.TransportProperties; import org.briarproject.bramble.util.IoUtils; -import org.briarproject.bramble.util.StringUtils; import java.io.IOException; import java.net.InetAddress; @@ -27,8 +27,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.List; -import java.util.Map; -import java.util.Map.Entry; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Logger; @@ -41,21 +39,23 @@ import static java.util.Collections.emptyList; import static java.util.Collections.list; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; +import static java.util.logging.Logger.getLogger; import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.bramble.util.PrivacyUtils.scrubSocketAddress; +import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty; @MethodsNotNullByDefault @ParametersNotNullByDefault abstract class TcpPlugin implements DuplexPlugin { + private static final Logger LOG = getLogger(TcpPlugin.class.getName()); + private static final Pattern DOTTED_QUAD = Pattern.compile("^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$"); - private static final Logger LOG = - Logger.getLogger(TcpPlugin.class.getName()); protected final Executor ioExecutor, bindExecutor; protected final Backoff backoff; - protected final DuplexPluginCallback callback; + protected final PluginCallback callback; protected final int maxLatency, maxIdleTime, socketTimeout; protected final AtomicBoolean used = new AtomicBoolean(false); @@ -86,8 +86,8 @@ abstract class TcpPlugin implements DuplexPlugin { */ protected abstract boolean isConnectable(InetSocketAddress remote); - TcpPlugin(Executor ioExecutor, Backoff backoff, - DuplexPluginCallback callback, int maxLatency, int maxIdleTime) { + TcpPlugin(Executor ioExecutor, Backoff backoff, PluginCallback callback, + int maxLatency, int maxIdleTime) { this.ioExecutor = ioExecutor; this.backoff = backoff; this.callback = callback; @@ -180,8 +180,7 @@ abstract class TcpPlugin implements DuplexPlugin { LOG.info("Connection from " + scrubSocketAddress(s.getRemoteSocketAddress())); backoff.reset(); - TcpTransportConnection conn = new TcpTransportConnection(this, s); - callback.incomingConnectionCreated(conn); + callback.handleConnection(new TcpTransportConnection(this, s)); } } @@ -207,20 +206,21 @@ abstract class TcpPlugin implements DuplexPlugin { } @Override - public void poll(Map contacts) { + public void poll(Collection> + properties) { if (!isRunning()) return; backoff.increment(); - for (Entry e : contacts.entrySet()) { - connectAndCallBack(e.getKey(), e.getValue()); + for (Pair p : properties) { + connect(p.getFirst(), p.getSecond()); } } - private void connectAndCallBack(ContactId c, TransportProperties p) { + private void connect(TransportProperties p, ConnectionHandler h) { ioExecutor.execute(() -> { DuplexTransportConnection d = createConnection(p); if (d != null) { backoff.reset(); - callback.outgoingConnectionCreated(c, d); + h.handleConnection(d); } }); } @@ -263,7 +263,7 @@ abstract class TcpPlugin implements DuplexPlugin { @Nullable InetSocketAddress parseSocketAddress(String ipPort) { - if (StringUtils.isNullOrEmpty(ipPort)) return null; + if (isNullOrEmpty(ipPort)) return null; String[] split = ipPort.split(":"); if (split.length != 2) return null; String addr = split[0], port = split[1]; diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/WanTcpPlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/WanTcpPlugin.java index 8144f921e..0450820dc 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/WanTcpPlugin.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/WanTcpPlugin.java @@ -3,18 +3,19 @@ package org.briarproject.bramble.plugin.tcp; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; import org.briarproject.bramble.api.plugin.Backoff; +import org.briarproject.bramble.api.plugin.PluginCallback; import org.briarproject.bramble.api.plugin.TransportId; -import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback; import org.briarproject.bramble.api.properties.TransportProperties; import java.net.Inet4Address; import java.net.InetAddress; import java.net.InetSocketAddress; -import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.concurrent.Executor; +import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; import static org.briarproject.bramble.api.plugin.WanTcpConstants.ID; @MethodsNotNullByDefault @@ -28,7 +29,7 @@ class WanTcpPlugin extends TcpPlugin { private volatile MappingResult mappingResult; WanTcpPlugin(Executor ioExecutor, Backoff backoff, PortMapper portMapper, - DuplexPluginCallback callback, int maxLatency, int maxIdleTime) { + PluginCallback callback, int maxLatency, int maxIdleTime) { super(ioExecutor, backoff, callback, maxLatency, maxIdleTime); this.portMapper = portMapper; } @@ -80,8 +81,8 @@ class WanTcpPlugin extends TcpPlugin { protected List getRemoteSocketAddresses( TransportProperties p) { InetSocketAddress parsed = parseSocketAddress(p.get(PROP_IP_PORT)); - if (parsed == null) return Collections.emptyList(); - return Collections.singletonList(parsed); + if (parsed == null) return emptyList(); + return singletonList(parsed); } @Override diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/WanTcpPluginFactory.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/WanTcpPluginFactory.java index 42deaaffc..440b208f1 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/WanTcpPluginFactory.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/WanTcpPluginFactory.java @@ -4,9 +4,9 @@ import org.briarproject.bramble.api.lifecycle.ShutdownManager; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.plugin.Backoff; import org.briarproject.bramble.api.plugin.BackoffFactory; +import org.briarproject.bramble.api.plugin.PluginCallback; import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; -import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback; import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory; import java.util.concurrent.Executor; @@ -47,7 +47,7 @@ public class WanTcpPluginFactory implements DuplexPluginFactory { } @Override - public DuplexPlugin createPlugin(DuplexPluginCallback callback) { + public DuplexPlugin createPlugin(PluginCallback callback) { Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL, MAX_POLLING_INTERVAL, BACKOFF_BASE); return new WanTcpPlugin(ioExecutor, backoff, diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java index b2d0f45bf..38efad254 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java @@ -4,9 +4,9 @@ import net.freehaven.tor.control.EventHandler; import net.freehaven.tor.control.TorControlConnection; import org.briarproject.bramble.PoliteExecutor; +import org.briarproject.bramble.api.Pair; import org.briarproject.bramble.api.battery.BatteryManager; import org.briarproject.bramble.api.battery.event.BatteryEvent; -import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.event.EventListener; @@ -17,11 +17,12 @@ import org.briarproject.bramble.api.network.event.NetworkStatusEvent; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; import org.briarproject.bramble.api.plugin.Backoff; +import org.briarproject.bramble.api.plugin.ConnectionHandler; +import org.briarproject.bramble.api.plugin.PluginCallback; import org.briarproject.bramble.api.plugin.PluginException; import org.briarproject.bramble.api.plugin.TorConstants; import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; -import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback; import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; import org.briarproject.bramble.api.properties.TransportProperties; import org.briarproject.bramble.api.settings.Settings; @@ -47,7 +48,6 @@ import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.Map.Entry; import java.util.Scanner; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicBoolean; @@ -60,6 +60,7 @@ import javax.net.SocketFactory; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; +import static java.util.logging.Logger.getLogger; import static net.freehaven.tor.control.TorControlCommands.HS_ADDRESS; import static net.freehaven.tor.control.TorControlCommands.HS_PRIVKEY; import static org.briarproject.bramble.api.plugin.TorConstants.CONTROL_PORT; @@ -81,8 +82,7 @@ import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty; @ParametersNotNullByDefault abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener { - private static final Logger LOG = - Logger.getLogger(TorPlugin.class.getName()); + private static final Logger LOG = getLogger(TorPlugin.class.getName()); private static final String[] EVENTS = { "CIRC", "ORCONN", "HS_DESC", "NOTICE", "WARN", "ERR" @@ -100,7 +100,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener { private final Clock clock; private final BatteryManager batteryManager; private final Backoff backoff; - private final DuplexPluginCallback callback; + private final PluginCallback callback; private final String architecture; private final CircumventionProvider circumventionProvider; private final ResourceProvider resourceProvider; @@ -126,7 +126,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener { Clock clock, ResourceProvider resourceProvider, CircumventionProvider circumventionProvider, BatteryManager batteryManager, Backoff backoff, - DuplexPluginCallback callback, String architecture, int maxLatency, + PluginCallback callback, String architecture, int maxLatency, int maxIdleTime, File torDirectory) { this.ioExecutor = ioExecutor; this.networkManager = networkManager; @@ -458,8 +458,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener { } LOG.info("Connection received"); backoff.reset(); - TorTransportConnection conn = new TorTransportConnection(this, s); - callback.incomingConnectionCreated(conn); + callback.handleConnection(new TorTransportConnection(this, s)); } } @@ -521,20 +520,21 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener { } @Override - public void poll(Map contacts) { + public void poll(Collection> + properties) { if (!isRunning()) return; backoff.increment(); - for (Entry e : contacts.entrySet()) { - connectAndCallBack(e.getKey(), e.getValue()); + for (Pair p : properties) { + connect(p.getFirst(), p.getSecond()); } } - private void connectAndCallBack(ContactId c, TransportProperties p) { + private void connect(TransportProperties p, ConnectionHandler h) { ioExecutor.execute(() -> { DuplexTransportConnection d = createConnection(p); if (d != null) { backoff.reset(); - callback.outgoingConnectionCreated(c, d); + h.handleConnection(d); } }); } diff --git a/bramble-core/src/test/java/org/briarproject/bramble/plugin/PluginManagerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/plugin/PluginManagerImplTest.java index 55ad46757..93f649db8 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/plugin/PluginManagerImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/plugin/PluginManagerImplTest.java @@ -2,14 +2,13 @@ package org.briarproject.bramble.plugin; import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.plugin.ConnectionManager; +import org.briarproject.bramble.api.plugin.PluginCallback; import org.briarproject.bramble.api.plugin.PluginConfig; import org.briarproject.bramble.api.plugin.PluginException; import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; -import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback; import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory; import org.briarproject.bramble.api.plugin.simplex.SimplexPlugin; -import org.briarproject.bramble.api.plugin.simplex.SimplexPluginCallback; import org.briarproject.bramble.api.plugin.simplex.SimplexPluginFactory; import org.briarproject.bramble.api.properties.TransportPropertyManager; import org.briarproject.bramble.api.settings.SettingsManager; @@ -78,15 +77,14 @@ public class PluginManagerImplTest extends BrambleTestCase { simplexFailFactory))); oneOf(simplexFactory).getId(); will(returnValue(simplexId)); - oneOf(simplexFactory).createPlugin(with(any( - SimplexPluginCallback.class))); + oneOf(simplexFactory).createPlugin(with(any(PluginCallback.class))); will(returnValue(simplexPlugin)); // Created oneOf(simplexPlugin).start(); // Second simplex plugin oneOf(simplexFailFactory).getId(); will(returnValue(simplexFailId)); oneOf(simplexFailFactory).createPlugin(with(any( - SimplexPluginCallback.class))); + PluginCallback.class))); will(returnValue(simplexFailPlugin)); // Created oneOf(simplexFailPlugin).start(); will(throwException(new PluginException())); @@ -95,15 +93,14 @@ public class PluginManagerImplTest extends BrambleTestCase { will(returnValue(Arrays.asList(duplexFactory, duplexFailFactory))); oneOf(duplexFactory).getId(); will(returnValue(duplexId)); - oneOf(duplexFactory).createPlugin(with(any( - DuplexPluginCallback.class))); + oneOf(duplexFactory).createPlugin(with(any(PluginCallback.class))); will(returnValue(duplexPlugin)); // Created oneOf(duplexPlugin).start(); // Second duplex plugin oneOf(duplexFailFactory).getId(); will(returnValue(duplexFailId)); oneOf(duplexFailFactory).createPlugin(with(any( - DuplexPluginCallback.class))); + PluginCallback.class))); will(returnValue(null)); // Failed to create a plugin // stop() // Stop the plugins diff --git a/bramble-core/src/test/java/org/briarproject/bramble/plugin/PollerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/plugin/PollerImplTest.java index 9b038ef0a..481de6755 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/plugin/PollerImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/plugin/PollerImplTest.java @@ -2,6 +2,7 @@ package org.briarproject.bramble.plugin; import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.event.ContactAddedEvent; +import org.briarproject.bramble.api.plugin.ConnectionHandler; import org.briarproject.bramble.api.plugin.ConnectionManager; import org.briarproject.bramble.api.plugin.ConnectionRegistry; import org.briarproject.bramble.api.plugin.Plugin; @@ -37,6 +38,8 @@ import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; import static java.util.Collections.singletonMap; import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static org.briarproject.bramble.test.CollectionMatcher.collectionOf; +import static org.briarproject.bramble.test.PairMatcher.pairOf; import static org.briarproject.bramble.test.TestUtils.getContactId; import static org.briarproject.bramble.test.TestUtils.getTransportId; @@ -354,7 +357,8 @@ public class PollerImplTest extends BrambleMockTestCase { oneOf(connectionRegistry).getConnectedContacts(transportId); will(returnValue(emptyList())); // Poll the plugin - oneOf(plugin).poll(singletonMap(contactId, properties)); + oneOf(plugin).poll(with(collectionOf( + pairOf(equal(properties), any(ConnectionHandler.class))))); }}); poller.eventOccurred(new TransportEnabledEvent(transportId)); diff --git a/bramble-core/src/test/java/org/briarproject/bramble/plugin/tcp/LanTcpPluginTest.java b/bramble-core/src/test/java/org/briarproject/bramble/plugin/tcp/LanTcpPluginTest.java index 8cc15b7f2..12ccaf1e8 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/plugin/tcp/LanTcpPluginTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/plugin/tcp/LanTcpPluginTest.java @@ -1,12 +1,13 @@ package org.briarproject.bramble.plugin.tcp; -import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.keyagreement.KeyAgreementListener; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.plugin.Backoff; +import org.briarproject.bramble.api.plugin.PluginCallback; +import org.briarproject.bramble.api.plugin.TransportConnectionReader; +import org.briarproject.bramble.api.plugin.TransportConnectionWriter; import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; -import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback; import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; import org.briarproject.bramble.api.properties.TransportProperties; import org.briarproject.bramble.api.settings.Settings; @@ -21,13 +22,14 @@ import java.net.InetSocketAddress; import java.net.NetworkInterface; import java.net.ServerSocket; import java.net.Socket; -import java.util.Collections; import java.util.Comparator; import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; +import java.util.concurrent.ExecutorService; import java.util.concurrent.atomic.AtomicBoolean; +import static java.net.NetworkInterface.getNetworkInterfaces; +import static java.util.Collections.list; +import static java.util.concurrent.Executors.newCachedThreadPool; import static java.util.concurrent.TimeUnit.SECONDS; import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.COMMIT_LENGTH; import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.TRANSPORT_ID_LAN; @@ -39,10 +41,13 @@ import static org.junit.Assert.assertTrue; public class LanTcpPluginTest extends BrambleTestCase { private final Backoff backoff = new TestBackoff(); + private final ExecutorService ioExecutor = newCachedThreadPool(); @Test public void testAddressesAreOnSameLan() { - LanTcpPlugin plugin = new LanTcpPlugin(null, null, null, 0, 0); + Callback callback = new Callback(); + LanTcpPlugin plugin = new LanTcpPlugin(ioExecutor, backoff, callback, + 0, 0); // Local and remote in 10.0.0.0/8 should return true assertTrue(plugin.addressesAreOnSameLan(makeAddress(10, 0, 0, 0), makeAddress(10, 255, 255, 255))); @@ -93,8 +98,7 @@ public class LanTcpPluginTest extends BrambleTestCase { return; } Callback callback = new Callback(); - Executor executor = Executors.newCachedThreadPool(); - DuplexPlugin plugin = new LanTcpPlugin(executor, backoff, callback, + DuplexPlugin plugin = new LanTcpPlugin(ioExecutor, backoff, callback, 0, 0); plugin.start(); // The plugin should have bound a socket and stored the port number @@ -129,8 +133,7 @@ public class LanTcpPluginTest extends BrambleTestCase { return; } Callback callback = new Callback(); - Executor executor = Executors.newCachedThreadPool(); - DuplexPlugin plugin = new LanTcpPlugin(executor, backoff, callback, + DuplexPlugin plugin = new LanTcpPlugin(ioExecutor, backoff, callback, 0, 0); plugin.start(); // The plugin should have bound a socket and stored the port number @@ -179,8 +182,7 @@ public class LanTcpPluginTest extends BrambleTestCase { return; } Callback callback = new Callback(); - Executor executor = Executors.newCachedThreadPool(); - DuplexPlugin plugin = new LanTcpPlugin(executor, backoff, callback, + DuplexPlugin plugin = new LanTcpPlugin(ioExecutor, backoff, callback, 0, 0); plugin.start(); assertTrue(callback.propertiesLatch.await(5, SECONDS)); @@ -228,8 +230,7 @@ public class LanTcpPluginTest extends BrambleTestCase { return; } Callback callback = new Callback(); - Executor executor = Executors.newCachedThreadPool(); - DuplexPlugin plugin = new LanTcpPlugin(executor, backoff, callback, + DuplexPlugin plugin = new LanTcpPlugin(ioExecutor, backoff, callback, 0, 0); plugin.start(); // The plugin should have bound a socket and stored the port number @@ -327,9 +328,8 @@ public class LanTcpPluginTest extends BrambleTestCase { } private boolean systemHasLocalIpv4Address() throws Exception { - for (NetworkInterface i : Collections.list( - NetworkInterface.getNetworkInterfaces())) { - for (InetAddress a : Collections.list(i.getInetAddresses())) { + for (NetworkInterface i : list(getNetworkInterfaces())) { + for (InetAddress a : list(i.getInetAddresses())) { if (a instanceof Inet4Address) return a.isLinkLocalAddress() || a.isSiteLocalAddress(); } @@ -338,7 +338,7 @@ public class LanTcpPluginTest extends BrambleTestCase { } @NotNullByDefault - private static class Callback implements DuplexPluginCallback { + private static class Callback implements PluginCallback { private final CountDownLatch propertiesLatch = new CountDownLatch(1); private final CountDownLatch connectionsLatch = new CountDownLatch(1); @@ -364,16 +364,6 @@ public class LanTcpPluginTest extends BrambleTestCase { propertiesLatch.countDown(); } - @Override - public void incomingConnectionCreated(DuplexTransportConnection d) { - connectionsLatch.countDown(); - } - - @Override - public void outgoingConnectionCreated(ContactId c, - DuplexTransportConnection d) { - } - @Override public void transportEnabled() { } @@ -381,6 +371,19 @@ public class LanTcpPluginTest extends BrambleTestCase { @Override public void transportDisabled() { } + + @Override + public void handleConnection(DuplexTransportConnection d) { + connectionsLatch.countDown(); + } + + @Override + public void handleReader(TransportConnectionReader r) { + } + + @Override + public void handleWriter(TransportConnectionWriter w) { + } } private static class TestBackoff implements Backoff { diff --git a/bramble-core/src/test/java/org/briarproject/bramble/test/CollectionMatcher.java b/bramble-core/src/test/java/org/briarproject/bramble/test/CollectionMatcher.java new file mode 100644 index 000000000..365878217 --- /dev/null +++ b/bramble-core/src/test/java/org/briarproject/bramble/test/CollectionMatcher.java @@ -0,0 +1,39 @@ +package org.briarproject.bramble.test; + +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; +import org.hamcrest.Matcher; + +import java.util.Collection; + +import javax.annotation.Nullable; + +@NotNullByDefault +public class CollectionMatcher extends BaseMatcher> { + + private final Matcher elementMatcher; + + public CollectionMatcher(Matcher elementMatcher) { + this.elementMatcher = elementMatcher; + } + + @Override + public boolean matches(@Nullable Object item) { + if (!(item instanceof Collection)) return false; + Collection collection = (Collection) item; + for (Object element : collection) { + if (!elementMatcher.matches(element)) return false; + } + return true; + } + + @Override + public void describeTo(Description description) { + description.appendText("matches a collection"); + } + + public static CollectionMatcher collectionOf(Matcher t) { + return new CollectionMatcher<>(t); + } +} diff --git a/bramble-core/src/test/java/org/briarproject/bramble/test/PairMatcher.java b/bramble-core/src/test/java/org/briarproject/bramble/test/PairMatcher.java new file mode 100644 index 000000000..5e834fb5e --- /dev/null +++ b/bramble-core/src/test/java/org/briarproject/bramble/test/PairMatcher.java @@ -0,0 +1,38 @@ +package org.briarproject.bramble.test; + +import org.briarproject.bramble.api.Pair; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; +import org.hamcrest.Matcher; + +import javax.annotation.Nullable; + +@NotNullByDefault +public class PairMatcher extends BaseMatcher> { + + private final Matcher firstMatcher; + private final Matcher secondMatcher; + + public PairMatcher(Matcher firstMatcher, Matcher secondMatcher) { + this.firstMatcher = firstMatcher; + this.secondMatcher = secondMatcher; + } + + @Override + public boolean matches(@Nullable Object item) { + if (!(item instanceof Pair)) return false; + Pair pair = (Pair) item; + return firstMatcher.matches(pair.getFirst()) && + secondMatcher.matches(pair.getSecond()); + } + + @Override + public void describeTo(Description description) { + description.appendText("matches a pair"); + } + + public static PairMatcher pairOf(Matcher a, Matcher b) { + return new PairMatcher<>(a, b); + } +} diff --git a/bramble-core/src/test/java/org/briarproject/bramble/test/TestPluginConfigModule.java b/bramble-core/src/test/java/org/briarproject/bramble/test/TestPluginConfigModule.java index be9cd23d5..02d63142c 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/test/TestPluginConfigModule.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/test/TestPluginConfigModule.java @@ -1,11 +1,11 @@ package org.briarproject.bramble.test; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.plugin.PluginCallback; import org.briarproject.bramble.api.plugin.PluginConfig; import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory; import org.briarproject.bramble.api.plugin.simplex.SimplexPlugin; -import org.briarproject.bramble.api.plugin.simplex.SimplexPluginCallback; import org.briarproject.bramble.api.plugin.simplex.SimplexPluginFactory; import java.util.Collection; @@ -40,7 +40,7 @@ public class TestPluginConfigModule { @Override @Nullable - public SimplexPlugin createPlugin(SimplexPluginCallback callback) { + public SimplexPlugin createPlugin(PluginCallback callback) { return null; } }; diff --git a/bramble-java/src/main/java/org/briarproject/bramble/plugin/bluetooth/JavaBluetoothPlugin.java b/bramble-java/src/main/java/org/briarproject/bramble/plugin/bluetooth/JavaBluetoothPlugin.java index c3fe9b028..59a105f20 100644 --- a/bramble-java/src/main/java/org/briarproject/bramble/plugin/bluetooth/JavaBluetoothPlugin.java +++ b/bramble-java/src/main/java/org/briarproject/bramble/plugin/bluetooth/JavaBluetoothPlugin.java @@ -3,7 +3,7 @@ package org.briarproject.bramble.plugin.bluetooth; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; import org.briarproject.bramble.api.plugin.Backoff; -import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback; +import org.briarproject.bramble.api.plugin.PluginCallback; import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; import java.io.IOException; @@ -19,6 +19,7 @@ import javax.microedition.io.StreamConnection; import javax.microedition.io.StreamConnectionNotifier; import static java.util.logging.Level.WARNING; +import static java.util.logging.Logger.getLogger; import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.bramble.util.StringUtils.isValidMac; @@ -27,14 +28,14 @@ import static org.briarproject.bramble.util.StringUtils.isValidMac; class JavaBluetoothPlugin extends BluetoothPlugin { private static final Logger LOG = - Logger.getLogger(JavaBluetoothPlugin.class.getName()); + getLogger(JavaBluetoothPlugin.class.getName()); // Non-null if the plugin started successfully private volatile LocalDevice localDevice = null; JavaBluetoothPlugin(BluetoothConnectionLimiter connectionManager, Executor ioExecutor, SecureRandom secureRandom, - Backoff backoff, DuplexPluginCallback callback, int maxLatency) { + Backoff backoff, PluginCallback callback, int maxLatency) { super(connectionManager, ioExecutor, secureRandom, backoff, callback, maxLatency); } diff --git a/bramble-java/src/main/java/org/briarproject/bramble/plugin/bluetooth/JavaBluetoothPluginFactory.java b/bramble-java/src/main/java/org/briarproject/bramble/plugin/bluetooth/JavaBluetoothPluginFactory.java index 3008e7767..a2ada859d 100644 --- a/bramble-java/src/main/java/org/briarproject/bramble/plugin/bluetooth/JavaBluetoothPluginFactory.java +++ b/bramble-java/src/main/java/org/briarproject/bramble/plugin/bluetooth/JavaBluetoothPluginFactory.java @@ -4,9 +4,9 @@ import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.plugin.Backoff; import org.briarproject.bramble.api.plugin.BackoffFactory; +import org.briarproject.bramble.api.plugin.PluginCallback; import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; -import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback; import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory; import java.security.SecureRandom; @@ -50,7 +50,7 @@ public class JavaBluetoothPluginFactory implements DuplexPluginFactory { } @Override - public DuplexPlugin createPlugin(DuplexPluginCallback callback) { + public DuplexPlugin createPlugin(PluginCallback callback) { BluetoothConnectionLimiter connectionLimiter = new BluetoothConnectionLimiterImpl(); Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL, diff --git a/bramble-java/src/main/java/org/briarproject/bramble/plugin/modem/ModemPlugin.java b/bramble-java/src/main/java/org/briarproject/bramble/plugin/modem/ModemPlugin.java index 4d70fa14b..f6449ccc9 100644 --- a/bramble-java/src/main/java/org/briarproject/bramble/plugin/modem/ModemPlugin.java +++ b/bramble-java/src/main/java/org/briarproject/bramble/plugin/modem/ModemPlugin.java @@ -1,29 +1,31 @@ package org.briarproject.bramble.plugin.modem; -import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.bramble.api.Pair; import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.keyagreement.KeyAgreementListener; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; +import org.briarproject.bramble.api.plugin.ConnectionHandler; +import org.briarproject.bramble.api.plugin.PluginCallback; import org.briarproject.bramble.api.plugin.PluginException; import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.duplex.AbstractDuplexTransportConnection; import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; -import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback; import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; import org.briarproject.bramble.api.properties.TransportProperties; -import org.briarproject.bramble.util.StringUtils; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.util.Map; +import java.util.Collection; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Logger; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; +import static java.util.logging.Logger.getLogger; import static org.briarproject.bramble.util.LogUtils.logException; +import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty; @MethodsNotNullByDefault @ParametersNotNullByDefault @@ -33,11 +35,11 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback { new TransportId("org.briarproject.bramble.modem"); private static final Logger LOG = - Logger.getLogger(ModemPlugin.class.getName()); + getLogger(ModemPlugin.class.getName()); private final ModemFactory modemFactory; private final SerialPortList serialPortList; - private final DuplexPluginCallback callback; + private final PluginCallback callback; private final int maxLatency; private final AtomicBoolean used = new AtomicBoolean(false); @@ -45,7 +47,7 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback { private volatile Modem modem = null; ModemPlugin(ModemFactory modemFactory, SerialPortList serialPortList, - DuplexPluginCallback callback, int maxLatency) { + PluginCallback callback, int maxLatency) { this.modemFactory = modemFactory; this.serialPortList = serialPortList; this.callback = callback; @@ -116,7 +118,8 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback { } @Override - public void poll(Map contacts) { + public void poll(Collection> + properties) { throw new UnsupportedOperationException(); } @@ -144,13 +147,13 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback { if (!running) return null; // Get the ISO 3166 code for the caller's country String fromIso = callback.getLocalProperties().get("iso3166"); - if (StringUtils.isNullOrEmpty(fromIso)) return null; + if (isNullOrEmpty(fromIso)) return null; // Get the ISO 3166 code for the callee's country String toIso = p.get("iso3166"); - if (StringUtils.isNullOrEmpty(toIso)) return null; + if (isNullOrEmpty(toIso)) return null; // Get the callee's phone number String number = p.get("number"); - if (StringUtils.isNullOrEmpty(number)) return null; + if (isNullOrEmpty(number)) return null; // Convert the number into direct dialling form number = CountryCodes.translate(number, fromIso, toIso); if (number == null) return null; @@ -184,7 +187,7 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback { @Override public void incomingCallConnected() { LOG.info("Incoming call connected"); - callback.incomingConnectionCreated(new ModemTransportConnection()); + callback.handleConnection(new ModemTransportConnection()); } private class ModemTransportConnection diff --git a/bramble-java/src/main/java/org/briarproject/bramble/plugin/modem/ModemPluginFactory.java b/bramble-java/src/main/java/org/briarproject/bramble/plugin/modem/ModemPluginFactory.java index 1a3a1f24a..edffe7a31 100644 --- a/bramble-java/src/main/java/org/briarproject/bramble/plugin/modem/ModemPluginFactory.java +++ b/bramble-java/src/main/java/org/briarproject/bramble/plugin/modem/ModemPluginFactory.java @@ -1,9 +1,9 @@ package org.briarproject.bramble.plugin.modem; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.plugin.PluginCallback; import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; -import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback; import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory; import org.briarproject.bramble.api.reliability.ReliabilityLayerFactory; import org.briarproject.bramble.util.StringUtils; @@ -38,7 +38,7 @@ public class ModemPluginFactory implements DuplexPluginFactory { } @Override - public DuplexPlugin createPlugin(DuplexPluginCallback callback) { + public DuplexPlugin createPlugin(PluginCallback callback) { // This plugin is not enabled by default String enabled = callback.getSettings().get("enabled"); if (StringUtils.isNullOrEmpty(enabled)) return null; diff --git a/bramble-java/src/main/java/org/briarproject/bramble/plugin/tor/JavaTorPlugin.java b/bramble-java/src/main/java/org/briarproject/bramble/plugin/tor/JavaTorPlugin.java index 75412fe55..d08300b2a 100644 --- a/bramble-java/src/main/java/org/briarproject/bramble/plugin/tor/JavaTorPlugin.java +++ b/bramble-java/src/main/java/org/briarproject/bramble/plugin/tor/JavaTorPlugin.java @@ -4,7 +4,7 @@ import org.briarproject.bramble.api.battery.BatteryManager; import org.briarproject.bramble.api.network.NetworkManager; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.plugin.Backoff; -import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback; +import org.briarproject.bramble.api.plugin.PluginCallback; import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.LocationUtils; import org.briarproject.bramble.api.system.ResourceProvider; @@ -25,7 +25,7 @@ abstract class JavaTorPlugin extends TorPlugin { Clock clock, ResourceProvider resourceProvider, CircumventionProvider circumventionProvider, BatteryManager batteryManager, Backoff backoff, - DuplexPluginCallback callback, String architecture, int maxLatency, + PluginCallback callback, String architecture, int maxLatency, int maxIdleTime, File torDirectory) { super(ioExecutor, networkManager, locationUtils, torSocketFactory, clock, resourceProvider, circumventionProvider, batteryManager, diff --git a/bramble-java/src/main/java/org/briarproject/bramble/plugin/tor/UnixTorPlugin.java b/bramble-java/src/main/java/org/briarproject/bramble/plugin/tor/UnixTorPlugin.java index e084875bf..753840a76 100644 --- a/bramble-java/src/main/java/org/briarproject/bramble/plugin/tor/UnixTorPlugin.java +++ b/bramble-java/src/main/java/org/briarproject/bramble/plugin/tor/UnixTorPlugin.java @@ -7,7 +7,7 @@ import org.briarproject.bramble.api.battery.BatteryManager; import org.briarproject.bramble.api.network.NetworkManager; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.plugin.Backoff; -import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback; +import org.briarproject.bramble.api.plugin.PluginCallback; import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.LocationUtils; import org.briarproject.bramble.api.system.ResourceProvider; @@ -25,7 +25,7 @@ class UnixTorPlugin extends JavaTorPlugin { Clock clock, ResourceProvider resourceProvider, CircumventionProvider circumventionProvider, BatteryManager batteryManager, Backoff backoff, - DuplexPluginCallback callback, String architecture, int maxLatency, + PluginCallback callback, String architecture, int maxLatency, int maxIdleTime, File torDirectory) { super(ioExecutor, networkManager, locationUtils, torSocketFactory, clock, resourceProvider, circumventionProvider, batteryManager, @@ -40,7 +40,7 @@ class UnixTorPlugin extends JavaTorPlugin { private interface CLibrary extends Library { - CLibrary INSTANCE = (CLibrary) Native.loadLibrary("c", CLibrary.class); + CLibrary INSTANCE = Native.loadLibrary("c", CLibrary.class); int getpid(); } diff --git a/bramble-java/src/main/java/org/briarproject/bramble/plugin/tor/UnixTorPluginFactory.java b/bramble-java/src/main/java/org/briarproject/bramble/plugin/tor/UnixTorPluginFactory.java index 2279ef07a..0e8425712 100644 --- a/bramble-java/src/main/java/org/briarproject/bramble/plugin/tor/UnixTorPluginFactory.java +++ b/bramble-java/src/main/java/org/briarproject/bramble/plugin/tor/UnixTorPluginFactory.java @@ -6,10 +6,10 @@ import org.briarproject.bramble.api.network.NetworkManager; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.plugin.Backoff; import org.briarproject.bramble.api.plugin.BackoffFactory; +import org.briarproject.bramble.api.plugin.PluginCallback; import org.briarproject.bramble.api.plugin.TorConstants; import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; -import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback; import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory; import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.LocationUtils; @@ -80,7 +80,7 @@ public class UnixTorPluginFactory implements DuplexPluginFactory { } @Override - public DuplexPlugin createPlugin(DuplexPluginCallback callback) { + public DuplexPlugin createPlugin(PluginCallback callback) { // Check that we have a Tor binary for this architecture String architecture = null; if (isLinux()) { diff --git a/bramble-java/src/test/java/org/briarproject/bramble/plugin/modem/ModemPluginTest.java b/bramble-java/src/test/java/org/briarproject/bramble/plugin/modem/ModemPluginTest.java index ba8fb519e..df03d3abf 100644 --- a/bramble-java/src/test/java/org/briarproject/bramble/plugin/modem/ModemPluginTest.java +++ b/bramble-java/src/test/java/org/briarproject/bramble/plugin/modem/ModemPluginTest.java @@ -1,10 +1,10 @@ package org.briarproject.bramble.plugin.modem; -import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback; +import org.briarproject.bramble.api.plugin.PluginCallback; import org.briarproject.bramble.api.properties.TransportProperties; -import org.briarproject.bramble.test.BrambleTestCase; +import org.briarproject.bramble.test.BrambleMockTestCase; import org.jmock.Expectations; -import org.jmock.Mockery; +import org.junit.Before; import org.junit.Test; import java.io.IOException; @@ -12,23 +12,29 @@ import java.io.IOException; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -public class ModemPluginTest extends BrambleTestCase { +public class ModemPluginTest extends BrambleMockTestCase { private static final String ISO_1336 = "GB"; private static final String NUMBER = "0123456789"; + private final ModemFactory modemFactory = context.mock(ModemFactory.class); + private final SerialPortList serialPortList = + context.mock(SerialPortList.class); + private final PluginCallback callback = context.mock(PluginCallback.class); + private final Modem modem = context.mock(Modem.class); + + private ModemPlugin plugin; + + @Before + public void setUp() { + plugin = new ModemPlugin(modemFactory, serialPortList, callback, 0); + } + @Test public void testModemCreation() throws Exception { - Mockery context = new Mockery(); - ModemFactory modemFactory = context.mock(ModemFactory.class); - SerialPortList serialPortList = - context.mock(SerialPortList.class); - ModemPlugin plugin = new ModemPlugin(modemFactory, - serialPortList, null, 0); - Modem modem = context.mock(Modem.class); context.checking(new Expectations() {{ oneOf(serialPortList).getPortNames(); - will(returnValue(new String[] { "foo", "bar", "baz" })); + will(returnValue(new String[] {"foo", "bar", "baz"})); // First call to createModem() returns false oneOf(modemFactory).createModem(plugin, "foo"); will(returnValue(modem)); @@ -45,30 +51,22 @@ public class ModemPluginTest extends BrambleTestCase { oneOf(modem).start(); will(returnValue(true)); }}); + plugin.start(); - context.assertIsSatisfied(); } @Test public void testCreateConnection() throws Exception { - Mockery context = new Mockery(); - ModemFactory modemFactory = context.mock(ModemFactory.class); - SerialPortList serialPortList = - context.mock(SerialPortList.class); - DuplexPluginCallback callback = - context.mock(DuplexPluginCallback.class); - ModemPlugin plugin = new ModemPlugin(modemFactory, - serialPortList, callback, 0); - Modem modem = context.mock(Modem.class); TransportProperties local = new TransportProperties(); local.put("iso3166", ISO_1336); TransportProperties remote = new TransportProperties(); remote.put("iso3166", ISO_1336); remote.put("number", NUMBER); + context.checking(new Expectations() {{ // start() oneOf(serialPortList).getPortNames(); - will(returnValue(new String[] { "foo" })); + will(returnValue(new String[] {"foo"})); oneOf(modemFactory).createModem(plugin, "foo"); will(returnValue(modem)); oneOf(modem).start(); @@ -79,32 +77,24 @@ public class ModemPluginTest extends BrambleTestCase { oneOf(modem).dial(NUMBER); will(returnValue(true)); }}); + plugin.start(); // A connection should be returned assertNotNull(plugin.createConnection(remote)); - context.assertIsSatisfied(); } @Test public void testCreateConnectionWhenDialReturnsFalse() throws Exception { - Mockery context = new Mockery(); - ModemFactory modemFactory = context.mock(ModemFactory.class); - SerialPortList serialPortList = - context.mock(SerialPortList.class); - DuplexPluginCallback callback = - context.mock(DuplexPluginCallback.class); - ModemPlugin plugin = new ModemPlugin(modemFactory, - serialPortList, callback, 0); - Modem modem = context.mock(Modem.class); TransportProperties local = new TransportProperties(); local.put("iso3166", ISO_1336); TransportProperties remote = new TransportProperties(); remote.put("iso3166", ISO_1336); remote.put("number", NUMBER); + context.checking(new Expectations() {{ // start() oneOf(serialPortList).getPortNames(); - will(returnValue(new String[] { "foo" })); + will(returnValue(new String[] {"foo"})); oneOf(modemFactory).createModem(plugin, "foo"); will(returnValue(modem)); oneOf(modem).start(); @@ -115,32 +105,24 @@ public class ModemPluginTest extends BrambleTestCase { oneOf(modem).dial(NUMBER); will(returnValue(false)); }}); + plugin.start(); // No connection should be returned assertNull(plugin.createConnection(remote)); - context.assertIsSatisfied(); } @Test public void testCreateConnectionWhenDialThrowsException() throws Exception { - Mockery context = new Mockery(); - ModemFactory modemFactory = context.mock(ModemFactory.class); - SerialPortList serialPortList = - context.mock(SerialPortList.class); - DuplexPluginCallback callback = - context.mock(DuplexPluginCallback.class); - ModemPlugin plugin = new ModemPlugin(modemFactory, - serialPortList, callback, 0); - Modem modem = context.mock(Modem.class); TransportProperties local = new TransportProperties(); local.put("iso3166", ISO_1336); TransportProperties remote = new TransportProperties(); remote.put("iso3166", ISO_1336); remote.put("number", NUMBER); + context.checking(new Expectations() {{ // start() oneOf(serialPortList).getPortNames(); - will(returnValue(new String[] { "foo" })); + will(returnValue(new String[] {"foo"})); oneOf(modemFactory).createModem(plugin, "foo"); will(returnValue(modem)); oneOf(modem).start(); @@ -152,15 +134,15 @@ public class ModemPluginTest extends BrambleTestCase { will(throwException(new IOException())); // resetModem() oneOf(serialPortList).getPortNames(); - will(returnValue(new String[] { "foo" })); + will(returnValue(new String[] {"foo"})); oneOf(modemFactory).createModem(plugin, "foo"); will(returnValue(modem)); oneOf(modem).start(); will(returnValue(true)); }}); + plugin.start(); // No connection should be returned assertNull(plugin.createConnection(remote)); - context.assertIsSatisfied(); } } diff --git a/bramble-java/src/test/java/org/briarproject/bramble/plugin/tor/BridgeTest.java b/bramble-java/src/test/java/org/briarproject/bramble/plugin/tor/BridgeTest.java index e9c57086a..72b473e5f 100644 --- a/bramble-java/src/test/java/org/briarproject/bramble/plugin/tor/BridgeTest.java +++ b/bramble-java/src/test/java/org/briarproject/bramble/plugin/tor/BridgeTest.java @@ -127,7 +127,7 @@ public class BridgeTest extends BrambleTestCase { @Test public void testBridges() throws Exception { DuplexPlugin duplexPlugin = - factory.createPlugin(new TorPluginCallBack()); + factory.createPlugin(new TestPluginCallback()); assertNotNull(duplexPlugin); UnixTorPlugin plugin = (UnixTorPlugin) duplexPlugin; diff --git a/bramble-java/src/test/java/org/briarproject/bramble/plugin/tor/TorPluginCallBack.java b/bramble-java/src/test/java/org/briarproject/bramble/plugin/tor/TestPluginCallback.java similarity index 63% rename from bramble-java/src/test/java/org/briarproject/bramble/plugin/tor/TorPluginCallBack.java rename to bramble-java/src/test/java/org/briarproject/bramble/plugin/tor/TestPluginCallback.java index 320e8f02f..e8b8121da 100644 --- a/bramble-java/src/test/java/org/briarproject/bramble/plugin/tor/TorPluginCallBack.java +++ b/bramble-java/src/test/java/org/briarproject/bramble/plugin/tor/TestPluginCallback.java @@ -1,25 +1,15 @@ package org.briarproject.bramble.plugin.tor; -import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback; +import org.briarproject.bramble.api.plugin.PluginCallback; +import org.briarproject.bramble.api.plugin.TransportConnectionReader; +import org.briarproject.bramble.api.plugin.TransportConnectionWriter; import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; import org.briarproject.bramble.api.properties.TransportProperties; import org.briarproject.bramble.api.settings.Settings; @NotNullByDefault -public class TorPluginCallBack implements DuplexPluginCallback { - - @Override - public void incomingConnectionCreated(DuplexTransportConnection d) { - - } - - @Override - public void outgoingConnectionCreated(ContactId c, - DuplexTransportConnection d) { - - } +public class TestPluginCallback implements PluginCallback { @Override public Settings getSettings() { @@ -33,22 +23,29 @@ public class TorPluginCallBack implements DuplexPluginCallback { @Override public void mergeSettings(Settings s) { - } @Override public void mergeLocalProperties(TransportProperties p) { - } @Override public void transportEnabled() { - } @Override public void transportDisabled() { - } + @Override + public void handleConnection(DuplexTransportConnection c) { + } + + @Override + public void handleReader(TransportConnectionReader r) { + } + + @Override + public void handleWriter(TransportConnectionWriter w) { + } } From 43b2f9da1ceb62e472910af53f5d4e08f9329dc0 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Fri, 17 May 2019 15:46:37 +0100 Subject: [PATCH 3/4] Static import. --- .../org/briarproject/bramble/plugin/tcp/LanTcpPlugin.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPlugin.java index 5d1575eaf..78ea1a7cd 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPlugin.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPlugin.java @@ -22,13 +22,13 @@ import java.net.Socket; import java.net.SocketAddress; import java.net.UnknownHostException; import java.util.ArrayList; -import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.concurrent.Executor; import java.util.logging.Logger; import static java.util.Collections.addAll; +import static java.util.Collections.emptyList; import static java.util.Collections.sort; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; @@ -85,7 +85,7 @@ class LanTcpPlugin extends TcpPlugin { } private List parseSocketAddresses(String ipPorts) { - if (isNullOrEmpty(ipPorts)) return Collections.emptyList(); + if (isNullOrEmpty(ipPorts)) return emptyList(); String[] split = ipPorts.split(SEPARATOR); List addresses = new ArrayList<>(); for (String ipPort : split) { From ead7570ec59b624df8b0d7a6c927ba7e6f506e72 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Tue, 21 May 2019 14:27:27 +0100 Subject: [PATCH 4/4] Add javadoc. --- .../bramble/api/plugin/ConnectionHandler.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/ConnectionHandler.java b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/ConnectionHandler.java index 7255d03a1..17e7d0f59 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/ConnectionHandler.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/ConnectionHandler.java @@ -1,7 +1,9 @@ package org.briarproject.bramble.api.plugin; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; +import org.briarproject.bramble.api.plugin.simplex.SimplexPlugin; /** * An interface for handling connections created by transport plugins. @@ -9,9 +11,18 @@ import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; @NotNullByDefault public interface ConnectionHandler { + /** + * Handles a connection created by a {@link DuplexPlugin}. + */ void handleConnection(DuplexTransportConnection c); + /** + * Handles a reader created by a {@link SimplexPlugin}. + */ void handleReader(TransportConnectionReader r); + /** + * Handles a writer created by a {@link SimplexPlugin}. + */ void handleWriter(TransportConnectionWriter w); }