mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 10:49:06 +01:00
Compare commits
257 Commits
41-alias-f
...
priority-e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b4d0a221a3 | ||
|
|
b342759e06 | ||
|
|
93d99b0111 | ||
|
|
61e8d576d2 | ||
|
|
75c37a258e | ||
|
|
e964dae64b | ||
|
|
986d884b40 | ||
|
|
9557afabc6 | ||
|
|
ebe6b0d4c0 | ||
|
|
6e83fb7aef | ||
|
|
7a5ec2af12 | ||
|
|
ce1fde496c | ||
|
|
4b62c51fbf | ||
|
|
226ed3dd73 | ||
|
|
ab07dfb32c | ||
|
|
20c51c1aa4 | ||
|
|
232c2129a7 | ||
|
|
3620edbfc9 | ||
|
|
ad71d69149 | ||
|
|
f73f8ca7e7 | ||
|
|
16c701a71a | ||
|
|
8183b7b26a | ||
|
|
bd48c97eab | ||
|
|
925dc29a1f | ||
|
|
91777fd942 | ||
|
|
fbce8f81c7 | ||
|
|
d7c72c4d68 | ||
|
|
4faf535801 | ||
|
|
526ef7c6d8 | ||
|
|
798dff1a03 | ||
|
|
a4336776c9 | ||
|
|
418451cbd9 | ||
|
|
045fcfc5fa | ||
|
|
ef998577db | ||
|
|
a53345a3c9 | ||
|
|
ed8c09282d | ||
|
|
42197b5b5c | ||
|
|
374fc7035b | ||
|
|
9b796c7cc3 | ||
|
|
532edff642 | ||
|
|
6857252471 | ||
|
|
c229e19452 | ||
|
|
42bca09d16 | ||
|
|
9eacbfa659 | ||
|
|
f14e546dc6 | ||
|
|
684c64a1d9 | ||
|
|
6fdab959b1 | ||
|
|
c8487483ff | ||
|
|
a159b23dc0 | ||
|
|
5070a27a83 | ||
|
|
9ce73a6840 | ||
|
|
6e9928f20f | ||
|
|
b31d61afc5 | ||
|
|
5a99cb93cc | ||
|
|
d0bbebd25e | ||
|
|
4307d26606 | ||
|
|
0089c1ac6d | ||
|
|
2a7aac4930 | ||
|
|
a37b6d81ed | ||
|
|
1d09a6708a | ||
|
|
d3b6f484c8 | ||
|
|
039c6edb66 | ||
|
|
8b9f89eab2 | ||
|
|
1e2c17b170 | ||
|
|
a994966095 | ||
|
|
2bea581654 | ||
|
|
87377666aa | ||
|
|
9d07b2e141 | ||
|
|
5c312b49e2 | ||
|
|
f56efe45cd | ||
|
|
2332a58681 | ||
|
|
8c6dfaa196 | ||
|
|
3cfb04b60d | ||
|
|
e85fbfb952 | ||
|
|
80ee35d926 | ||
|
|
4796902b9c | ||
|
|
149e67c0f7 | ||
|
|
1d5214117f | ||
|
|
b8f248ca9c | ||
|
|
dfb71a03a5 | ||
|
|
961fdc8e72 | ||
|
|
c3d44663cd | ||
|
|
0081472489 | ||
|
|
cdf4f3a24b | ||
|
|
fb1d8e860f | ||
|
|
a3c526ec9a | ||
|
|
dee488d06d | ||
|
|
b29c7d8022 | ||
|
|
0725d207ec | ||
|
|
5a7599a88d | ||
|
|
59cd98db81 | ||
|
|
768488eb04 | ||
|
|
a6b1ad48c3 | ||
|
|
77299a68ed | ||
|
|
5e5705c73b | ||
|
|
e6229a3a13 | ||
|
|
5fbacb4ee4 | ||
|
|
c7f4e976ed | ||
|
|
419f2d966a | ||
|
|
d6c18db9e9 | ||
|
|
8fe49d9961 | ||
|
|
f536cfdab8 | ||
|
|
4d594acad5 | ||
|
|
800dfed5c1 | ||
|
|
54b823e401 | ||
|
|
52ec56d690 | ||
|
|
7b3afcca99 | ||
|
|
a22d03d028 | ||
|
|
d857338ad0 | ||
|
|
a5c9e7c74d | ||
|
|
8a4a343147 | ||
|
|
dcd5e34c6b | ||
|
|
7b22d3b84d | ||
|
|
c8fa23273f | ||
|
|
fbe5df8938 | ||
|
|
008cf95741 | ||
|
|
3eb066a836 | ||
|
|
674b29af25 | ||
|
|
b8ca5ab557 | ||
|
|
6e17709f46 | ||
|
|
726d90145c | ||
|
|
165211eb9b | ||
|
|
868c61e5d6 | ||
|
|
798bb6d4f7 | ||
|
|
bc352a2dc6 | ||
|
|
ce7d6d3db5 | ||
|
|
61276c81d2 | ||
|
|
c09abdb088 | ||
|
|
45a11badd5 | ||
|
|
152ac3df43 | ||
|
|
dd5ad86db8 | ||
|
|
10e9fb308d | ||
|
|
de8e95692a | ||
|
|
d6b52cf4ec | ||
|
|
8a839fb5e4 | ||
|
|
fbf8642edb | ||
|
|
ade6a14342 | ||
|
|
d500ff81c3 | ||
|
|
3053e3cfa7 | ||
|
|
6964a67ca3 | ||
|
|
f4b06e1fb3 | ||
|
|
4db075d643 | ||
|
|
78a8ae6b8e | ||
|
|
7866037d02 | ||
|
|
35716051fb | ||
|
|
6cafea836f | ||
|
|
bd0fd229c6 | ||
|
|
ea05a5c703 | ||
|
|
4103eaf639 | ||
|
|
753a25bc2a | ||
|
|
8f4c3c4528 | ||
|
|
636a7dfe72 | ||
|
|
08e99edd42 | ||
|
|
e28bc475df | ||
|
|
88276a4d44 | ||
|
|
f9987c89df | ||
|
|
2c8cb8301f | ||
|
|
c00ee80f0f | ||
|
|
3bfedfdc3d | ||
|
|
ecb63d1acb | ||
|
|
b24914408d | ||
|
|
5ede63edd5 | ||
|
|
4e523c5fbc | ||
|
|
cf79ed5633 | ||
|
|
0a0a6a6369 | ||
|
|
4784980e7b | ||
|
|
3bfa5e2081 | ||
|
|
f2b09deac4 | ||
|
|
ad4729b2f9 | ||
|
|
50cc0a6815 | ||
|
|
32c8ac6576 | ||
|
|
c12422d949 | ||
|
|
3841713c18 | ||
|
|
79232eb558 | ||
|
|
d02b30e751 | ||
|
|
043662a092 | ||
|
|
efc85fb88f | ||
|
|
8b3983ef9e | ||
|
|
6766fb76b2 | ||
|
|
7f74bd1c38 | ||
|
|
951ee30b95 | ||
|
|
c386a0f5eb | ||
|
|
52c778dce3 | ||
|
|
e846a13f50 | ||
|
|
23e9b119d1 | ||
|
|
e6f380296f | ||
|
|
794fb9686b | ||
|
|
bb22b9db10 | ||
|
|
d4f015d054 | ||
|
|
41e5d8900c | ||
|
|
c3cb966009 | ||
|
|
f964d1ef07 | ||
|
|
cccaeeda6c | ||
|
|
483106e00c | ||
|
|
934f14ef31 | ||
|
|
e3abff5ad8 | ||
|
|
391732b239 | ||
|
|
4738bfdd85 | ||
|
|
be1ca89309 | ||
|
|
866be99179 | ||
|
|
48822e2133 | ||
|
|
6883c5caa9 | ||
|
|
8b709969ab | ||
|
|
fe94b65b3b | ||
|
|
f54df1d787 | ||
|
|
a7e826ccf5 | ||
|
|
845eb3262b | ||
|
|
0a46ad439f | ||
|
|
d14d93ea35 | ||
|
|
12a1cf8f8b | ||
|
|
fb2ab861db | ||
|
|
aa15b68d24 | ||
|
|
7059f376f1 | ||
|
|
9313c191c1 | ||
|
|
7746364ae9 | ||
|
|
7429857b28 | ||
|
|
4db64f51a8 | ||
|
|
78172038ef | ||
|
|
7d0c418877 | ||
|
|
5ae4f8f6cb | ||
|
|
45dd10db9d | ||
|
|
5cc8c268ca | ||
|
|
93a6bf2f52 | ||
|
|
852dd46a1b | ||
|
|
4a42e767d3 | ||
|
|
8547b4dc91 | ||
|
|
f6c8a8cec7 | ||
|
|
db8796049e | ||
|
|
e1f31ad381 | ||
|
|
3a15e47ddd | ||
|
|
cf616905d6 | ||
|
|
d3f774f339 | ||
|
|
6c7c488892 | ||
|
|
3fe7aae97e | ||
|
|
ecf417c93b | ||
|
|
c1785c5b13 | ||
|
|
fb2c321a3d | ||
|
|
6e3adc0874 | ||
|
|
cdbe2a00f5 | ||
|
|
a51dc7e0d5 | ||
|
|
0ee7465429 | ||
|
|
7c202189a2 | ||
|
|
da3b2c1591 | ||
|
|
6c5e8ce4cf | ||
|
|
ca700d8d23 | ||
|
|
db11dad61e | ||
|
|
69e7366226 | ||
|
|
90b7b4e67f | ||
|
|
d29812a42b | ||
|
|
6565172e10 | ||
|
|
7447468ce5 | ||
|
|
2db2a1a208 | ||
|
|
0d7e4feaf2 | ||
|
|
eb3983f6b2 | ||
|
|
e2ce49c30e | ||
|
|
adc6fb2fd5 | ||
|
|
ca6dc33cdd |
@@ -3,7 +3,7 @@
|
|||||||
<module name="briar-headless" />
|
<module name="briar-headless" />
|
||||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||||
<option name="ALTERNATIVE_JRE_PATH" />
|
<option name="ALTERNATIVE_JRE_PATH" />
|
||||||
<option name="PACKAGE_NAME" value="" />
|
<option name="PACKAGE_NAME" value="org.briarproject.briar.headless" />
|
||||||
<option name="MAIN_CLASS_NAME" value="" />
|
<option name="MAIN_CLASS_NAME" value="" />
|
||||||
<option name="METHOD_NAME" value="" />
|
<option name="METHOD_NAME" value="" />
|
||||||
<option name="TEST_OBJECT" value="package" />
|
<option name="TEST_OBJECT" value="package" />
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import com.android.build.gradle.tasks.MergeResources
|
||||||
|
|
||||||
apply plugin: 'com.android.library'
|
apply plugin: 'com.android.library'
|
||||||
apply plugin: 'witness'
|
apply plugin: 'witness'
|
||||||
apply from: 'witness.gradle'
|
apply from: 'witness.gradle'
|
||||||
@@ -9,8 +11,8 @@ android {
|
|||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 14
|
minSdkVersion 14
|
||||||
targetSdkVersion 26
|
targetSdkVersion 26
|
||||||
versionCode 10103
|
versionCode 10105
|
||||||
versionName "1.1.3"
|
versionName "1.1.5"
|
||||||
consumerProguardFiles 'proguard-rules.txt'
|
consumerProguardFiles 'proguard-rules.txt'
|
||||||
|
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
@@ -29,8 +31,9 @@ configurations {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation project(path: ':bramble-core', configuration: 'default')
|
implementation project(path: ':bramble-core', configuration: 'default')
|
||||||
tor 'org.briarproject:tor-android:0.3.4.8@zip'
|
tor 'org.briarproject:tor-android:0.3.4.8@zip'
|
||||||
|
tor 'org.briarproject:obfs4proxy-android:0.0.7@zip'
|
||||||
|
|
||||||
annotationProcessor 'com.google.dagger:dagger-compiler:2.0.2'
|
annotationProcessor 'com.google.dagger:dagger-compiler:2.19'
|
||||||
|
|
||||||
compileOnly 'javax.annotation:jsr250-api:1.0'
|
compileOnly 'javax.annotation:jsr250-api:1.0'
|
||||||
|
|
||||||
@@ -39,13 +42,29 @@ dependencies {
|
|||||||
testImplementation "org.jmock:jmock:2.8.2"
|
testImplementation "org.jmock:jmock:2.8.2"
|
||||||
testImplementation "org.jmock:jmock-junit4:2.8.2"
|
testImplementation "org.jmock:jmock-junit4:2.8.2"
|
||||||
testImplementation "org.jmock:jmock-legacy:2.8.2"
|
testImplementation "org.jmock:jmock-legacy:2.8.2"
|
||||||
testImplementation "org.hamcrest:hamcrest-library:1.3"
|
|
||||||
testImplementation "org.hamcrest:hamcrest-core:1.3"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
project.afterEvaluate {
|
def torBinariesDir = 'src/main/res/raw'
|
||||||
|
|
||||||
|
task cleanTorBinaries {
|
||||||
|
doLast {
|
||||||
|
delete fileTree(torBinariesDir) { include '*.zip' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clean.dependsOn cleanTorBinaries
|
||||||
|
|
||||||
|
task unpackTorBinaries {
|
||||||
|
doLast {
|
||||||
copy {
|
copy {
|
||||||
from configurations.tor.collect { zipTree(it) }
|
from configurations.tor.collect { zipTree(it) }
|
||||||
into 'src/main/res/raw'
|
into torBinariesDir
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
dependsOn cleanTorBinaries
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType(MergeResources) {
|
||||||
|
inputs.dir torBinariesDir
|
||||||
|
dependsOn unpackTorBinaries
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package org.briarproject.bramble;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.battery.AndroidBatteryModule;
|
||||||
|
import org.briarproject.bramble.network.AndroidNetworkModule;
|
||||||
|
|
||||||
|
public interface BrambleAndroidEagerSingletons {
|
||||||
|
|
||||||
|
void inject(AndroidBatteryModule.EagerSingletons init);
|
||||||
|
|
||||||
|
void inject(AndroidNetworkModule.EagerSingletons init);
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.briarproject.bramble;
|
package org.briarproject.bramble;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.battery.AndroidBatteryModule;
|
||||||
import org.briarproject.bramble.network.AndroidNetworkModule;
|
import org.briarproject.bramble.network.AndroidNetworkModule;
|
||||||
import org.briarproject.bramble.plugin.tor.CircumventionModule;
|
import org.briarproject.bramble.plugin.tor.CircumventionModule;
|
||||||
import org.briarproject.bramble.system.AndroidSystemModule;
|
import org.briarproject.bramble.system.AndroidSystemModule;
|
||||||
@@ -7,10 +8,15 @@ import org.briarproject.bramble.system.AndroidSystemModule;
|
|||||||
import dagger.Module;
|
import dagger.Module;
|
||||||
|
|
||||||
@Module(includes = {
|
@Module(includes = {
|
||||||
|
AndroidBatteryModule.class,
|
||||||
AndroidNetworkModule.class,
|
AndroidNetworkModule.class,
|
||||||
AndroidSystemModule.class,
|
AndroidSystemModule.class,
|
||||||
CircumventionModule.class
|
CircumventionModule.class
|
||||||
})
|
})
|
||||||
public class BrambleAndroidModule {
|
public class BrambleAndroidModule {
|
||||||
|
|
||||||
|
public static void initEagerSingletons(BrambleAndroidEagerSingletons c) {
|
||||||
|
c.inject(new AndroidBatteryModule.EagerSingletons());
|
||||||
|
c.inject(new AndroidNetworkModule.EagerSingletons());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
package org.briarproject.bramble.battery;
|
||||||
|
|
||||||
|
import android.app.Application;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.battery.BatteryManager;
|
||||||
|
import org.briarproject.bramble.api.battery.event.BatteryEvent;
|
||||||
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
|
import org.briarproject.bramble.api.lifecycle.Service;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import static android.content.Intent.ACTION_BATTERY_CHANGED;
|
||||||
|
import static android.content.Intent.ACTION_POWER_CONNECTED;
|
||||||
|
import static android.content.Intent.ACTION_POWER_DISCONNECTED;
|
||||||
|
import static android.os.BatteryManager.EXTRA_PLUGGED;
|
||||||
|
import static java.util.logging.Level.INFO;
|
||||||
|
import static java.util.logging.Logger.getLogger;
|
||||||
|
|
||||||
|
class AndroidBatteryManager implements BatteryManager, Service {
|
||||||
|
|
||||||
|
private static final Logger LOG =
|
||||||
|
getLogger(AndroidBatteryManager.class.getName());
|
||||||
|
|
||||||
|
private final Context appContext;
|
||||||
|
private final EventBus eventBus;
|
||||||
|
private final AtomicBoolean used = new AtomicBoolean(false);
|
||||||
|
|
||||||
|
private volatile BroadcastReceiver batteryReceiver = null;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
AndroidBatteryManager(Application app, EventBus eventBus) {
|
||||||
|
this.appContext = app.getApplicationContext();
|
||||||
|
this.eventBus = eventBus;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCharging() {
|
||||||
|
// Get the sticky intent for ACTION_BATTERY_CHANGED
|
||||||
|
IntentFilter filter = new IntentFilter(ACTION_BATTERY_CHANGED);
|
||||||
|
Intent i = appContext.registerReceiver(null, filter);
|
||||||
|
if (i == null) return false;
|
||||||
|
int status = i.getIntExtra(EXTRA_PLUGGED, 0);
|
||||||
|
return status != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startService() {
|
||||||
|
if (used.getAndSet(true)) throw new IllegalStateException();
|
||||||
|
batteryReceiver = new BatteryReceiver();
|
||||||
|
IntentFilter filter = new IntentFilter();
|
||||||
|
filter.addAction(ACTION_POWER_CONNECTED);
|
||||||
|
filter.addAction(ACTION_POWER_DISCONNECTED);
|
||||||
|
appContext.registerReceiver(batteryReceiver, filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stopService() {
|
||||||
|
if (batteryReceiver != null)
|
||||||
|
appContext.unregisterReceiver(batteryReceiver);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class BatteryReceiver extends BroadcastReceiver {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context ctx, Intent i) {
|
||||||
|
String action = i.getAction();
|
||||||
|
if (LOG.isLoggable(INFO)) LOG.info("Received broadcast " + action);
|
||||||
|
if (ACTION_POWER_CONNECTED.equals(action))
|
||||||
|
eventBus.broadcast(new BatteryEvent(true));
|
||||||
|
else if (ACTION_POWER_DISCONNECTED.equals(action))
|
||||||
|
eventBus.broadcast(new BatteryEvent(false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package org.briarproject.bramble.battery;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.battery.BatteryManager;
|
||||||
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import dagger.Module;
|
||||||
|
import dagger.Provides;
|
||||||
|
|
||||||
|
@Module
|
||||||
|
public class AndroidBatteryModule {
|
||||||
|
|
||||||
|
public static class EagerSingletons {
|
||||||
|
@Inject
|
||||||
|
BatteryManager batteryManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
BatteryManager provideBatteryManager(LifecycleManager lifecycleManager,
|
||||||
|
AndroidBatteryManager batteryManager) {
|
||||||
|
lifecycleManager.registerService(batteryManager);
|
||||||
|
return batteryManager;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ package org.briarproject.bramble.network;
|
|||||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||||
import org.briarproject.bramble.api.network.NetworkManager;
|
import org.briarproject.bramble.api.network.NetworkManager;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import dagger.Module;
|
import dagger.Module;
|
||||||
@@ -11,6 +12,11 @@ import dagger.Provides;
|
|||||||
@Module
|
@Module
|
||||||
public class AndroidNetworkModule {
|
public class AndroidNetworkModule {
|
||||||
|
|
||||||
|
public static class EagerSingletons {
|
||||||
|
@Inject
|
||||||
|
NetworkManager networkManager;
|
||||||
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
NetworkManager provideNetworkManager(LifecycleManager lifecycleManager,
|
NetworkManager provideNetworkManager(LifecycleManager lifecycleManager,
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
|||||||
import org.briarproject.bramble.api.system.AndroidExecutor;
|
import org.briarproject.bramble.api.system.AndroidExecutor;
|
||||||
import org.briarproject.bramble.api.system.Clock;
|
import org.briarproject.bramble.api.system.Clock;
|
||||||
import org.briarproject.bramble.util.AndroidUtils;
|
import org.briarproject.bramble.util.AndroidUtils;
|
||||||
|
import org.briarproject.bramble.util.IoUtils;
|
||||||
|
|
||||||
import java.io.Closeable;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -51,7 +51,6 @@ import static android.bluetooth.BluetoothDevice.EXTRA_DEVICE;
|
|||||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
|
||||||
import static org.briarproject.bramble.util.PrivacyUtils.scrubMacAddress;
|
import static org.briarproject.bramble.util.PrivacyUtils.scrubMacAddress;
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@@ -161,11 +160,7 @@ class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
void tryToClose(@Nullable BluetoothServerSocket ss) {
|
void tryToClose(@Nullable BluetoothServerSocket ss) {
|
||||||
try {
|
IoUtils.tryToClose(ss, LOG, WARNING);
|
||||||
if (ss != null) ss.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
logException(LOG, WARNING, e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -195,7 +190,7 @@ class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
|
|||||||
s.connect();
|
s.connect();
|
||||||
return wrapSocket(s);
|
return wrapSocket(s);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
tryToClose(s);
|
IoUtils.tryToClose(s, LOG, WARNING);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -268,14 +263,6 @@ class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
|
|||||||
return addresses;
|
return addresses;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tryToClose(@Nullable Closeable c) {
|
|
||||||
try {
|
|
||||||
if (c != null) c.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
logException(LOG, WARNING, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class BluetoothStateReceiver extends BroadcastReceiver {
|
private class BluetoothStateReceiver extends BroadcastReceiver {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import android.content.pm.PackageManager;
|
|||||||
import android.content.pm.PackageManager.NameNotFoundException;
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.battery.BatteryManager;
|
||||||
import org.briarproject.bramble.api.network.NetworkManager;
|
import org.briarproject.bramble.api.network.NetworkManager;
|
||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||||
@@ -41,17 +42,18 @@ class AndroidTorPlugin extends TorPlugin {
|
|||||||
Context appContext, NetworkManager networkManager,
|
Context appContext, NetworkManager networkManager,
|
||||||
LocationUtils locationUtils, SocketFactory torSocketFactory,
|
LocationUtils locationUtils, SocketFactory torSocketFactory,
|
||||||
Clock clock, ResourceProvider resourceProvider,
|
Clock clock, ResourceProvider resourceProvider,
|
||||||
CircumventionProvider circumventionProvider, Backoff backoff,
|
CircumventionProvider circumventionProvider,
|
||||||
|
BatteryManager batteryManager, Backoff backoff,
|
||||||
DuplexPluginCallback callback, String architecture, int maxLatency,
|
DuplexPluginCallback callback, String architecture, int maxLatency,
|
||||||
int maxIdleTime) {
|
int maxIdleTime) {
|
||||||
super(ioExecutor, networkManager, locationUtils, torSocketFactory,
|
super(ioExecutor, networkManager, locationUtils, torSocketFactory,
|
||||||
clock, resourceProvider, circumventionProvider, backoff,
|
clock, resourceProvider, circumventionProvider, batteryManager,
|
||||||
callback, architecture, maxLatency, maxIdleTime,
|
backoff, callback, architecture, maxLatency, maxIdleTime,
|
||||||
appContext.getDir("tor", MODE_PRIVATE));
|
appContext.getDir("tor", MODE_PRIVATE));
|
||||||
this.appContext = appContext;
|
this.appContext = appContext;
|
||||||
PowerManager pm = (PowerManager)
|
PowerManager pm = (PowerManager)
|
||||||
appContext.getSystemService(POWER_SERVICE);
|
appContext.getSystemService(POWER_SERVICE);
|
||||||
assert pm != null;
|
if (pm == null) throw new AssertionError();
|
||||||
wakeLock = new RenewableWakeLock(pm, scheduler, PARTIAL_WAKE_LOCK,
|
wakeLock = new RenewableWakeLock(pm, scheduler, PARTIAL_WAKE_LOCK,
|
||||||
WAKE_LOCK_TAG, 1, MINUTES);
|
WAKE_LOCK_TAG, 1, MINUTES);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.briarproject.bramble.plugin.tor;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.battery.BatteryManager;
|
||||||
import org.briarproject.bramble.api.event.EventBus;
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
import org.briarproject.bramble.api.network.NetworkManager;
|
import org.briarproject.bramble.api.network.NetworkManager;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
@@ -48,6 +49,7 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
|
|||||||
private final BackoffFactory backoffFactory;
|
private final BackoffFactory backoffFactory;
|
||||||
private final ResourceProvider resourceProvider;
|
private final ResourceProvider resourceProvider;
|
||||||
private final CircumventionProvider circumventionProvider;
|
private final CircumventionProvider circumventionProvider;
|
||||||
|
private final BatteryManager batteryManager;
|
||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
|
|
||||||
public AndroidTorPluginFactory(Executor ioExecutor,
|
public AndroidTorPluginFactory(Executor ioExecutor,
|
||||||
@@ -55,7 +57,8 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
|
|||||||
NetworkManager networkManager, LocationUtils locationUtils,
|
NetworkManager networkManager, LocationUtils locationUtils,
|
||||||
EventBus eventBus, SocketFactory torSocketFactory,
|
EventBus eventBus, SocketFactory torSocketFactory,
|
||||||
BackoffFactory backoffFactory, ResourceProvider resourceProvider,
|
BackoffFactory backoffFactory, ResourceProvider resourceProvider,
|
||||||
CircumventionProvider circumventionProvider, Clock clock) {
|
CircumventionProvider circumventionProvider,
|
||||||
|
BatteryManager batteryManager, Clock clock) {
|
||||||
this.ioExecutor = ioExecutor;
|
this.ioExecutor = ioExecutor;
|
||||||
this.scheduler = scheduler;
|
this.scheduler = scheduler;
|
||||||
this.appContext = appContext;
|
this.appContext = appContext;
|
||||||
@@ -66,6 +69,7 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
|
|||||||
this.backoffFactory = backoffFactory;
|
this.backoffFactory = backoffFactory;
|
||||||
this.resourceProvider = resourceProvider;
|
this.resourceProvider = resourceProvider;
|
||||||
this.circumventionProvider = circumventionProvider;
|
this.circumventionProvider = circumventionProvider;
|
||||||
|
this.batteryManager = batteryManager;
|
||||||
this.clock = clock;
|
this.clock = clock;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,8 +108,8 @@ public class AndroidTorPluginFactory implements DuplexPluginFactory {
|
|||||||
MAX_POLLING_INTERVAL, BACKOFF_BASE);
|
MAX_POLLING_INTERVAL, BACKOFF_BASE);
|
||||||
AndroidTorPlugin plugin = new AndroidTorPlugin(ioExecutor, scheduler,
|
AndroidTorPlugin plugin = new AndroidTorPlugin(ioExecutor, scheduler,
|
||||||
appContext, networkManager, locationUtils, torSocketFactory,
|
appContext, networkManager, locationUtils, torSocketFactory,
|
||||||
clock, resourceProvider, circumventionProvider, backoff,
|
clock, resourceProvider, circumventionProvider, batteryManager,
|
||||||
callback, architecture, MAX_LATENCY, MAX_IDLE_TIME);
|
backoff, callback, architecture, MAX_LATENCY, MAX_IDLE_TIME);
|
||||||
eventBus.addListener(plugin);
|
eventBus.addListener(plugin);
|
||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.briarproject.bramble.system;
|
package org.briarproject.bramble.system;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.bluetooth.BluetoothAdapter;
|
import android.bluetooth.BluetoothAdapter;
|
||||||
import android.bluetooth.BluetoothDevice;
|
import android.bluetooth.BluetoothDevice;
|
||||||
@@ -26,7 +27,7 @@ import static android.provider.Settings.Secure.ANDROID_ID;
|
|||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class AndroidSecureRandomProvider extends LinuxSecureRandomProvider {
|
class AndroidSecureRandomProvider extends UnixSecureRandomProvider {
|
||||||
|
|
||||||
private static final int SEED_LENGTH = 32;
|
private static final int SEED_LENGTH = 32;
|
||||||
|
|
||||||
@@ -37,6 +38,7 @@ class AndroidSecureRandomProvider extends LinuxSecureRandomProvider {
|
|||||||
appContext = app.getApplicationContext();
|
appContext = app.getApplicationContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("HardwareIds")
|
||||||
@Override
|
@Override
|
||||||
protected void writeToEntropyPool(DataOutputStream out) throws IOException {
|
protected void writeToEntropyPool(DataOutputStream out) throws IOException {
|
||||||
super.writeToEntropyPool(out);
|
super.writeToEntropyPool(out);
|
||||||
@@ -49,13 +51,15 @@ class AndroidSecureRandomProvider extends LinuxSecureRandomProvider {
|
|||||||
String id = Settings.Secure.getString(contentResolver, ANDROID_ID);
|
String id = Settings.Secure.getString(contentResolver, ANDROID_ID);
|
||||||
if (id != null) out.writeUTF(id);
|
if (id != null) out.writeUTF(id);
|
||||||
Parcel parcel = Parcel.obtain();
|
Parcel parcel = Parcel.obtain();
|
||||||
WifiManager wm =
|
WifiManager wm = (WifiManager) appContext.getApplicationContext()
|
||||||
(WifiManager) appContext.getSystemService(WIFI_SERVICE);
|
.getSystemService(WIFI_SERVICE);
|
||||||
|
if (wm != null) {
|
||||||
List<WifiConfiguration> configs = wm.getConfiguredNetworks();
|
List<WifiConfiguration> configs = wm.getConfiguredNetworks();
|
||||||
if (configs != null) {
|
if (configs != null) {
|
||||||
for (WifiConfiguration config : configs)
|
for (WifiConfiguration config : configs)
|
||||||
parcel.writeParcelable(config, 0);
|
parcel.writeParcelable(config, 0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter();
|
BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter();
|
||||||
if (bt != null) {
|
if (bt != null) {
|
||||||
for (BluetoothDevice device : bt.getBondedDevices())
|
for (BluetoothDevice device : bt.getBondedDevices())
|
||||||
@@ -77,13 +81,13 @@ class AndroidSecureRandomProvider extends LinuxSecureRandomProvider {
|
|||||||
|
|
||||||
// Based on https://android-developers.googleblog.com/2013/08/some-securerandom-thoughts.html
|
// Based on https://android-developers.googleblog.com/2013/08/some-securerandom-thoughts.html
|
||||||
private void applyOpenSslFix() {
|
private void applyOpenSslFix() {
|
||||||
byte[] seed = new LinuxSecureRandomSpi().engineGenerateSeed(
|
byte[] seed = new UnixSecureRandomSpi().engineGenerateSeed(
|
||||||
SEED_LENGTH);
|
SEED_LENGTH);
|
||||||
try {
|
try {
|
||||||
// Seed the OpenSSL PRNG
|
// Seed the OpenSSL PRNG
|
||||||
Class.forName("org.apache.harmony.xnet.provider.jsse.NativeCrypto")
|
Class.forName("org.apache.harmony.xnet.provider.jsse.NativeCrypto")
|
||||||
.getMethod("RAND_seed", byte[].class)
|
.getMethod("RAND_seed", byte[].class)
|
||||||
.invoke(null, seed);
|
.invoke(null, (Object) seed);
|
||||||
// Mix the output of the Linux PRNG into the OpenSSL PRNG
|
// Mix the output of the Linux PRNG into the OpenSSL PRNG
|
||||||
int bytesRead = (Integer) Class.forName(
|
int bytesRead = (Integer) Class.forName(
|
||||||
"org.apache.harmony.xnet.provider.jsse.NativeCrypto")
|
"org.apache.harmony.xnet.provider.jsse.NativeCrypto")
|
||||||
|
|||||||
@@ -11,15 +11,12 @@ import java.util.ArrayList;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
import static android.content.Context.MODE_PRIVATE;
|
import static android.content.Context.MODE_PRIVATE;
|
||||||
|
import static android.os.Build.VERSION.SDK_INT;
|
||||||
|
|
||||||
public class AndroidUtils {
|
public class AndroidUtils {
|
||||||
|
|
||||||
private static final Logger LOG =
|
|
||||||
Logger.getLogger(AndroidUtils.class.getName());
|
|
||||||
|
|
||||||
// Fake Bluetooth address returned by BluetoothAdapter on API 23 and later
|
// Fake Bluetooth address returned by BluetoothAdapter on API 23 and later
|
||||||
private static final String FAKE_BLUETOOTH_ADDRESS = "02:00:00:00:00:00";
|
private static final String FAKE_BLUETOOTH_ADDRESS = "02:00:00:00:00:00";
|
||||||
|
|
||||||
@@ -28,7 +25,7 @@ public class AndroidUtils {
|
|||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public static Collection<String> getSupportedArchitectures() {
|
public static Collection<String> getSupportedArchitectures() {
|
||||||
List<String> abis = new ArrayList<>();
|
List<String> abis = new ArrayList<>();
|
||||||
if (Build.VERSION.SDK_INT >= 21) {
|
if (SDK_INT >= 21) {
|
||||||
abis.addAll(Arrays.asList(Build.SUPPORTED_ABIS));
|
abis.addAll(Arrays.asList(Build.SUPPORTED_ABIS));
|
||||||
} else {
|
} else {
|
||||||
abis.add(Build.CPU_ABI);
|
abis.add(Build.CPU_ABI);
|
||||||
|
|||||||
@@ -31,16 +31,21 @@ dependencyVerification {
|
|||||||
'com.android.tools:sdklib:26.2.1:sdklib-26.2.1.jar:248df7ad5eac4aeb6f96c394c76760de4b7b89ac056e54d0c21a739368b91b45',
|
'com.android.tools:sdklib:26.2.1:sdklib-26.2.1.jar:248df7ad5eac4aeb6f96c394c76760de4b7b89ac056e54d0c21a739368b91b45',
|
||||||
'com.google.code.findbugs:jsr305:1.3.9:jsr305-1.3.9.jar:905721a0eea90a81534abb7ee6ef4ea2e5e645fa1def0a5cd88402df1b46c9ed',
|
'com.google.code.findbugs:jsr305:1.3.9:jsr305-1.3.9.jar:905721a0eea90a81534abb7ee6ef4ea2e5e645fa1def0a5cd88402df1b46c9ed',
|
||||||
'com.google.code.gson:gson:2.8.0:gson-2.8.0.jar:c6221763bd79c4f1c3dc7f750b5f29a0bb38b367b81314c4f71896e340c40825',
|
'com.google.code.gson:gson:2.8.0:gson-2.8.0.jar:c6221763bd79c4f1c3dc7f750b5f29a0bb38b367b81314c4f71896e340c40825',
|
||||||
'com.google.dagger:dagger-compiler:2.0.2:dagger-compiler-2.0.2.jar:b74bc9de063dd4c6400b232231f2ef5056145b8fbecbf5382012007dd1c071b3',
|
'com.google.dagger:dagger-compiler:2.19:dagger-compiler-2.19.jar:27a4b202a2de908182edb261f8c0a264e08e5e4733d7514bc7fbf0d31da5c0fc',
|
||||||
'com.google.dagger:dagger-producers:2.0-beta:dagger-producers-2.0-beta.jar:99ec15e8a0507ba569e7655bc1165ee5e5ca5aa914b3c8f7e2c2458f724edd6b',
|
'com.google.dagger:dagger-producers:2.19:dagger-producers-2.19.jar:a17663abe0fc38b676026950907d4c5f5e2bf338375415861eaff6e3bdb0b768',
|
||||||
'com.google.dagger:dagger:2.0.2:dagger-2.0.2.jar:84c0282ed8be73a29e0475d639da030b55dee72369e58dd35ae7d4fe6243dcf9',
|
'com.google.dagger:dagger-spi:2.19:dagger-spi-2.19.jar:e7a6379d82c841f6aac2866948ad1eed716528707814602842a8d844ce04e2e1',
|
||||||
|
'com.google.dagger:dagger:2.19:dagger-2.19.jar:514b6f1e0727c6572e1d65cb27e4ae668b7aeaeb93a29515182965265b609939',
|
||||||
'com.google.errorprone:error_prone_annotations:2.0.18:error_prone_annotations-2.0.18.jar:cb4cfad870bf563a07199f3ebea5763f0dec440fcda0b318640b1feaa788656b',
|
'com.google.errorprone:error_prone_annotations:2.0.18:error_prone_annotations-2.0.18.jar:cb4cfad870bf563a07199f3ebea5763f0dec440fcda0b318640b1feaa788656b',
|
||||||
'com.google.guava:guava:18.0:guava-18.0.jar:d664fbfc03d2e5ce9cab2a44fb01f1d0bf9dfebeccc1a473b1f9ea31f79f6f99',
|
'com.google.errorprone:error_prone_annotations:2.1.3:error_prone_annotations-2.1.3.jar:03d0329547c13da9e17c634d1049ea2ead093925e290567e1a364fd6b1fc7ff8',
|
||||||
|
'com.google.errorprone:javac-shaded:9-dev-r4023-3:javac-shaded-9-dev-r4023-3.jar:65bfccf60986c47fbc17c9ebab0be626afc41741e0a6ec7109e0768817a36f30',
|
||||||
|
'com.google.googlejavaformat:google-java-format:1.5:google-java-format-1.5.jar:aa19ad7850fb85178aa22f2fddb163b84d6ce4d0035872f30d4408195ca1144e',
|
||||||
'com.google.guava:guava:23.0:guava-23.0.jar:7baa80df284117e5b945b19b98d367a85ea7b7801bd358ff657946c3bd1b6596',
|
'com.google.guava:guava:23.0:guava-23.0.jar:7baa80df284117e5b945b19b98d367a85ea7b7801bd358ff657946c3bd1b6596',
|
||||||
|
'com.google.guava:guava:25.0-jre:guava-25.0-jre.jar:3fd4341776428c7e0e5c18a7c10de129475b69ab9d30aeafbb5c277bb6074fa9',
|
||||||
'com.google.j2objc:j2objc-annotations:1.1:j2objc-annotations-1.1.jar:40ceb7157feb263949e0f503fe5f71689333a621021aa20ce0d0acee3badaa0f',
|
'com.google.j2objc:j2objc-annotations:1.1:j2objc-annotations-1.1.jar:40ceb7157feb263949e0f503fe5f71689333a621021aa20ce0d0acee3badaa0f',
|
||||||
'com.google.jimfs:jimfs:1.1:jimfs-1.1.jar:c4828e28d7c0a930af9387510b3bada7daa5c04d7c25a75c7b8b081f1c257ddd',
|
'com.google.jimfs:jimfs:1.1:jimfs-1.1.jar:c4828e28d7c0a930af9387510b3bada7daa5c04d7c25a75c7b8b081f1c257ddd',
|
||||||
'com.google.protobuf:protobuf-java:3.4.0:protobuf-java-3.4.0.jar:dce7e66b32456a1b1198da0caff3a8acb71548658391e798c79369241e6490a4',
|
'com.google.protobuf:protobuf-java:3.4.0:protobuf-java-3.4.0.jar:dce7e66b32456a1b1198da0caff3a8acb71548658391e798c79369241e6490a4',
|
||||||
'com.googlecode.json-simple:json-simple:1.1:json-simple-1.1.jar:2d9484f4c649f708f47f9a479465fc729770ee65617dca3011836602264f6439',
|
'com.googlecode.json-simple:json-simple:1.1:json-simple-1.1.jar:2d9484f4c649f708f47f9a479465fc729770ee65617dca3011836602264f6439',
|
||||||
|
'com.squareup:javapoet:1.11.1:javapoet-1.11.1.jar:9cbf2107be499ec6e95afd36b58e3ca122a24166cdd375732e51267d64058e90',
|
||||||
'com.squareup:javawriter:2.5.0:javawriter-2.5.0.jar:fcfb09fb0ea0aa97d3cfe7ea792398081348e468f126b3603cb3803f240197f0',
|
'com.squareup:javawriter:2.5.0:javawriter-2.5.0.jar:fcfb09fb0ea0aa97d3cfe7ea792398081348e468f126b3603cb3803f240197f0',
|
||||||
'com.sun.activation:javax.activation:1.2.0:javax.activation-1.2.0.jar:993302b16cd7056f21e779cc577d175a810bb4900ef73cd8fbf2b50f928ba9ce',
|
'com.sun.activation:javax.activation:1.2.0:javax.activation-1.2.0.jar:993302b16cd7056f21e779cc577d175a810bb4900ef73cd8fbf2b50f928ba9ce',
|
||||||
'com.sun.istack:istack-commons-runtime:2.21:istack-commons-runtime-2.21.jar:c33e67a0807095f02a0e2da139412dd7c4f9cc1a4c054b3e434f96831ba950f4',
|
'com.sun.istack:istack-commons-runtime:2.21:istack-commons-runtime-2.21.jar:c33e67a0807095f02a0e2da139412dd7c4f9cc1a4c054b3e434f96831ba950f4',
|
||||||
@@ -63,7 +68,9 @@ dependencyVerification {
|
|||||||
'org.beanshell:bsh:1.3.0:bsh-1.3.0.jar:9b04edc75d19db54f1b4e8b5355e9364384c6cf71eb0a1b9724c159d779879f8',
|
'org.beanshell:bsh:1.3.0:bsh-1.3.0.jar:9b04edc75d19db54f1b4e8b5355e9364384c6cf71eb0a1b9724c159d779879f8',
|
||||||
'org.bouncycastle:bcpkix-jdk15on:1.56:bcpkix-jdk15on-1.56.jar:7043dee4e9e7175e93e0b36f45b1ec1ecb893c5f755667e8b916eb8dd201c6ca',
|
'org.bouncycastle:bcpkix-jdk15on:1.56:bcpkix-jdk15on-1.56.jar:7043dee4e9e7175e93e0b36f45b1ec1ecb893c5f755667e8b916eb8dd201c6ca',
|
||||||
'org.bouncycastle:bcprov-jdk15on:1.56:bcprov-jdk15on-1.56.jar:963e1ee14f808ffb99897d848ddcdb28fa91ddda867eb18d303e82728f878349',
|
'org.bouncycastle:bcprov-jdk15on:1.56:bcprov-jdk15on-1.56.jar:963e1ee14f808ffb99897d848ddcdb28fa91ddda867eb18d303e82728f878349',
|
||||||
|
'org.briarproject:obfs4proxy-android:0.0.7:obfs4proxy-android-0.0.7.zip:abdfb5d889d848de9bf214f9276abbf454808a505b870819eccc9a9e985bf617',
|
||||||
'org.briarproject:tor-android:0.3.4.8:tor-android-0.3.4.8.zip:989a0352d9d8d8172cd6c2137654e165e5d2beb10ed1211bab3814e224ad1926',
|
'org.briarproject:tor-android:0.3.4.8:tor-android-0.3.4.8.zip:989a0352d9d8d8172cd6c2137654e165e5d2beb10ed1211bab3814e224ad1926',
|
||||||
|
'org.checkerframework:checker-compat-qual:2.5.3:checker-compat-qual-2.5.3.jar:d76b9afea61c7c082908023f0cbc1427fab9abd2df915c8b8a3e7a509bccbc6d',
|
||||||
'org.codehaus.groovy:groovy-all:2.4.12:groovy-all-2.4.12.jar:6a56af4bd48903d56bec62821876cadefafd007360cc6bd0d8f7aa8d72b38be4',
|
'org.codehaus.groovy:groovy-all:2.4.12:groovy-all-2.4.12.jar:6a56af4bd48903d56bec62821876cadefafd007360cc6bd0d8f7aa8d72b38be4',
|
||||||
'org.codehaus.mojo:animal-sniffer-annotations:1.14:animal-sniffer-annotations-1.14.jar:2068320bd6bad744c3673ab048f67e30bef8f518996fa380033556600669905d',
|
'org.codehaus.mojo:animal-sniffer-annotations:1.14:animal-sniffer-annotations-1.14.jar:2068320bd6bad744c3673ab048f67e30bef8f518996fa380033556600669905d',
|
||||||
'org.glassfish.jaxb:jaxb-core:2.2.11:jaxb-core-2.2.11.jar:37bcaee8ebb04362c8352a5bf6221b86967ecdab5164c696b10b9a2bb587b2aa',
|
'org.glassfish.jaxb:jaxb-core:2.2.11:jaxb-core-2.2.11.jar:37bcaee8ebb04362c8352a5bf6221b86967ecdab5164c696b10b9a2bb587b2aa',
|
||||||
|
|||||||
@@ -7,15 +7,13 @@ apply plugin: 'witness'
|
|||||||
apply from: 'witness.gradle'
|
apply from: 'witness.gradle'
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation "com.google.dagger:dagger:2.0.2"
|
implementation "com.google.dagger:dagger:2.19"
|
||||||
implementation 'com.google.code.findbugs:jsr305:3.0.2'
|
implementation 'com.google.code.findbugs:jsr305:3.0.2'
|
||||||
|
|
||||||
testImplementation 'junit:junit:4.12'
|
testImplementation 'junit:junit:4.12'
|
||||||
testImplementation "org.jmock:jmock:2.8.2"
|
testImplementation "org.jmock:jmock:2.8.2"
|
||||||
testImplementation "org.jmock:jmock-junit4:2.8.2"
|
testImplementation "org.jmock:jmock-junit4:2.8.2"
|
||||||
testImplementation "org.jmock:jmock-legacy:2.8.2"
|
testImplementation "org.jmock:jmock-legacy:2.8.2"
|
||||||
testImplementation "org.hamcrest:hamcrest-library:1.3"
|
|
||||||
testImplementation "org.hamcrest:hamcrest-core:1.3"
|
|
||||||
|
|
||||||
signature 'org.codehaus.mojo.signature:java16:1.1@signature'
|
signature 'org.codehaus.mojo.signature:java16:1.1@signature'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package org.briarproject.bramble.api;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
@NotNullByDefault
|
||||||
|
public class Pair<A, B> {
|
||||||
|
|
||||||
|
private final A first;
|
||||||
|
private final B second;
|
||||||
|
|
||||||
|
public Pair(A first, B second) {
|
||||||
|
this.first = first;
|
||||||
|
this.second = second;
|
||||||
|
}
|
||||||
|
|
||||||
|
public A getFirst() {
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
|
||||||
|
public B getSecond() {
|
||||||
|
return second;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package org.briarproject.bramble.api.battery;
|
||||||
|
|
||||||
|
public interface BatteryManager {
|
||||||
|
|
||||||
|
boolean isCharging();
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package org.briarproject.bramble.api.battery.event;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.event.Event;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An event that is broadcast when the device starts or stops charging.
|
||||||
|
*/
|
||||||
|
public class BatteryEvent extends Event {
|
||||||
|
|
||||||
|
private final boolean charging;
|
||||||
|
|
||||||
|
public BatteryEvent(boolean charging) {
|
||||||
|
this.charging = charging;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCharging() {
|
||||||
|
return charging;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package org.briarproject.briar.client;
|
package org.briarproject.bramble.api.client;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.FormatException;
|
import org.briarproject.bramble.api.FormatException;
|
||||||
import org.briarproject.bramble.api.client.ClientHelper;
|
|
||||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||||
import org.briarproject.bramble.api.data.BdfList;
|
import org.briarproject.bramble.api.data.BdfList;
|
||||||
import org.briarproject.bramble.api.data.MetadataParser;
|
import org.briarproject.bramble.api.data.MetadataParser;
|
||||||
@@ -12,7 +11,7 @@ import org.briarproject.bramble.api.db.Transaction;
|
|||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.sync.InvalidMessageException;
|
import org.briarproject.bramble.api.sync.InvalidMessageException;
|
||||||
import org.briarproject.bramble.api.sync.Message;
|
import org.briarproject.bramble.api.sync.Message;
|
||||||
import org.briarproject.bramble.api.sync.ValidationManager.IncomingMessageHook;
|
import org.briarproject.bramble.api.sync.validation.IncomingMessageHook;
|
||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
@@ -62,5 +61,4 @@ public abstract class BdfIncomingMessageHook implements IncomingMessageHook {
|
|||||||
throw new InvalidMessageException(e);
|
throw new InvalidMessageException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -9,7 +9,7 @@ import org.briarproject.bramble.api.sync.Group;
|
|||||||
import org.briarproject.bramble.api.sync.InvalidMessageException;
|
import org.briarproject.bramble.api.sync.InvalidMessageException;
|
||||||
import org.briarproject.bramble.api.sync.Message;
|
import org.briarproject.bramble.api.sync.Message;
|
||||||
import org.briarproject.bramble.api.sync.MessageContext;
|
import org.briarproject.bramble.api.sync.MessageContext;
|
||||||
import org.briarproject.bramble.api.sync.ValidationManager.MessageValidator;
|
import org.briarproject.bramble.api.sync.validation.MessageValidator;
|
||||||
import org.briarproject.bramble.api.system.Clock;
|
import org.briarproject.bramble.api.system.Clock;
|
||||||
|
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import java.util.Collection;
|
|||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import static org.briarproject.bramble.api.contact.PendingContact.PendingContactState.FAILED;
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public interface ContactManager {
|
public interface ContactManager {
|
||||||
|
|
||||||
@@ -52,6 +54,35 @@ public interface ContactManager {
|
|||||||
long timestamp, boolean alice, boolean verified, boolean active)
|
long timestamp, boolean alice, boolean verified, boolean active)
|
||||||
throws DbException;
|
throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the static link that needs to be sent to the contact to be added.
|
||||||
|
*/
|
||||||
|
String getRemoteContactLink();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the given link is syntactically valid.
|
||||||
|
*/
|
||||||
|
boolean isValidRemoteContactLink(String link);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests a new contact to be added via the given {@code link}.
|
||||||
|
*
|
||||||
|
* @param link The link received from the contact we want to add.
|
||||||
|
* @param alias The alias the user has given this contact.
|
||||||
|
* @return A PendingContact representing the contact to be added.
|
||||||
|
*/
|
||||||
|
PendingContact addRemoteContactRequest(String link, String alias);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of {@link PendingContact}s.
|
||||||
|
*/
|
||||||
|
Collection<PendingContact> getPendingContacts();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a {@link PendingContact} that is in state {@link FAILED}.
|
||||||
|
*/
|
||||||
|
void removePendingContact(PendingContact pendingContact);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the contact with the given ID.
|
* Returns the contact with the given ID.
|
||||||
*/
|
*/
|
||||||
@@ -96,6 +127,12 @@ public interface ContactManager {
|
|||||||
void setContactActive(Transaction txn, ContactId c, boolean active)
|
void setContactActive(Transaction txn, ContactId c, boolean active)
|
||||||
throws DbException;
|
throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets an alias name for the contact or unsets it if alias is null.
|
||||||
|
*/
|
||||||
|
void setContactAlias(Transaction txn, ContactId c, @Nullable String alias)
|
||||||
|
throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets an alias name for the contact or unsets it if alias is null.
|
* Sets an alias name for the contact or unsets it if alias is null.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package org.briarproject.bramble.api.contact;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
@NotNullByDefault
|
||||||
|
public class PendingContact {
|
||||||
|
|
||||||
|
public enum PendingContactState {
|
||||||
|
WAITING_FOR_CONNECTION,
|
||||||
|
CONNECTED,
|
||||||
|
ADDING_CONTACT,
|
||||||
|
FAILED
|
||||||
|
}
|
||||||
|
|
||||||
|
private final PendingContactId id;
|
||||||
|
private final String alias;
|
||||||
|
private final PendingContactState state;
|
||||||
|
private final long timestamp;
|
||||||
|
|
||||||
|
public PendingContact(PendingContactId id, String alias,
|
||||||
|
PendingContactState state, long timestamp) {
|
||||||
|
this.id = id;
|
||||||
|
this.alias = alias;
|
||||||
|
this.state = state;
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAlias() {
|
||||||
|
return alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PendingContactState getState() {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTimestamp() {
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return id.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
return o instanceof PendingContact &&
|
||||||
|
id.equals(((PendingContact) o).id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package org.briarproject.bramble.api.contact;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.UniqueId;
|
||||||
|
|
||||||
|
public class PendingContactId extends UniqueId {
|
||||||
|
|
||||||
|
public PendingContactId(byte[] id) {
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package org.briarproject.bramble.api.contact.event;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.contact.PendingContact.PendingContactState;
|
||||||
|
import org.briarproject.bramble.api.contact.PendingContactId;
|
||||||
|
import org.briarproject.bramble.api.event.Event;
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An event that is broadcast when a pending contact's state is changed.
|
||||||
|
*/
|
||||||
|
@Immutable
|
||||||
|
@NotNullByDefault
|
||||||
|
public class PendingContactStateChangedEvent extends Event {
|
||||||
|
|
||||||
|
private final PendingContactId id;
|
||||||
|
private final PendingContactState state;
|
||||||
|
|
||||||
|
public PendingContactStateChangedEvent(PendingContactId id,
|
||||||
|
PendingContactState state) {
|
||||||
|
this.id = id;
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PendingContactId getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PendingContactState getPendingContactState() {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package org.briarproject.bramble.api.data;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.Bytes;
|
||||||
|
import org.briarproject.bramble.api.FormatException;
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
|
||||||
|
import static org.briarproject.bramble.util.StringUtils.toHexString;
|
||||||
|
|
||||||
|
@NotNullByDefault
|
||||||
|
public class BdfStringUtils {
|
||||||
|
|
||||||
|
public static String toString(@Nullable Object o) throws FormatException {
|
||||||
|
return toString(o, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String toString(@Nullable Object o, int indent)
|
||||||
|
throws FormatException {
|
||||||
|
if (o == null || o == NULL_VALUE) return "null";
|
||||||
|
if (o instanceof Boolean) return o.toString();
|
||||||
|
if (o instanceof Number) return o.toString();
|
||||||
|
if (o instanceof String) return "\"" + o + "\"";
|
||||||
|
if (o instanceof Bytes)
|
||||||
|
return "x" + toHexString(((Bytes) o).getBytes());
|
||||||
|
if (o instanceof byte[])
|
||||||
|
return "x" + toHexString((byte[]) o);
|
||||||
|
if (o instanceof List) {
|
||||||
|
List<?> list = (List) o;
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("[\n");
|
||||||
|
int i = 0, size = list.size();
|
||||||
|
for (Object e : list) {
|
||||||
|
indent(sb, indent + 1);
|
||||||
|
sb.append(toString(e, indent + 1));
|
||||||
|
if (i++ < size - 1) sb.append(',');
|
||||||
|
sb.append('\n');
|
||||||
|
}
|
||||||
|
indent(sb, indent);
|
||||||
|
sb.append(']');
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
if (o instanceof Map) {
|
||||||
|
Map<?, ?> map = (Map) o;
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("{\n");
|
||||||
|
int i = 0, size = map.size();
|
||||||
|
for (Entry e : map.entrySet()) {
|
||||||
|
indent(sb, indent + 1);
|
||||||
|
sb.append(toString(e.getKey(), indent + 1));
|
||||||
|
sb.append(": ");
|
||||||
|
sb.append(toString(e.getValue(), indent + 1));
|
||||||
|
if (i++ < size - 1) sb.append(',');
|
||||||
|
sb.append('\n');
|
||||||
|
}
|
||||||
|
indent(sb, indent);
|
||||||
|
sb.append('}');
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
throw new FormatException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void indent(StringBuilder sb, int indent) {
|
||||||
|
for (int i = 0; i < indent; i++) sb.append('\t');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,6 +19,7 @@ import org.briarproject.bramble.api.sync.MessageId;
|
|||||||
import org.briarproject.bramble.api.sync.MessageStatus;
|
import org.briarproject.bramble.api.sync.MessageStatus;
|
||||||
import org.briarproject.bramble.api.sync.Offer;
|
import org.briarproject.bramble.api.sync.Offer;
|
||||||
import org.briarproject.bramble.api.sync.Request;
|
import org.briarproject.bramble.api.sync.Request;
|
||||||
|
import org.briarproject.bramble.api.sync.validation.MessageState;
|
||||||
import org.briarproject.bramble.api.transport.KeySet;
|
import org.briarproject.bramble.api.transport.KeySet;
|
||||||
import org.briarproject.bramble.api.transport.KeySetId;
|
import org.briarproject.bramble.api.transport.KeySetId;
|
||||||
import org.briarproject.bramble.api.transport.TransportKeys;
|
import org.briarproject.bramble.api.transport.TransportKeys;
|
||||||
@@ -28,8 +29,6 @@ import java.util.Map;
|
|||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import static org.briarproject.bramble.api.sync.ValidationManager.State;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encapsulates the database implementation and exposes high-level operations
|
* Encapsulates the database implementation and exposes high-level operations
|
||||||
* to other components.
|
* to other components.
|
||||||
@@ -89,6 +88,14 @@ public interface DatabaseComponent {
|
|||||||
<R, E extends Exception> R transactionWithResult(boolean readOnly,
|
<R, E extends Exception> R transactionWithResult(boolean readOnly,
|
||||||
DbCallable<R, E> task) throws DbException, E;
|
DbCallable<R, E> task) throws DbException, E;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs the given task within a transaction and returns the result of the
|
||||||
|
* task, which may be null.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
<R, E extends Exception> R transactionWithNullableResult(boolean readOnly,
|
||||||
|
NullableDbCallable<R, E> task) throws DbException, E;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores a contact associated with the given local and remote pseudonyms,
|
* Stores a contact associated with the given local and remote pseudonyms,
|
||||||
* and returns an ID for the contact.
|
* and returns an ID for the contact.
|
||||||
@@ -366,12 +373,12 @@ public interface DatabaseComponent {
|
|||||||
/**
|
/**
|
||||||
* Returns the IDs and states of all dependencies of the given message.
|
* Returns the IDs and states of all dependencies of the given message.
|
||||||
* For missing dependencies and dependencies in other groups, the state
|
* For missing dependencies and dependencies in other groups, the state
|
||||||
* {@link State UNKNOWN} is returned.
|
* {@link MessageState UNKNOWN} is returned.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Read-only.
|
* Read-only.
|
||||||
*/
|
*/
|
||||||
Map<MessageId, State> getMessageDependencies(Transaction txn, MessageId m)
|
Map<MessageId, MessageState> getMessageDependencies(Transaction txn,
|
||||||
throws DbException;
|
MessageId m) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the IDs and states of all dependents of the given message.
|
* Returns the IDs and states of all dependents of the given message.
|
||||||
@@ -380,15 +387,16 @@ public interface DatabaseComponent {
|
|||||||
* <p/>
|
* <p/>
|
||||||
* Read-only.
|
* Read-only.
|
||||||
*/
|
*/
|
||||||
Map<MessageId, State> getMessageDependents(Transaction txn, MessageId m)
|
Map<MessageId, MessageState> getMessageDependents(Transaction txn,
|
||||||
throws DbException;
|
MessageId m) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the validation and delivery state of the given message.
|
* Gets the validation and delivery state of the given message.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Read-only.
|
* Read-only.
|
||||||
*/
|
*/
|
||||||
State getMessageState(Transaction txn, MessageId m) throws DbException;
|
MessageState getMessageState(Transaction txn, MessageId m)
|
||||||
|
throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the status of the given delivered message with respect to the
|
* Returns the status of the given delivered message with respect to the
|
||||||
@@ -535,7 +543,7 @@ public interface DatabaseComponent {
|
|||||||
/**
|
/**
|
||||||
* Sets the validation and delivery state of the given message.
|
* Sets the validation and delivery state of the given message.
|
||||||
*/
|
*/
|
||||||
void setMessageState(Transaction txn, MessageId m, State state)
|
void setMessageState(Transaction txn, MessageId m, MessageState state)
|
||||||
throws DbException;
|
throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
package org.briarproject.bramble.api.db;
|
package org.briarproject.bramble.api.db;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
@NotNullByDefault
|
||||||
public interface DbCallable<R, E extends Exception> {
|
public interface DbCallable<R, E extends Exception> {
|
||||||
|
|
||||||
R call(Transaction txn) throws DbException, E;
|
R call(Transaction txn) throws DbException, E;
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
package org.briarproject.bramble.api.db;
|
package org.briarproject.bramble.api.db;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
@NotNullByDefault
|
||||||
public interface DbRunnable<E extends Exception> {
|
public interface DbRunnable<E extends Exception> {
|
||||||
|
|
||||||
void run(Transaction txn) throws DbException, E;
|
void run(Transaction txn) throws DbException, E;
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package org.briarproject.bramble.api.db;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
@NotNullByDefault
|
||||||
|
public interface NullableDbCallable<R, E extends Exception> {
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
R call(Transaction txn) throws DbException, E;
|
||||||
|
}
|
||||||
@@ -10,7 +10,11 @@ import javax.annotation.concurrent.Immutable;
|
|||||||
public class AuthorInfo {
|
public class AuthorInfo {
|
||||||
|
|
||||||
public enum Status {
|
public enum Status {
|
||||||
NONE, ANONYMOUS, UNKNOWN, UNVERIFIED, VERIFIED, OURSELVES
|
NONE, ANONYMOUS, UNKNOWN, UNVERIFIED, VERIFIED, OURSELVES;
|
||||||
|
|
||||||
|
public boolean isContact() {
|
||||||
|
return this == UNVERIFIED || this == VERIFIED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Status status;
|
private final Status status;
|
||||||
@@ -35,4 +39,18 @@ public class AuthorInfo {
|
|||||||
return alias;
|
return alias;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int hashCode = status.ordinal();
|
||||||
|
if (alias != null) hashCode += alias.hashCode();
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (!(o instanceof AuthorInfo)) return false;
|
||||||
|
AuthorInfo info = (AuthorInfo) o;
|
||||||
|
return status == info.status &&
|
||||||
|
(alias == null ? info.alias == null : alias.equals(info.alias));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package org.briarproject.bramble.api.nullsafety;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
@NotNullByDefault
|
||||||
|
public class NullSafety {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stand-in for `Objects.requireNonNull()`.
|
||||||
|
*/
|
||||||
|
public static <T> T requireNonNull(@Nullable T t) {
|
||||||
|
if (t == null) throw new NullPointerException();
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@ public interface TorConstants {
|
|||||||
String PREF_TOR_NETWORK = "network2";
|
String PREF_TOR_NETWORK = "network2";
|
||||||
String PREF_TOR_PORT = "port";
|
String PREF_TOR_PORT = "port";
|
||||||
String PREF_TOR_MOBILE = "useMobileData";
|
String PREF_TOR_MOBILE = "useMobileData";
|
||||||
|
String PREF_TOR_ONLY_WHEN_CHARGING = "onlyWhenCharging";
|
||||||
|
|
||||||
int PREF_TOR_NETWORK_AUTOMATIC = 0;
|
int PREF_TOR_NETWORK_AUTOMATIC = 0;
|
||||||
int PREF_TOR_NETWORK_WITHOUT_BRIDGES = 1;
|
int PREF_TOR_NETWORK_WITHOUT_BRIDGES = 1;
|
||||||
|
|||||||
@@ -1,87 +0,0 @@
|
|||||||
package org.briarproject.bramble.api.sync;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
|
||||||
import org.briarproject.bramble.api.db.Metadata;
|
|
||||||
import org.briarproject.bramble.api.db.Transaction;
|
|
||||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Responsible for managing message validators and passing them messages to
|
|
||||||
* validate.
|
|
||||||
*/
|
|
||||||
@NotNullByDefault
|
|
||||||
public interface ValidationManager {
|
|
||||||
|
|
||||||
enum State {
|
|
||||||
|
|
||||||
UNKNOWN(0), INVALID(1), PENDING(2), DELIVERED(3);
|
|
||||||
|
|
||||||
private final int value;
|
|
||||||
|
|
||||||
State(int value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static State fromValue(int value) {
|
|
||||||
for (State s : values()) if (s.value == value) return s;
|
|
||||||
throw new IllegalArgumentException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers the message validator for the given client. This method
|
|
||||||
* should be called before
|
|
||||||
* {@link LifecycleManager#startServices(SecretKey)}.
|
|
||||||
*/
|
|
||||||
void registerMessageValidator(ClientId c, int majorVersion,
|
|
||||||
MessageValidator v);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers the incoming message hook for the given client. The hook will
|
|
||||||
* be called once for each incoming message that passes validation. This
|
|
||||||
* method should be called before
|
|
||||||
* {@link LifecycleManager#startServices(SecretKey)}.
|
|
||||||
*/
|
|
||||||
void registerIncomingMessageHook(ClientId c, int majorVersion,
|
|
||||||
IncomingMessageHook hook);
|
|
||||||
|
|
||||||
interface MessageValidator {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validates the given message and returns its metadata and
|
|
||||||
* dependencies.
|
|
||||||
*/
|
|
||||||
MessageContext validateMessage(Message m, Group g)
|
|
||||||
throws InvalidMessageException;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IncomingMessageHook {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called once for each incoming message that passes validation.
|
|
||||||
*
|
|
||||||
* @return whether or not this message should be shared
|
|
||||||
* @throws DbException Should only be used for real database errors.
|
|
||||||
* If this is thrown, delivery will be attempted again at next startup,
|
|
||||||
* whereas if an InvalidMessageException is thrown,
|
|
||||||
* the message will be permanently invalidated.
|
|
||||||
* @throws InvalidMessageException for any non-database error
|
|
||||||
* that occurs while handling remotely created data.
|
|
||||||
* This includes errors that occur while handling locally created data
|
|
||||||
* in a context controlled by remotely created data
|
|
||||||
* (for example, parsing the metadata of a dependency
|
|
||||||
* of an incoming message).
|
|
||||||
* Throwing this will delete the incoming message and its metadata
|
|
||||||
* marking it as invalid in the database.
|
|
||||||
* Never rethrow DbException as InvalidMessageException!
|
|
||||||
*/
|
|
||||||
boolean incomingMessage(Transaction txn, Message m, Metadata meta)
|
|
||||||
throws DbException, InvalidMessageException;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -3,11 +3,10 @@ package org.briarproject.bramble.api.sync.event;
|
|||||||
import org.briarproject.bramble.api.event.Event;
|
import org.briarproject.bramble.api.event.Event;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
|
import org.briarproject.bramble.api.sync.validation.MessageState;
|
||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
import static org.briarproject.bramble.api.sync.ValidationManager.State;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An event that is broadcast when a message state changed.
|
* An event that is broadcast when a message state changed.
|
||||||
*/
|
*/
|
||||||
@@ -17,10 +16,10 @@ public class MessageStateChangedEvent extends Event {
|
|||||||
|
|
||||||
private final MessageId messageId;
|
private final MessageId messageId;
|
||||||
private final boolean local;
|
private final boolean local;
|
||||||
private final State state;
|
private final MessageState state;
|
||||||
|
|
||||||
public MessageStateChangedEvent(MessageId messageId, boolean local,
|
public MessageStateChangedEvent(MessageId messageId, boolean local,
|
||||||
State state) {
|
MessageState state) {
|
||||||
this.messageId = messageId;
|
this.messageId = messageId;
|
||||||
this.local = local;
|
this.local = local;
|
||||||
this.state = state;
|
this.state = state;
|
||||||
@@ -34,7 +33,7 @@ public class MessageStateChangedEvent extends Event {
|
|||||||
return local;
|
return local;
|
||||||
}
|
}
|
||||||
|
|
||||||
public State getState() {
|
public MessageState getState() {
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package org.briarproject.bramble.api.sync.validation;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
|
import org.briarproject.bramble.api.db.Metadata;
|
||||||
|
import org.briarproject.bramble.api.db.Transaction;
|
||||||
|
import org.briarproject.bramble.api.sync.InvalidMessageException;
|
||||||
|
import org.briarproject.bramble.api.sync.Message;
|
||||||
|
|
||||||
|
public interface IncomingMessageHook {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called once for each incoming message that passes validation.
|
||||||
|
*
|
||||||
|
* @return whether or not this message should be shared
|
||||||
|
* @throws DbException Should only be used for real database errors.
|
||||||
|
* If this is thrown, delivery will be attempted again at next startup,
|
||||||
|
* whereas if an InvalidMessageException is thrown,
|
||||||
|
* the message will be permanently invalidated.
|
||||||
|
* @throws InvalidMessageException for any non-database error
|
||||||
|
* that occurs while handling remotely created data.
|
||||||
|
* This includes errors that occur while handling locally created data
|
||||||
|
* in a context controlled by remotely created data
|
||||||
|
* (for example, parsing the metadata of a dependency
|
||||||
|
* of an incoming message).
|
||||||
|
* Throwing this will delete the incoming message and its metadata
|
||||||
|
* marking it as invalid in the database.
|
||||||
|
* Never rethrow DbException as InvalidMessageException!
|
||||||
|
*/
|
||||||
|
boolean incomingMessage(Transaction txn, Message m, Metadata meta)
|
||||||
|
throws DbException, InvalidMessageException;
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package org.briarproject.bramble.api.sync.validation;
|
||||||
|
|
||||||
|
public enum MessageState {
|
||||||
|
|
||||||
|
UNKNOWN(0), INVALID(1), PENDING(2), DELIVERED(3);
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
MessageState(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MessageState fromValue(int value) {
|
||||||
|
for (MessageState s : values()) if (s.value == value) return s;
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package org.briarproject.bramble.api.sync.validation;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.sync.Group;
|
||||||
|
import org.briarproject.bramble.api.sync.InvalidMessageException;
|
||||||
|
import org.briarproject.bramble.api.sync.Message;
|
||||||
|
import org.briarproject.bramble.api.sync.MessageContext;
|
||||||
|
|
||||||
|
public interface MessageValidator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the given message and returns its metadata and
|
||||||
|
* dependencies.
|
||||||
|
*/
|
||||||
|
MessageContext validateMessage(Message m, Group g)
|
||||||
|
throws InvalidMessageException;
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package org.briarproject.bramble.api.sync.validation;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||||
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.bramble.api.sync.ClientId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Responsible for managing message validators and passing them messages to
|
||||||
|
* validate.
|
||||||
|
*/
|
||||||
|
@NotNullByDefault
|
||||||
|
public interface ValidationManager {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers the {@link MessageValidator} for the given client. This method
|
||||||
|
* should be called before
|
||||||
|
* {@link LifecycleManager#startServices(SecretKey)}.
|
||||||
|
*/
|
||||||
|
void registerMessageValidator(ClientId c, int majorVersion,
|
||||||
|
MessageValidator v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers the {@link IncomingMessageHook} for the given client. The hook
|
||||||
|
* will be called once for each incoming message that passes validation.
|
||||||
|
* This method should be called before
|
||||||
|
* {@link LifecycleManager#startServices(SecretKey)}.
|
||||||
|
*/
|
||||||
|
void registerIncomingMessageHook(ClientId c, int majorVersion,
|
||||||
|
IncomingMessageHook hook);
|
||||||
|
}
|
||||||
@@ -38,6 +38,13 @@ public interface ClientVersioningManager {
|
|||||||
Visibility getClientVisibility(Transaction txn, ContactId contactId,
|
Visibility getClientVisibility(Transaction txn, ContactId contactId,
|
||||||
ClientId clientId, int majorVersion) throws DbException;
|
ClientId clientId, int majorVersion) throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the minor version of the given client that is supported by the
|
||||||
|
* given contact, or -1 if the contact does not support the client.
|
||||||
|
*/
|
||||||
|
int getClientMinorVersion(Transaction txn, ContactId contactId,
|
||||||
|
ClientId clientId, int majorVersion) throws DbException;
|
||||||
|
|
||||||
interface ClientVersioningHook {
|
interface ClientVersioningHook {
|
||||||
|
|
||||||
void onClientVisibilityChanging(Transaction txn, Contact c,
|
void onClientVisibilityChanging(Transaction txn, Contact c,
|
||||||
|
|||||||
@@ -8,12 +8,15 @@ import java.io.File;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.net.ServerSocket;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class IoUtils {
|
public class IoUtils {
|
||||||
@@ -54,16 +57,35 @@ public class IoUtils {
|
|||||||
out.flush();
|
out.flush();
|
||||||
out.close();
|
out.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
tryToClose(in);
|
tryToClose(in, LOG, WARNING);
|
||||||
tryToClose(out);
|
tryToClose(out, LOG, WARNING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void tryToClose(@Nullable Closeable c) {
|
public static void tryToClose(@Nullable Closeable c, Logger logger,
|
||||||
|
Level level) {
|
||||||
try {
|
try {
|
||||||
if (c != null) c.close();
|
if (c != null) c.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// We did our best
|
logException(logger, level, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void tryToClose(@Nullable Socket s, Logger logger,
|
||||||
|
Level level) {
|
||||||
|
try {
|
||||||
|
if (s != null) s.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
logException(logger, level, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void tryToClose(@Nullable ServerSocket ss, Logger logger,
|
||||||
|
Level level) {
|
||||||
|
try {
|
||||||
|
if (ss != null) ss.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
logException(logger, level, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,6 @@ public class OsUtils {
|
|||||||
@Nullable
|
@Nullable
|
||||||
private static final String os = System.getProperty("os.name");
|
private static final String os = System.getProperty("os.name");
|
||||||
@Nullable
|
@Nullable
|
||||||
private static final String version = System.getProperty("os.version");
|
|
||||||
@Nullable
|
|
||||||
private static final String vendor = System.getProperty("java.vendor");
|
private static final String vendor = System.getProperty("java.vendor");
|
||||||
|
|
||||||
public static boolean isWindows() {
|
public static boolean isWindows() {
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public class StringUtils {
|
|||||||
try {
|
try {
|
||||||
return s.getBytes("UTF-8");
|
return s.getBytes("UTF-8");
|
||||||
} catch (UnsupportedEncodingException e) {
|
} catch (UnsupportedEncodingException e) {
|
||||||
throw new RuntimeException(e);
|
throw new AssertionError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ public class StringUtils {
|
|||||||
try {
|
try {
|
||||||
return decoder.decode(buffer).toString();
|
return decoder.decode(buffer).toString();
|
||||||
} catch (CharacterCodingException e) {
|
} catch (CharacterCodingException e) {
|
||||||
throw new RuntimeException(e);
|
throw new AssertionError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package org.briarproject.bramble.api.identity;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.test.BrambleTestCase;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.briarproject.bramble.api.identity.AuthorInfo.Status.NONE;
|
||||||
|
import static org.briarproject.bramble.api.identity.AuthorInfo.Status.VERIFIED;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotEquals;
|
||||||
|
|
||||||
|
public class AuthorInfoTest extends BrambleTestCase {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEquals() {
|
||||||
|
assertEquals(
|
||||||
|
new AuthorInfo(NONE),
|
||||||
|
new AuthorInfo(NONE, null)
|
||||||
|
);
|
||||||
|
assertEquals(
|
||||||
|
new AuthorInfo(NONE, "test"),
|
||||||
|
new AuthorInfo(NONE, "test")
|
||||||
|
);
|
||||||
|
|
||||||
|
assertNotEquals(
|
||||||
|
new AuthorInfo(NONE),
|
||||||
|
new AuthorInfo(VERIFIED)
|
||||||
|
);
|
||||||
|
assertNotEquals(
|
||||||
|
new AuthorInfo(NONE, "test"),
|
||||||
|
new AuthorInfo(NONE)
|
||||||
|
);
|
||||||
|
assertNotEquals(
|
||||||
|
new AuthorInfo(NONE),
|
||||||
|
new AuthorInfo(NONE, "test")
|
||||||
|
);
|
||||||
|
assertNotEquals(
|
||||||
|
new AuthorInfo(NONE, "a"),
|
||||||
|
new AuthorInfo(NONE, "b")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@ dependencyVerification {
|
|||||||
verify = [
|
verify = [
|
||||||
'cglib:cglib:3.2.0:cglib-3.2.0.jar:adb13bab79712ad6bdf1bd59f2a3918018a8016e722e8a357065afb9e6690861',
|
'cglib:cglib:3.2.0:cglib-3.2.0.jar:adb13bab79712ad6bdf1bd59f2a3918018a8016e722e8a357065afb9e6690861',
|
||||||
'com.google.code.findbugs:jsr305:3.0.2:jsr305-3.0.2.jar:766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7',
|
'com.google.code.findbugs:jsr305:3.0.2:jsr305-3.0.2.jar:766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7',
|
||||||
'com.google.dagger:dagger:2.0.2:dagger-2.0.2.jar:84c0282ed8be73a29e0475d639da030b55dee72369e58dd35ae7d4fe6243dcf9',
|
'com.google.dagger:dagger:2.19:dagger-2.19.jar:514b6f1e0727c6572e1d65cb27e4ae668b7aeaeb93a29515182965265b609939',
|
||||||
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
|
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
|
||||||
'junit:junit:4.12:junit-4.12.jar:59721f0805e223d84b90677887d9ff567dc534d7c502ca903c0c2b17f05c116a',
|
'junit:junit:4.12:junit-4.12.jar:59721f0805e223d84b90677887d9ff567dc534d7c502ca903c0c2b17f05c116a',
|
||||||
'org.apache.ant:ant-launcher:1.9.4:ant-launcher-1.9.4.jar:7bccea20b41801ca17bcbc909a78c835d0f443f12d639c77bd6ae3d05861608d',
|
'org.apache.ant:ant-launcher:1.9.4:ant-launcher-1.9.4.jar:7bccea20b41801ca17bcbc909a78c835d0f443f12d639c77bd6ae3d05861608d',
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ sourceCompatibility = 1.8
|
|||||||
targetCompatibility = 1.8
|
targetCompatibility = 1.8
|
||||||
|
|
||||||
apply plugin: 'ru.vyarus.animalsniffer'
|
apply plugin: 'ru.vyarus.animalsniffer'
|
||||||
apply plugin: 'net.ltgt.apt'
|
|
||||||
apply plugin: 'idea'
|
apply plugin: 'idea'
|
||||||
apply plugin: 'witness'
|
apply plugin: 'witness'
|
||||||
apply from: 'witness.gradle'
|
apply from: 'witness.gradle'
|
||||||
|
apply from: '../dagger.gradle'
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation project(path: ':bramble-api', configuration: 'default')
|
implementation project(path: ':bramble-api', configuration: 'default')
|
||||||
@@ -17,7 +17,7 @@ dependencies {
|
|||||||
implementation 'org.whispersystems:curve25519-java:0.5.0'
|
implementation 'org.whispersystems:curve25519-java:0.5.0'
|
||||||
implementation 'org.briarproject:jtorctl:0.3'
|
implementation 'org.briarproject:jtorctl:0.3'
|
||||||
|
|
||||||
apt 'com.google.dagger:dagger-compiler:2.0.2'
|
annotationProcessor 'com.google.dagger:dagger-compiler:2.19'
|
||||||
|
|
||||||
testImplementation project(path: ':bramble-api', configuration: 'testOutput')
|
testImplementation project(path: ':bramble-api', configuration: 'testOutput')
|
||||||
testImplementation 'org.hsqldb:hsqldb:2.3.5' // The last version that supports Java 1.6
|
testImplementation 'org.hsqldb:hsqldb:2.3.5' // The last version that supports Java 1.6
|
||||||
@@ -25,10 +25,8 @@ dependencies {
|
|||||||
testImplementation "org.jmock:jmock:2.8.2"
|
testImplementation "org.jmock:jmock:2.8.2"
|
||||||
testImplementation "org.jmock:jmock-junit4:2.8.2"
|
testImplementation "org.jmock:jmock-junit4:2.8.2"
|
||||||
testImplementation "org.jmock:jmock-legacy:2.8.2"
|
testImplementation "org.jmock:jmock-legacy:2.8.2"
|
||||||
testImplementation "org.hamcrest:hamcrest-library:1.3"
|
|
||||||
testImplementation "org.hamcrest:hamcrest-core:1.3"
|
|
||||||
|
|
||||||
testApt 'com.google.dagger:dagger-compiler:2.0.2'
|
testAnnotationProcessor 'com.google.dagger:dagger-compiler:2.19'
|
||||||
|
|
||||||
signature 'org.codehaus.mojo.signature:java16:1.1@signature'
|
signature 'org.codehaus.mojo.signature:java16:1.1@signature'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import org.briarproject.bramble.lifecycle.LifecycleModule;
|
|||||||
import org.briarproject.bramble.plugin.PluginModule;
|
import org.briarproject.bramble.plugin.PluginModule;
|
||||||
import org.briarproject.bramble.properties.PropertiesModule;
|
import org.briarproject.bramble.properties.PropertiesModule;
|
||||||
import org.briarproject.bramble.reporting.ReportingModule;
|
import org.briarproject.bramble.reporting.ReportingModule;
|
||||||
import org.briarproject.bramble.sync.SyncModule;
|
import org.briarproject.bramble.sync.validation.ValidationModule;
|
||||||
import org.briarproject.bramble.system.SystemModule;
|
import org.briarproject.bramble.system.SystemModule;
|
||||||
import org.briarproject.bramble.transport.TransportModule;
|
import org.briarproject.bramble.transport.TransportModule;
|
||||||
import org.briarproject.bramble.versioning.VersioningModule;
|
import org.briarproject.bramble.versioning.VersioningModule;
|
||||||
@@ -31,11 +31,11 @@ public interface BrambleCoreEagerSingletons {
|
|||||||
|
|
||||||
void inject(ReportingModule.EagerSingletons init);
|
void inject(ReportingModule.EagerSingletons init);
|
||||||
|
|
||||||
void inject(SyncModule.EagerSingletons init);
|
|
||||||
|
|
||||||
void inject(SystemModule.EagerSingletons init);
|
void inject(SystemModule.EagerSingletons init);
|
||||||
|
|
||||||
void inject(TransportModule.EagerSingletons init);
|
void inject(TransportModule.EagerSingletons init);
|
||||||
|
|
||||||
|
void inject(ValidationModule.EagerSingletons init);
|
||||||
|
|
||||||
void inject(VersioningModule.EagerSingletons init);
|
void inject(VersioningModule.EagerSingletons init);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import org.briarproject.bramble.reporting.ReportingModule;
|
|||||||
import org.briarproject.bramble.settings.SettingsModule;
|
import org.briarproject.bramble.settings.SettingsModule;
|
||||||
import org.briarproject.bramble.socks.SocksModule;
|
import org.briarproject.bramble.socks.SocksModule;
|
||||||
import org.briarproject.bramble.sync.SyncModule;
|
import org.briarproject.bramble.sync.SyncModule;
|
||||||
|
import org.briarproject.bramble.sync.validation.ValidationModule;
|
||||||
import org.briarproject.bramble.system.SystemModule;
|
import org.briarproject.bramble.system.SystemModule;
|
||||||
import org.briarproject.bramble.transport.TransportModule;
|
import org.briarproject.bramble.transport.TransportModule;
|
||||||
import org.briarproject.bramble.versioning.VersioningModule;
|
import org.briarproject.bramble.versioning.VersioningModule;
|
||||||
@@ -47,6 +48,7 @@ import dagger.Module;
|
|||||||
SyncModule.class,
|
SyncModule.class,
|
||||||
SystemModule.class,
|
SystemModule.class,
|
||||||
TransportModule.class,
|
TransportModule.class,
|
||||||
|
ValidationModule.class,
|
||||||
VersioningModule.class
|
VersioningModule.class
|
||||||
})
|
})
|
||||||
public class BrambleCoreModule {
|
public class BrambleCoreModule {
|
||||||
@@ -60,9 +62,9 @@ public class BrambleCoreModule {
|
|||||||
c.inject(new PluginModule.EagerSingletons());
|
c.inject(new PluginModule.EagerSingletons());
|
||||||
c.inject(new PropertiesModule.EagerSingletons());
|
c.inject(new PropertiesModule.EagerSingletons());
|
||||||
c.inject(new ReportingModule.EagerSingletons());
|
c.inject(new ReportingModule.EagerSingletons());
|
||||||
c.inject(new SyncModule.EagerSingletons());
|
|
||||||
c.inject(new SystemModule.EagerSingletons());
|
c.inject(new SystemModule.EagerSingletons());
|
||||||
c.inject(new TransportModule.EagerSingletons());
|
c.inject(new TransportModule.EagerSingletons());
|
||||||
|
c.inject(new ValidationModule.EagerSingletons());
|
||||||
c.inject(new VersioningModule.EagerSingletons());
|
c.inject(new VersioningModule.EagerSingletons());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package org.briarproject.bramble;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.Queue;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
import javax.annotation.concurrent.GuardedBy;
|
||||||
|
|
||||||
|
@NotNullByDefault
|
||||||
|
public class PriorityExecutor {
|
||||||
|
|
||||||
|
private final Object lock = new Object();
|
||||||
|
private final Executor delegate, high, low;
|
||||||
|
@GuardedBy("lock")
|
||||||
|
private final Queue<Runnable> highQueue = new LinkedList<>();
|
||||||
|
@GuardedBy("lock")
|
||||||
|
private final Queue<Runnable> lowQueue = new LinkedList<>();
|
||||||
|
|
||||||
|
@GuardedBy("lock")
|
||||||
|
private boolean isTaskRunning = false;
|
||||||
|
|
||||||
|
public PriorityExecutor(Executor delegate) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
high = r -> submit(r, true);
|
||||||
|
low = r -> submit(r, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Executor getHighPriorityExecutor() {
|
||||||
|
return high;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Executor getLowPriorityExecutor() {
|
||||||
|
return low;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void submit(Runnable r, boolean isHighPriority) {
|
||||||
|
Runnable wrapped = () -> {
|
||||||
|
try {
|
||||||
|
r.run();
|
||||||
|
} finally {
|
||||||
|
scheduleNext();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
synchronized (lock) {
|
||||||
|
if (!isTaskRunning && highQueue.isEmpty() &&
|
||||||
|
(isHighPriority || lowQueue.isEmpty())) {
|
||||||
|
isTaskRunning = true;
|
||||||
|
delegate.execute(wrapped);
|
||||||
|
} else if (isHighPriority) {
|
||||||
|
highQueue.add(wrapped);
|
||||||
|
} else {
|
||||||
|
lowQueue.add(wrapped);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void scheduleNext() {
|
||||||
|
synchronized (lock) {
|
||||||
|
Runnable next = highQueue.poll();
|
||||||
|
if (next == null) next = lowQueue.poll();
|
||||||
|
if (next == null) isTaskRunning = false;
|
||||||
|
else delegate.execute(next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package org.briarproject.bramble.battery;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.battery.BatteryManager;
|
||||||
|
|
||||||
|
import dagger.Module;
|
||||||
|
import dagger.Provides;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a default implementation of {@link BatteryManager} for systems
|
||||||
|
* without batteries.
|
||||||
|
*/
|
||||||
|
@Module
|
||||||
|
public class DefaultBatteryManagerModule {
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
BatteryManager provideBatteryManager() {
|
||||||
|
return () -> false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -82,13 +82,7 @@ class ClientHelperImpl implements ClientHelper {
|
|||||||
@Override
|
@Override
|
||||||
public void addLocalMessage(Message m, BdfDictionary metadata,
|
public void addLocalMessage(Message m, BdfDictionary metadata,
|
||||||
boolean shared) throws DbException, FormatException {
|
boolean shared) throws DbException, FormatException {
|
||||||
Transaction txn = db.startTransaction(false);
|
db.transaction(false, txn -> addLocalMessage(txn, m, metadata, shared));
|
||||||
try {
|
|
||||||
addLocalMessage(txn, m, metadata, shared);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -113,15 +107,7 @@ class ClientHelperImpl implements ClientHelper {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Message getMessage(MessageId m) throws DbException {
|
public Message getMessage(MessageId m) throws DbException {
|
||||||
Message message;
|
return db.transactionWithResult(true, txn -> getMessage(txn, m));
|
||||||
Transaction txn = db.startTransaction(true);
|
|
||||||
try {
|
|
||||||
message = getMessage(txn, m);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
return message;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -132,15 +118,7 @@ class ClientHelperImpl implements ClientHelper {
|
|||||||
@Override
|
@Override
|
||||||
public BdfList getMessageAsList(MessageId m) throws DbException,
|
public BdfList getMessageAsList(MessageId m) throws DbException,
|
||||||
FormatException {
|
FormatException {
|
||||||
BdfList list;
|
return db.transactionWithResult(true, txn -> getMessageAsList(txn, m));
|
||||||
Transaction txn = db.startTransaction(true);
|
|
||||||
try {
|
|
||||||
list = getMessageAsList(txn, m);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -152,15 +130,8 @@ class ClientHelperImpl implements ClientHelper {
|
|||||||
@Override
|
@Override
|
||||||
public BdfDictionary getGroupMetadataAsDictionary(GroupId g)
|
public BdfDictionary getGroupMetadataAsDictionary(GroupId g)
|
||||||
throws DbException, FormatException {
|
throws DbException, FormatException {
|
||||||
BdfDictionary dictionary;
|
return db.transactionWithResult(true, txn ->
|
||||||
Transaction txn = db.startTransaction(true);
|
getGroupMetadataAsDictionary(txn, g));
|
||||||
try {
|
|
||||||
dictionary = getGroupMetadataAsDictionary(txn, g);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
return dictionary;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -173,15 +144,8 @@ class ClientHelperImpl implements ClientHelper {
|
|||||||
@Override
|
@Override
|
||||||
public BdfDictionary getMessageMetadataAsDictionary(MessageId m)
|
public BdfDictionary getMessageMetadataAsDictionary(MessageId m)
|
||||||
throws DbException, FormatException {
|
throws DbException, FormatException {
|
||||||
BdfDictionary dictionary;
|
return db.transactionWithResult(true, txn ->
|
||||||
Transaction txn = db.startTransaction(true);
|
getMessageMetadataAsDictionary(txn, m));
|
||||||
try {
|
|
||||||
dictionary = getMessageMetadataAsDictionary(txn, m);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
return dictionary;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -194,15 +158,8 @@ class ClientHelperImpl implements ClientHelper {
|
|||||||
@Override
|
@Override
|
||||||
public Map<MessageId, BdfDictionary> getMessageMetadataAsDictionary(
|
public Map<MessageId, BdfDictionary> getMessageMetadataAsDictionary(
|
||||||
GroupId g) throws DbException, FormatException {
|
GroupId g) throws DbException, FormatException {
|
||||||
Map<MessageId, BdfDictionary> map;
|
return db.transactionWithResult(true, txn ->
|
||||||
Transaction txn = db.startTransaction(true);
|
getMessageMetadataAsDictionary(txn, g));
|
||||||
try {
|
|
||||||
map = getMessageMetadataAsDictionary(txn, g);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -219,15 +176,8 @@ class ClientHelperImpl implements ClientHelper {
|
|||||||
public Map<MessageId, BdfDictionary> getMessageMetadataAsDictionary(
|
public Map<MessageId, BdfDictionary> getMessageMetadataAsDictionary(
|
||||||
GroupId g, BdfDictionary query) throws DbException,
|
GroupId g, BdfDictionary query) throws DbException,
|
||||||
FormatException {
|
FormatException {
|
||||||
Map<MessageId, BdfDictionary> map;
|
return db.transactionWithResult(true, txn ->
|
||||||
Transaction txn = db.startTransaction(true);
|
getMessageMetadataAsDictionary(txn, g, query));
|
||||||
try {
|
|
||||||
map = getMessageMetadataAsDictionary(txn, g, query);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -245,13 +195,7 @@ class ClientHelperImpl implements ClientHelper {
|
|||||||
@Override
|
@Override
|
||||||
public void mergeGroupMetadata(GroupId g, BdfDictionary metadata)
|
public void mergeGroupMetadata(GroupId g, BdfDictionary metadata)
|
||||||
throws DbException, FormatException {
|
throws DbException, FormatException {
|
||||||
Transaction txn = db.startTransaction(false);
|
db.transaction(false, txn -> mergeGroupMetadata(txn, g, metadata));
|
||||||
try {
|
|
||||||
mergeGroupMetadata(txn, g, metadata);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -263,13 +207,7 @@ class ClientHelperImpl implements ClientHelper {
|
|||||||
@Override
|
@Override
|
||||||
public void mergeMessageMetadata(MessageId m, BdfDictionary metadata)
|
public void mergeMessageMetadata(MessageId m, BdfDictionary metadata)
|
||||||
throws DbException, FormatException {
|
throws DbException, FormatException {
|
||||||
Transaction txn = db.startTransaction(false);
|
db.transaction(false, txn -> mergeMessageMetadata(txn, m, metadata));
|
||||||
try {
|
|
||||||
mergeMessageMetadata(txn, m, metadata);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import org.briarproject.bramble.api.data.BdfList;
|
|||||||
import org.briarproject.bramble.api.db.ContactExistsException;
|
import org.briarproject.bramble.api.db.ContactExistsException;
|
||||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.db.Transaction;
|
|
||||||
import org.briarproject.bramble.api.identity.Author;
|
import org.briarproject.bramble.api.identity.Author;
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
@@ -158,7 +157,8 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
|
|||||||
streamWriterFactory.createContactExchangeStreamWriter(out,
|
streamWriterFactory.createContactExchangeStreamWriter(out,
|
||||||
alice ? aliceHeaderKey : bobHeaderKey);
|
alice ? aliceHeaderKey : bobHeaderKey);
|
||||||
RecordWriter recordWriter =
|
RecordWriter recordWriter =
|
||||||
recordWriterFactory.createRecordWriter(streamWriter.getOutputStream());
|
recordWriterFactory
|
||||||
|
.createRecordWriter(streamWriter.getOutputStream());
|
||||||
|
|
||||||
// Derive the nonces to be signed
|
// Derive the nonces to be signed
|
||||||
byte[] aliceNonce = crypto.mac(ALICE_NONCE_LABEL, masterSecret,
|
byte[] aliceNonce = crypto.mac(ALICE_NONCE_LABEL, masterSecret,
|
||||||
@@ -287,19 +287,14 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
|
|||||||
private ContactId addContact(Author remoteAuthor, long timestamp,
|
private ContactId addContact(Author remoteAuthor, long timestamp,
|
||||||
Map<TransportId, TransportProperties> remoteProperties)
|
Map<TransportId, TransportProperties> remoteProperties)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
ContactId contactId;
|
return db.transactionWithResult(false, txn -> {
|
||||||
Transaction txn = db.startTransaction(false);
|
ContactId contactId = contactManager.addContact(txn, remoteAuthor,
|
||||||
try {
|
|
||||||
contactId = contactManager.addContact(txn, remoteAuthor,
|
|
||||||
localAuthor.getId(), masterSecret, timestamp, alice,
|
localAuthor.getId(), masterSecret, timestamp, alice,
|
||||||
true, true);
|
true, true);
|
||||||
transportPropertyManager.addRemoteProperties(txn, contactId,
|
transportPropertyManager.addRemoteProperties(txn, contactId,
|
||||||
remoteProperties);
|
remoteProperties);
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
return contactId;
|
return contactId;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tryToClose(DuplexTransportConnection conn) {
|
private void tryToClose(DuplexTransportConnection conn) {
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package org.briarproject.bramble.contact;
|
|||||||
import org.briarproject.bramble.api.contact.Contact;
|
import org.briarproject.bramble.api.contact.Contact;
|
||||||
import org.briarproject.bramble.api.contact.ContactId;
|
import org.briarproject.bramble.api.contact.ContactId;
|
||||||
import org.briarproject.bramble.api.contact.ContactManager;
|
import org.briarproject.bramble.api.contact.ContactManager;
|
||||||
|
import org.briarproject.bramble.api.contact.PendingContact;
|
||||||
|
import org.briarproject.bramble.api.contact.PendingContactId;
|
||||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
@@ -19,12 +21,16 @@ import org.briarproject.bramble.api.transport.KeyManager;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.annotation.concurrent.ThreadSafe;
|
import javax.annotation.concurrent.ThreadSafe;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import static java.util.Collections.emptyList;
|
||||||
|
import static org.briarproject.bramble.api.contact.PendingContact.PendingContactState.WAITING_FOR_CONNECTION;
|
||||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
||||||
import static org.briarproject.bramble.api.identity.AuthorInfo.Status.OURSELVES;
|
import static org.briarproject.bramble.api.identity.AuthorInfo.Status.OURSELVES;
|
||||||
import static org.briarproject.bramble.api.identity.AuthorInfo.Status.UNKNOWN;
|
import static org.briarproject.bramble.api.identity.AuthorInfo.Status.UNKNOWN;
|
||||||
@@ -36,6 +42,12 @@ import static org.briarproject.bramble.util.StringUtils.toUtf8;
|
|||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class ContactManagerImpl implements ContactManager {
|
class ContactManagerImpl implements ContactManager {
|
||||||
|
|
||||||
|
private static final int LINK_LENGTH = 64;
|
||||||
|
private static final String REMOTE_CONTACT_LINK =
|
||||||
|
"briar://" + getRandomBase32String(LINK_LENGTH);
|
||||||
|
private static final Pattern LINK_REGEX =
|
||||||
|
Pattern.compile("(briar://)?([a-z2-7]{" + LINK_LENGTH + "})");
|
||||||
|
|
||||||
private final DatabaseComponent db;
|
private final DatabaseComponent db;
|
||||||
private final KeyManager keyManager;
|
private final KeyManager keyManager;
|
||||||
private final IdentityManager identityManager;
|
private final IdentityManager identityManager;
|
||||||
@@ -79,42 +91,63 @@ class ContactManagerImpl implements ContactManager {
|
|||||||
public ContactId addContact(Author remote, AuthorId local, SecretKey master,
|
public ContactId addContact(Author remote, AuthorId local, SecretKey master,
|
||||||
long timestamp, boolean alice, boolean verified, boolean active)
|
long timestamp, boolean alice, boolean verified, boolean active)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
ContactId c;
|
return db.transactionWithResult(false, txn ->
|
||||||
Transaction txn = db.startTransaction(false);
|
addContact(txn, remote, local, master, timestamp, alice,
|
||||||
try {
|
verified, active));
|
||||||
c = addContact(txn, remote, local, master, timestamp, alice,
|
|
||||||
verified, active);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
}
|
||||||
return c;
|
|
||||||
|
@Override
|
||||||
|
public String getRemoteContactLink() {
|
||||||
|
// TODO replace with real implementation
|
||||||
|
return REMOTE_CONTACT_LINK;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("SameParameterValue")
|
||||||
|
private static String getRandomBase32String(int length) {
|
||||||
|
Random random = new Random();
|
||||||
|
char[] c = new char[length];
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
int character = random.nextInt(32);
|
||||||
|
if (character < 26) c[i] = (char) ('a' + character);
|
||||||
|
else c[i] = (char) ('2' + (character - 26));
|
||||||
|
}
|
||||||
|
return new String(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValidRemoteContactLink(String link) {
|
||||||
|
return LINK_REGEX.matcher(link).matches();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PendingContact addRemoteContactRequest(String link, String alias) {
|
||||||
|
// TODO replace with real implementation
|
||||||
|
PendingContactId id = new PendingContactId(link.getBytes());
|
||||||
|
return new PendingContact(id, alias, WAITING_FOR_CONNECTION,
|
||||||
|
System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<PendingContact> getPendingContacts() {
|
||||||
|
// TODO replace with real implementation
|
||||||
|
return emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removePendingContact(PendingContact pendingContact) {
|
||||||
|
// TODO replace with real implementation
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Contact getContact(ContactId c) throws DbException {
|
public Contact getContact(ContactId c) throws DbException {
|
||||||
Contact contact;
|
return db.transactionWithResult(true, txn -> db.getContact(txn, c));
|
||||||
Transaction txn = db.startTransaction(true);
|
|
||||||
try {
|
|
||||||
contact = db.getContact(txn, c);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
return contact;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Contact getContact(AuthorId remoteAuthorId, AuthorId localAuthorId)
|
public Contact getContact(AuthorId remoteAuthorId, AuthorId localAuthorId)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
Transaction txn = db.startTransaction(true);
|
return db.transactionWithResult(true, txn ->
|
||||||
try {
|
getContact(txn, remoteAuthorId, localAuthorId));
|
||||||
Contact c = getContact(txn, remoteAuthorId, localAuthorId);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
return c;
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -132,14 +165,8 @@ class ContactManagerImpl implements ContactManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Contact> getActiveContacts() throws DbException {
|
public Collection<Contact> getActiveContacts() throws DbException {
|
||||||
Collection<Contact> contacts;
|
Collection<Contact> contacts =
|
||||||
Transaction txn = db.startTransaction(true);
|
db.transactionWithResult(true, db::getContacts);
|
||||||
try {
|
|
||||||
contacts = db.getContacts(txn);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
List<Contact> active = new ArrayList<>(contacts.size());
|
List<Contact> active = new ArrayList<>(contacts.size());
|
||||||
for (Contact c : contacts) if (c.isActive()) active.add(c);
|
for (Contact c : contacts) if (c.isActive()) active.add(c);
|
||||||
return active;
|
return active;
|
||||||
@@ -147,13 +174,7 @@ class ContactManagerImpl implements ContactManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeContact(ContactId c) throws DbException {
|
public void removeContact(ContactId c) throws DbException {
|
||||||
Transaction txn = db.startTransaction(false);
|
db.transaction(false, txn -> removeContact(txn, c));
|
||||||
try {
|
|
||||||
removeContact(txn, c);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -163,14 +184,20 @@ class ContactManagerImpl implements ContactManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setContactAlias(ContactId c, @Nullable String alias)
|
public void setContactAlias(Transaction txn, ContactId c,
|
||||||
throws DbException {
|
@Nullable String alias) throws DbException {
|
||||||
if (alias != null) {
|
if (alias != null) {
|
||||||
int aliasLength = toUtf8(alias).length;
|
int aliasLength = toUtf8(alias).length;
|
||||||
if (aliasLength == 0 || aliasLength > MAX_AUTHOR_NAME_LENGTH)
|
if (aliasLength == 0 || aliasLength > MAX_AUTHOR_NAME_LENGTH)
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
db.transaction(false, txn -> db.setContactAlias(txn, c, alias));
|
db.setContactAlias(txn, c, alias);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setContactAlias(ContactId c, @Nullable String alias)
|
||||||
|
throws DbException {
|
||||||
|
db.transaction(false, txn -> setContactAlias(txn, c, alias));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -182,15 +209,8 @@ class ContactManagerImpl implements ContactManager {
|
|||||||
@Override
|
@Override
|
||||||
public boolean contactExists(AuthorId remoteAuthorId,
|
public boolean contactExists(AuthorId remoteAuthorId,
|
||||||
AuthorId localAuthorId) throws DbException {
|
AuthorId localAuthorId) throws DbException {
|
||||||
boolean exists;
|
return db.transactionWithResult(true, txn ->
|
||||||
Transaction txn = db.startTransaction(true);
|
contactExists(txn, remoteAuthorId, localAuthorId));
|
||||||
try {
|
|
||||||
exists = contactExists(txn, remoteAuthorId, localAuthorId);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
return exists;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import static org.briarproject.bramble.data.Types.STRING_16;
|
|||||||
import static org.briarproject.bramble.data.Types.STRING_32;
|
import static org.briarproject.bramble.data.Types.STRING_32;
|
||||||
import static org.briarproject.bramble.data.Types.STRING_8;
|
import static org.briarproject.bramble.data.Types.STRING_8;
|
||||||
import static org.briarproject.bramble.data.Types.TRUE;
|
import static org.briarproject.bramble.data.Types.TRUE;
|
||||||
|
import static org.briarproject.bramble.util.StringUtils.fromUtf8;
|
||||||
|
|
||||||
@NotThreadSafe
|
@NotThreadSafe
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
@@ -253,7 +254,7 @@ class BdfReaderImpl implements BdfReader {
|
|||||||
if (length < 0 || length > maxBufferSize) throw new FormatException();
|
if (length < 0 || length > maxBufferSize) throw new FormatException();
|
||||||
if (length == 0) return "";
|
if (length == 0) return "";
|
||||||
readIntoBuffer(length);
|
readIntoBuffer(length);
|
||||||
return new String(buf, 0, length, "UTF-8");
|
return fromUtf8(buf, 0, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int readStringLength() throws IOException {
|
private int readStringLength() throws IOException {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import org.briarproject.bramble.api.sync.GroupId;
|
|||||||
import org.briarproject.bramble.api.sync.Message;
|
import org.briarproject.bramble.api.sync.Message;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
import org.briarproject.bramble.api.sync.MessageStatus;
|
import org.briarproject.bramble.api.sync.MessageStatus;
|
||||||
import org.briarproject.bramble.api.sync.ValidationManager.State;
|
import org.briarproject.bramble.api.sync.validation.MessageState;
|
||||||
import org.briarproject.bramble.api.transport.KeySet;
|
import org.briarproject.bramble.api.transport.KeySet;
|
||||||
import org.briarproject.bramble.api.transport.KeySetId;
|
import org.briarproject.bramble.api.transport.KeySetId;
|
||||||
import org.briarproject.bramble.api.transport.TransportKeys;
|
import org.briarproject.bramble.api.transport.TransportKeys;
|
||||||
@@ -106,7 +106,7 @@ interface Database<T> {
|
|||||||
* @param sender the contact from whom the message was received, or null
|
* @param sender the contact from whom the message was received, or null
|
||||||
* if the message was created locally.
|
* if the message was created locally.
|
||||||
*/
|
*/
|
||||||
void addMessage(T txn, Message m, State state, boolean shared,
|
void addMessage(T txn, Message m, MessageState state, boolean shared,
|
||||||
@Nullable ContactId sender) throws DbException;
|
@Nullable ContactId sender) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -114,7 +114,7 @@ interface Database<T> {
|
|||||||
* in the given state.
|
* in the given state.
|
||||||
*/
|
*/
|
||||||
void addMessageDependency(T txn, Message dependent, MessageId dependency,
|
void addMessageDependency(T txn, Message dependent, MessageId dependency,
|
||||||
State dependentState) throws DbException;
|
MessageState dependentState) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Records that a message has been offered by the given contact.
|
* Records that a message has been offered by the given contact.
|
||||||
@@ -310,11 +310,11 @@ interface Database<T> {
|
|||||||
/**
|
/**
|
||||||
* Returns the IDs and states of all dependencies of the given message.
|
* Returns the IDs and states of all dependencies of the given message.
|
||||||
* For missing dependencies and dependencies in other groups, the state
|
* For missing dependencies and dependencies in other groups, the state
|
||||||
* {@link State UNKNOWN} is returned.
|
* {@link MessageState UNKNOWN} is returned.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Read-only.
|
* Read-only.
|
||||||
*/
|
*/
|
||||||
Map<MessageId, State> getMessageDependencies(T txn, MessageId m)
|
Map<MessageId, MessageState> getMessageDependencies(T txn, MessageId m)
|
||||||
throws DbException;
|
throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -324,7 +324,7 @@ interface Database<T> {
|
|||||||
* <p/>
|
* <p/>
|
||||||
* Read-only.
|
* Read-only.
|
||||||
*/
|
*/
|
||||||
Map<MessageId, State> getMessageDependents(T txn, MessageId m)
|
Map<MessageId, MessageState> getMessageDependents(T txn, MessageId m)
|
||||||
throws DbException;
|
throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -383,7 +383,7 @@ interface Database<T> {
|
|||||||
* <p/>
|
* <p/>
|
||||||
* Read-only.
|
* Read-only.
|
||||||
*/
|
*/
|
||||||
State getMessageState(T txn, MessageId m) throws DbException;
|
MessageState getMessageState(T txn, MessageId m) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the status of all delivered messages in the given group with
|
* Returns the status of all delivered messages in the given group with
|
||||||
@@ -637,7 +637,8 @@ interface Database<T> {
|
|||||||
/**
|
/**
|
||||||
* Sets the validation and delivery state of the given message.
|
* Sets the validation and delivery state of the given message.
|
||||||
*/
|
*/
|
||||||
void setMessageState(T txn, MessageId m, State state) throws DbException;
|
void setMessageState(T txn, MessageId m, MessageState state)
|
||||||
|
throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the reordering window for the given key set and transport in the
|
* Sets the reordering window for the given key set and transport in the
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import org.briarproject.bramble.api.db.NoSuchGroupException;
|
|||||||
import org.briarproject.bramble.api.db.NoSuchLocalAuthorException;
|
import org.briarproject.bramble.api.db.NoSuchLocalAuthorException;
|
||||||
import org.briarproject.bramble.api.db.NoSuchMessageException;
|
import org.briarproject.bramble.api.db.NoSuchMessageException;
|
||||||
import org.briarproject.bramble.api.db.NoSuchTransportException;
|
import org.briarproject.bramble.api.db.NoSuchTransportException;
|
||||||
|
import org.briarproject.bramble.api.db.NullableDbCallable;
|
||||||
import org.briarproject.bramble.api.db.Transaction;
|
import org.briarproject.bramble.api.db.Transaction;
|
||||||
import org.briarproject.bramble.api.event.Event;
|
import org.briarproject.bramble.api.event.Event;
|
||||||
import org.briarproject.bramble.api.event.EventBus;
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
@@ -42,7 +43,6 @@ import org.briarproject.bramble.api.sync.MessageId;
|
|||||||
import org.briarproject.bramble.api.sync.MessageStatus;
|
import org.briarproject.bramble.api.sync.MessageStatus;
|
||||||
import org.briarproject.bramble.api.sync.Offer;
|
import org.briarproject.bramble.api.sync.Offer;
|
||||||
import org.briarproject.bramble.api.sync.Request;
|
import org.briarproject.bramble.api.sync.Request;
|
||||||
import org.briarproject.bramble.api.sync.ValidationManager.State;
|
|
||||||
import org.briarproject.bramble.api.sync.event.GroupAddedEvent;
|
import org.briarproject.bramble.api.sync.event.GroupAddedEvent;
|
||||||
import org.briarproject.bramble.api.sync.event.GroupRemovedEvent;
|
import org.briarproject.bramble.api.sync.event.GroupRemovedEvent;
|
||||||
import org.briarproject.bramble.api.sync.event.GroupVisibilityUpdatedEvent;
|
import org.briarproject.bramble.api.sync.event.GroupVisibilityUpdatedEvent;
|
||||||
@@ -54,6 +54,7 @@ import org.briarproject.bramble.api.sync.event.MessageToAckEvent;
|
|||||||
import org.briarproject.bramble.api.sync.event.MessageToRequestEvent;
|
import org.briarproject.bramble.api.sync.event.MessageToRequestEvent;
|
||||||
import org.briarproject.bramble.api.sync.event.MessagesAckedEvent;
|
import org.briarproject.bramble.api.sync.event.MessagesAckedEvent;
|
||||||
import org.briarproject.bramble.api.sync.event.MessagesSentEvent;
|
import org.briarproject.bramble.api.sync.event.MessagesSentEvent;
|
||||||
|
import org.briarproject.bramble.api.sync.validation.MessageState;
|
||||||
import org.briarproject.bramble.api.transport.KeySet;
|
import org.briarproject.bramble.api.transport.KeySet;
|
||||||
import org.briarproject.bramble.api.transport.KeySetId;
|
import org.briarproject.bramble.api.transport.KeySetId;
|
||||||
import org.briarproject.bramble.api.transport.TransportKeys;
|
import org.briarproject.bramble.api.transport.TransportKeys;
|
||||||
@@ -74,8 +75,8 @@ import javax.inject.Inject;
|
|||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
|
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
|
||||||
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
|
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
|
||||||
import static org.briarproject.bramble.api.sync.ValidationManager.State.DELIVERED;
|
import static org.briarproject.bramble.api.sync.validation.MessageState.DELIVERED;
|
||||||
import static org.briarproject.bramble.api.sync.ValidationManager.State.UNKNOWN;
|
import static org.briarproject.bramble.api.sync.validation.MessageState.UNKNOWN;
|
||||||
import static org.briarproject.bramble.db.DatabaseConstants.MAX_OFFERED_MESSAGES;
|
import static org.briarproject.bramble.db.DatabaseConstants.MAX_OFFERED_MESSAGES;
|
||||||
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
@@ -193,6 +194,20 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <R, E extends Exception> R transactionWithNullableResult(
|
||||||
|
boolean readOnly, NullableDbCallable<R, E> task)
|
||||||
|
throws DbException, E {
|
||||||
|
Transaction txn = startTransaction(readOnly);
|
||||||
|
try {
|
||||||
|
R result = task.call(txn);
|
||||||
|
commitTransaction(txn);
|
||||||
|
return result;
|
||||||
|
} finally {
|
||||||
|
endTransaction(txn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private T unbox(Transaction transaction) {
|
private T unbox(Transaction transaction) {
|
||||||
if (transaction.isCommitted()) throw new IllegalStateException();
|
if (transaction.isCommitted()) throw new IllegalStateException();
|
||||||
return txnClass.cast(transaction.unbox());
|
return txnClass.cast(transaction.unbox());
|
||||||
@@ -564,7 +579,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public State getMessageState(Transaction transaction, MessageId m)
|
public MessageState getMessageState(Transaction transaction, MessageId m)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
T txn = unbox(transaction);
|
T txn = unbox(transaction);
|
||||||
if (!db.containsMessage(txn, m))
|
if (!db.containsMessage(txn, m))
|
||||||
@@ -604,8 +619,8 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<MessageId, State> getMessageDependencies(Transaction transaction,
|
public Map<MessageId, MessageState> getMessageDependencies(
|
||||||
MessageId m) throws DbException {
|
Transaction transaction, MessageId m) throws DbException {
|
||||||
T txn = unbox(transaction);
|
T txn = unbox(transaction);
|
||||||
if (!db.containsMessage(txn, m))
|
if (!db.containsMessage(txn, m))
|
||||||
throw new NoSuchMessageException();
|
throw new NoSuchMessageException();
|
||||||
@@ -613,8 +628,8 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<MessageId, State> getMessageDependents(Transaction transaction,
|
public Map<MessageId, MessageState> getMessageDependents(
|
||||||
MessageId m) throws DbException {
|
Transaction transaction, MessageId m) throws DbException {
|
||||||
T txn = unbox(transaction);
|
T txn = unbox(transaction);
|
||||||
if (!db.containsMessage(txn, m))
|
if (!db.containsMessage(txn, m))
|
||||||
throw new NoSuchMessageException();
|
throw new NoSuchMessageException();
|
||||||
@@ -861,7 +876,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setContactAlias(Transaction transaction, ContactId c,
|
public void setContactAlias(Transaction transaction, ContactId c,
|
||||||
String alias) throws DbException {
|
@Nullable String alias) throws DbException {
|
||||||
if (transaction.isReadOnly()) throw new IllegalArgumentException();
|
if (transaction.isReadOnly()) throw new IllegalArgumentException();
|
||||||
T txn = unbox(transaction);
|
T txn = unbox(transaction);
|
||||||
if (!db.containsContact(txn, c))
|
if (!db.containsContact(txn, c))
|
||||||
@@ -903,7 +918,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setMessageState(Transaction transaction, MessageId m,
|
public void setMessageState(Transaction transaction, MessageId m,
|
||||||
State state) throws DbException {
|
MessageState state) throws DbException {
|
||||||
if (transaction.isReadOnly()) throw new IllegalArgumentException();
|
if (transaction.isReadOnly()) throw new IllegalArgumentException();
|
||||||
T txn = unbox(transaction);
|
T txn = unbox(transaction);
|
||||||
if (!db.containsMessage(txn, m))
|
if (!db.containsMessage(txn, m))
|
||||||
@@ -920,10 +935,10 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
|||||||
T txn = unbox(transaction);
|
T txn = unbox(transaction);
|
||||||
if (!db.containsMessage(txn, dependent.getId()))
|
if (!db.containsMessage(txn, dependent.getId()))
|
||||||
throw new NoSuchMessageException();
|
throw new NoSuchMessageException();
|
||||||
State dependentState = db.getMessageState(txn, dependent.getId());
|
MessageState dependentState =
|
||||||
|
db.getMessageState(txn, dependent.getId());
|
||||||
for (MessageId dependency : dependencies) {
|
for (MessageId dependency : dependencies) {
|
||||||
db.addMessageDependency(txn, dependent, dependency,
|
db.addMessageDependency(txn, dependent, dependency, dependentState);
|
||||||
dependentState);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,16 +15,23 @@ import java.sql.DriverManager;
|
|||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import static java.util.logging.Level.WARNING;
|
||||||
|
import static java.util.logging.Logger.getLogger;
|
||||||
|
import static org.briarproject.bramble.db.JdbcUtils.tryToClose;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains all the H2-specific code for the database.
|
* Contains all the H2-specific code for the database.
|
||||||
*/
|
*/
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class H2Database extends JdbcDatabase {
|
class H2Database extends JdbcDatabase {
|
||||||
|
|
||||||
|
private static final Logger LOG = getLogger(H2Database.class.getName());
|
||||||
|
|
||||||
private static final String HASH_TYPE = "BINARY(32)";
|
private static final String HASH_TYPE = "BINARY(32)";
|
||||||
private static final String SECRET_TYPE = "BINARY(32)";
|
private static final String SECRET_TYPE = "BINARY(32)";
|
||||||
private static final String BINARY_TYPE = "BINARY";
|
private static final String BINARY_TYPE = "BINARY";
|
||||||
@@ -121,8 +128,8 @@ class H2Database extends JdbcDatabase {
|
|||||||
s.close();
|
s.close();
|
||||||
c.close();
|
c.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(s);
|
tryToClose(s, LOG, WARNING);
|
||||||
tryToClose(c);
|
tryToClose(c, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,16 +14,24 @@ import java.sql.Connection;
|
|||||||
import java.sql.DriverManager;
|
import java.sql.DriverManager;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import static java.util.logging.Level.WARNING;
|
||||||
|
import static java.util.logging.Logger.getLogger;
|
||||||
|
import static org.briarproject.bramble.db.JdbcUtils.tryToClose;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains all the HSQLDB-specific code for the database.
|
* Contains all the HSQLDB-specific code for the database.
|
||||||
*/
|
*/
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class HyperSqlDatabase extends JdbcDatabase {
|
class HyperSqlDatabase extends JdbcDatabase {
|
||||||
|
|
||||||
|
private static final Logger LOG =
|
||||||
|
getLogger(HyperSqlDatabase.class.getName());
|
||||||
|
|
||||||
private static final String HASH_TYPE = "BINARY(32)";
|
private static final String HASH_TYPE = "BINARY(32)";
|
||||||
private static final String SECRET_TYPE = "BINARY(32)";
|
private static final String SECRET_TYPE = "BINARY(32)";
|
||||||
private static final String BINARY_TYPE = "BINARY";
|
private static final String BINARY_TYPE = "BINARY";
|
||||||
@@ -72,8 +80,8 @@ class HyperSqlDatabase extends JdbcDatabase {
|
|||||||
s.close();
|
s.close();
|
||||||
c.close();
|
c.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(s);
|
tryToClose(s, LOG, WARNING);
|
||||||
tryToClose(c);
|
tryToClose(c, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -122,8 +130,8 @@ class HyperSqlDatabase extends JdbcDatabase {
|
|||||||
s.close();
|
s.close();
|
||||||
c.close();
|
c.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(s);
|
tryToClose(s, LOG, WARNING);
|
||||||
tryToClose(c);
|
tryToClose(c, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import org.briarproject.bramble.api.sync.Message;
|
|||||||
import org.briarproject.bramble.api.sync.MessageFactory;
|
import org.briarproject.bramble.api.sync.MessageFactory;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
import org.briarproject.bramble.api.sync.MessageStatus;
|
import org.briarproject.bramble.api.sync.MessageStatus;
|
||||||
import org.briarproject.bramble.api.sync.ValidationManager.State;
|
import org.briarproject.bramble.api.sync.validation.MessageState;
|
||||||
import org.briarproject.bramble.api.system.Clock;
|
import org.briarproject.bramble.api.system.Clock;
|
||||||
import org.briarproject.bramble.api.transport.IncomingKeys;
|
import org.briarproject.bramble.api.transport.IncomingKeys;
|
||||||
import org.briarproject.bramble.api.transport.KeySet;
|
import org.briarproject.bramble.api.transport.KeySet;
|
||||||
@@ -64,14 +64,15 @@ import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
|
|||||||
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
|
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
|
||||||
import static org.briarproject.bramble.api.sync.Group.Visibility.VISIBLE;
|
import static org.briarproject.bramble.api.sync.Group.Visibility.VISIBLE;
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
|
import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
|
||||||
import static org.briarproject.bramble.api.sync.ValidationManager.State.DELIVERED;
|
import static org.briarproject.bramble.api.sync.validation.MessageState.DELIVERED;
|
||||||
import static org.briarproject.bramble.api.sync.ValidationManager.State.PENDING;
|
import static org.briarproject.bramble.api.sync.validation.MessageState.PENDING;
|
||||||
import static org.briarproject.bramble.api.sync.ValidationManager.State.UNKNOWN;
|
import static org.briarproject.bramble.api.sync.validation.MessageState.UNKNOWN;
|
||||||
import static org.briarproject.bramble.db.DatabaseConstants.DB_SETTINGS_NAMESPACE;
|
import static org.briarproject.bramble.db.DatabaseConstants.DB_SETTINGS_NAMESPACE;
|
||||||
import static org.briarproject.bramble.db.DatabaseConstants.LAST_COMPACTED_KEY;
|
import static org.briarproject.bramble.db.DatabaseConstants.LAST_COMPACTED_KEY;
|
||||||
import static org.briarproject.bramble.db.DatabaseConstants.MAX_COMPACTION_INTERVAL_MS;
|
import static org.briarproject.bramble.db.DatabaseConstants.MAX_COMPACTION_INTERVAL_MS;
|
||||||
import static org.briarproject.bramble.db.DatabaseConstants.SCHEMA_VERSION_KEY;
|
import static org.briarproject.bramble.db.DatabaseConstants.SCHEMA_VERSION_KEY;
|
||||||
import static org.briarproject.bramble.db.ExponentialBackoff.calculateExpiry;
|
import static org.briarproject.bramble.db.ExponentialBackoff.calculateExpiry;
|
||||||
|
import static org.briarproject.bramble.db.JdbcUtils.tryToClose;
|
||||||
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
import static org.briarproject.bramble.util.LogUtils.now;
|
import static org.briarproject.bramble.util.LogUtils.now;
|
||||||
@@ -458,30 +459,6 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
mergeSettings(txn, s, DB_SETTINGS_NAMESPACE);
|
mergeSettings(txn, s, DB_SETTINGS_NAMESPACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tryToClose(@Nullable ResultSet rs) {
|
|
||||||
try {
|
|
||||||
if (rs != null) rs.close();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
logException(LOG, WARNING, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void tryToClose(@Nullable Statement s) {
|
|
||||||
try {
|
|
||||||
if (s != null) s.close();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
logException(LOG, WARNING, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void tryToClose(@Nullable Connection c) {
|
|
||||||
try {
|
|
||||||
if (c != null) c.close();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
logException(LOG, WARNING, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createTables(Connection txn) throws DbException {
|
private void createTables(Connection txn) throws DbException {
|
||||||
Statement s = null;
|
Statement s = null;
|
||||||
try {
|
try {
|
||||||
@@ -502,7 +479,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
s.executeUpdate(dbTypes.replaceTypes(CREATE_INCOMING_KEYS));
|
s.executeUpdate(dbTypes.replaceTypes(CREATE_INCOMING_KEYS));
|
||||||
s.close();
|
s.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(s);
|
tryToClose(s, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -519,7 +496,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
s.executeUpdate(INDEX_STATUSES_BY_CONTACT_ID_TIMESTAMP);
|
s.executeUpdate(INDEX_STATUSES_BY_CONTACT_ID_TIMESTAMP);
|
||||||
s.close();
|
s.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(s);
|
tryToClose(s, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -566,11 +543,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
// Try to close the connection
|
// Try to close the connection
|
||||||
logException(LOG, WARNING, e);
|
logException(LOG, WARNING, e);
|
||||||
try {
|
tryToClose(txn, LOG, WARNING);
|
||||||
txn.close();
|
|
||||||
} catch (SQLException e1) {
|
|
||||||
logException(LOG, WARNING, e1);
|
|
||||||
}
|
|
||||||
// Whatever happens, allow the database to close
|
// Whatever happens, allow the database to close
|
||||||
connectionsLock.lock();
|
connectionsLock.lock();
|
||||||
try {
|
try {
|
||||||
@@ -659,8 +632,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return c;
|
return c;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -681,7 +654,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected != 1) throw new DbStateException();
|
if (affected != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -704,7 +677,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
// Create a status row for each message in the group
|
// Create a status row for each message in the group
|
||||||
addStatus(txn, c, g, groupShared);
|
addStatus(txn, c, g, groupShared);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -724,7 +697,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
MessageId id = new MessageId(rs.getBytes(1));
|
MessageId id = new MessageId(rs.getBytes(1));
|
||||||
long timestamp = rs.getLong(2);
|
long timestamp = rs.getLong(2);
|
||||||
State state = State.fromValue(rs.getInt(3));
|
MessageState state = MessageState.fromValue(rs.getInt(3));
|
||||||
boolean messageShared = rs.getBoolean(4);
|
boolean messageShared = rs.getBoolean(4);
|
||||||
int length = rs.getInt(5);
|
int length = rs.getInt(5);
|
||||||
boolean deleted = rs.getBoolean(6);
|
boolean deleted = rs.getBoolean(6);
|
||||||
@@ -735,8 +708,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
rs.close();
|
rs.close();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -761,13 +734,13 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected != 1) throw new DbStateException();
|
if (affected != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addMessage(Connection txn, Message m, State state,
|
public void addMessage(Connection txn, Message m, MessageState state,
|
||||||
boolean messageShared, @Nullable ContactId sender)
|
boolean messageShared, @Nullable ContactId sender)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
@@ -810,7 +783,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0) throw new DbStateException();
|
if (affected < 0) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -840,14 +813,14 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected != 1) throw new DbStateException();
|
if (affected != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addStatus(Connection txn, MessageId m, ContactId c, GroupId g,
|
private void addStatus(Connection txn, MessageId m, ContactId c, GroupId g,
|
||||||
long timestamp, int length, State state, boolean groupShared,
|
long timestamp, int length, MessageState state, boolean groupShared,
|
||||||
boolean messageShared, boolean deleted, boolean seen)
|
boolean messageShared, boolean deleted, boolean seen)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
@@ -873,14 +846,15 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected != 1) throw new DbStateException();
|
if (affected != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addMessageDependency(Connection txn, Message dependent,
|
public void addMessageDependency(Connection txn, Message dependent,
|
||||||
MessageId dependency, State dependentState) throws DbException {
|
MessageId dependency, MessageState dependentState)
|
||||||
|
throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
try {
|
try {
|
||||||
@@ -891,9 +865,9 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.setBytes(1, dependency.getBytes());
|
ps.setBytes(1, dependency.getBytes());
|
||||||
ps.setBytes(2, dependent.getGroupId().getBytes());
|
ps.setBytes(2, dependent.getGroupId().getBytes());
|
||||||
rs = ps.executeQuery();
|
rs = ps.executeQuery();
|
||||||
State dependencyState = null;
|
MessageState dependencyState = null;
|
||||||
if (rs.next()) {
|
if (rs.next()) {
|
||||||
dependencyState = State.fromValue(rs.getInt(1));
|
dependencyState = MessageState.fromValue(rs.getInt(1));
|
||||||
if (rs.next()) throw new DbStateException();
|
if (rs.next()) throw new DbStateException();
|
||||||
}
|
}
|
||||||
rs.close();
|
rs.close();
|
||||||
@@ -914,8 +888,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected != 1) throw new DbStateException();
|
if (affected != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -934,7 +908,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected != 1) throw new DbStateException();
|
if (affected != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1014,8 +988,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return keySetId;
|
return keySetId;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1038,8 +1012,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return found;
|
return found;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1060,8 +1034,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return found;
|
return found;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1082,8 +1056,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return found;
|
return found;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1104,8 +1078,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return found;
|
return found;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1126,8 +1100,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return found;
|
return found;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1148,8 +1122,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return found;
|
return found;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1173,8 +1147,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return found;
|
return found;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1197,8 +1171,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return count;
|
return count;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1222,7 +1196,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0) throw new DbStateException();
|
if (affected < 0) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1239,7 +1213,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0) throw new DbStateException();
|
if (affected < 0) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1272,8 +1246,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
return new Contact(c, author, localAuthorId, alias, verified,
|
return new Contact(c, author, localAuthorId, alias, verified,
|
||||||
active);
|
active);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1309,8 +1283,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return contacts;
|
return contacts;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1332,8 +1306,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return ids;
|
return ids;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1370,8 +1344,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return contacts;
|
return contacts;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1394,8 +1368,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return new Group(g, clientId, majorVersion, descriptor);
|
return new Group(g, clientId, majorVersion, descriptor);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1422,8 +1396,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return groups;
|
return groups;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1448,8 +1422,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return v;
|
return v;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1472,8 +1446,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return visible;
|
return visible;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1504,8 +1478,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return localAuthor;
|
return localAuthor;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1536,8 +1510,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return authors;
|
return authors;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1565,8 +1539,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
System.arraycopy(raw, MESSAGE_HEADER_LENGTH, body, 0, body.length);
|
System.arraycopy(raw, MESSAGE_HEADER_LENGTH, body, 0, body.length);
|
||||||
return new Message(m, g, timestamp, body);
|
return new Message(m, g, timestamp, body);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1589,8 +1563,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return ids;
|
return ids;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1627,8 +1601,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (intersection == null) throw new AssertionError();
|
if (intersection == null) throw new AssertionError();
|
||||||
return intersection;
|
return intersection;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1660,8 +1634,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return all;
|
return all;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1695,8 +1669,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return metadata;
|
return metadata;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1719,8 +1693,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return metadata;
|
return metadata;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1745,8 +1719,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return metadata;
|
return metadata;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1775,8 +1749,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return statuses;
|
return statuses;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1806,14 +1780,14 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return status;
|
return status;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<MessageId, State> getMessageDependencies(Connection txn,
|
public Map<MessageId, MessageState> getMessageDependencies(Connection txn,
|
||||||
MessageId m) throws DbException {
|
MessageId m) throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
@@ -1824,10 +1798,10 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
ps.setBytes(1, m.getBytes());
|
ps.setBytes(1, m.getBytes());
|
||||||
rs = ps.executeQuery();
|
rs = ps.executeQuery();
|
||||||
Map<MessageId, State> dependencies = new HashMap<>();
|
Map<MessageId, MessageState> dependencies = new HashMap<>();
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
MessageId dependency = new MessageId(rs.getBytes(1));
|
MessageId dependency = new MessageId(rs.getBytes(1));
|
||||||
State state = State.fromValue(rs.getInt(2));
|
MessageState state = MessageState.fromValue(rs.getInt(2));
|
||||||
if (rs.wasNull())
|
if (rs.wasNull())
|
||||||
state = UNKNOWN; // Missing or in a different group
|
state = UNKNOWN; // Missing or in a different group
|
||||||
dependencies.put(dependency, state);
|
dependencies.put(dependency, state);
|
||||||
@@ -1836,14 +1810,14 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return dependencies;
|
return dependencies;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<MessageId, State> getMessageDependents(Connection txn,
|
public Map<MessageId, MessageState> getMessageDependents(Connection txn,
|
||||||
MessageId m) throws DbException {
|
MessageId m) throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
@@ -1857,24 +1831,24 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
ps.setBytes(1, m.getBytes());
|
ps.setBytes(1, m.getBytes());
|
||||||
rs = ps.executeQuery();
|
rs = ps.executeQuery();
|
||||||
Map<MessageId, State> dependents = new HashMap<>();
|
Map<MessageId, MessageState> dependents = new HashMap<>();
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
MessageId dependent = new MessageId(rs.getBytes(1));
|
MessageId dependent = new MessageId(rs.getBytes(1));
|
||||||
State state = State.fromValue(rs.getInt(2));
|
MessageState state = MessageState.fromValue(rs.getInt(2));
|
||||||
dependents.put(dependent, state);
|
dependents.put(dependent, state);
|
||||||
}
|
}
|
||||||
rs.close();
|
rs.close();
|
||||||
ps.close();
|
ps.close();
|
||||||
return dependents;
|
return dependents;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public State getMessageState(Connection txn, MessageId m)
|
public MessageState getMessageState(Connection txn, MessageId m)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
@@ -1884,14 +1858,14 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.setBytes(1, m.getBytes());
|
ps.setBytes(1, m.getBytes());
|
||||||
rs = ps.executeQuery();
|
rs = ps.executeQuery();
|
||||||
if (!rs.next()) throw new DbStateException();
|
if (!rs.next()) throw new DbStateException();
|
||||||
State state = State.fromValue(rs.getInt(1));
|
MessageState state = MessageState.fromValue(rs.getInt(1));
|
||||||
if (rs.next()) throw new DbStateException();
|
if (rs.next()) throw new DbStateException();
|
||||||
rs.close();
|
rs.close();
|
||||||
ps.close();
|
ps.close();
|
||||||
return state;
|
return state;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1915,8 +1889,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return ids;
|
return ids;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1949,8 +1923,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return ids;
|
return ids;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1974,8 +1948,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return ids;
|
return ids;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2013,8 +1987,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return ids;
|
return ids;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2032,7 +2006,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Collection<MessageId> getMessagesInState(Connection txn,
|
private Collection<MessageId> getMessagesInState(Connection txn,
|
||||||
State state) throws DbException {
|
MessageState state) throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
try {
|
try {
|
||||||
@@ -2047,8 +2021,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return ids;
|
return ids;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2075,8 +2049,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return ids;
|
return ids;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2105,8 +2079,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return nextSendTime;
|
return nextSendTime;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2144,8 +2118,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return ids;
|
return ids;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2167,8 +2141,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return s;
|
return s;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2233,8 +2207,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return keys;
|
return keys;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2253,7 +2227,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected != 1) throw new DbStateException();
|
if (affected != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2280,7 +2254,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2307,7 +2281,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2337,7 +2311,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (rows != 1) throw new DbStateException();
|
if (rows != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2359,7 +2333,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
rs = ps.executeQuery();
|
rs = ps.executeQuery();
|
||||||
if (!rs.next()) throw new DbStateException();
|
if (!rs.next()) throw new DbStateException();
|
||||||
GroupId g = new GroupId(rs.getBytes(1));
|
GroupId g = new GroupId(rs.getBytes(1));
|
||||||
State state = State.fromValue(rs.getInt(2));
|
MessageState state = MessageState.fromValue(rs.getInt(2));
|
||||||
rs.close();
|
rs.close();
|
||||||
ps.close();
|
ps.close();
|
||||||
// Insert any keys that don't already exist
|
// Insert any keys that don't already exist
|
||||||
@@ -2382,8 +2356,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (rows != 1) throw new DbStateException();
|
if (rows != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2449,7 +2423,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
return added;
|
return added;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2496,7 +2470,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (rows != 1) throw new DbStateException();
|
if (rows != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2515,7 +2489,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0 || affected > 1) throw new DbStateException();
|
if (affected < 0 || affected > 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2534,7 +2508,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0 || affected > 1) throw new DbStateException();
|
if (affected < 0 || affected > 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2553,7 +2527,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0 || affected > 1) throw new DbStateException();
|
if (affected < 0 || affected > 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2570,7 +2544,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected != 1) throw new DbStateException();
|
if (affected != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2586,7 +2560,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected != 1) throw new DbStateException();
|
if (affected != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2614,7 +2588,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0) throw new DbStateException();
|
if (affected < 0) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2631,7 +2605,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected != 1) throw new DbStateException();
|
if (affected != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2647,7 +2621,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected != 1) throw new DbStateException();
|
if (affected != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2666,7 +2640,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return affected == 1;
|
return affected == 1;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2691,7 +2665,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (rows != 1) throw new DbStateException();
|
if (rows != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2708,7 +2682,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected != 1) throw new DbStateException();
|
if (affected != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2729,7 +2703,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0) throw new DbStateException();
|
if (affected < 0) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2748,7 +2722,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0 || affected > 1) throw new DbStateException();
|
if (affected < 0 || affected > 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2766,7 +2740,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0 || affected > 1) throw new DbStateException();
|
if (affected < 0 || affected > 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2784,7 +2758,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0 || affected > 1) throw new DbStateException();
|
if (affected < 0 || affected > 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2803,7 +2777,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0 || affected > 1) throw new DbStateException();
|
if (affected < 0 || affected > 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2833,7 +2807,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0) throw new DbStateException();
|
if (affected < 0) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2859,13 +2833,13 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0) throw new DbStateException();
|
if (affected < 0) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setMessageState(Connection txn, MessageId m, State state)
|
public void setMessageState(Connection txn, MessageId m, MessageState state)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
try {
|
try {
|
||||||
@@ -2912,7 +2886,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0) throw new DbStateException();
|
if (affected < 0) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2935,7 +2909,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0 || affected > 1) throw new DbStateException();
|
if (affected < 0 || affected > 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2954,7 +2928,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected < 0 || affected > 1) throw new DbStateException();
|
if (affected < 0 || affected > 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2990,8 +2964,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (affected != 1) throw new DbStateException();
|
if (affected != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3058,7 +3032,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (rows < 0 || rows > 1) throw new DbStateException();
|
if (rows < 0 || rows > 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package org.briarproject.bramble.db;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
|
|
||||||
|
@NotNullByDefault
|
||||||
|
class JdbcUtils {
|
||||||
|
|
||||||
|
static void tryToClose(@Nullable ResultSet rs, Logger logger, Level level) {
|
||||||
|
try {
|
||||||
|
if (rs != null) rs.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
logException(logger, level, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tryToClose(@Nullable Statement s, Logger logger, Level level) {
|
||||||
|
try {
|
||||||
|
if (s != null) s.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
logException(logger, level, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tryToClose(@Nullable Connection c, Logger logger, Level level) {
|
||||||
|
try {
|
||||||
|
if (c != null) c.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
logException(logger, level, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,10 +7,8 @@ import java.sql.SQLException;
|
|||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
import static org.briarproject.bramble.db.JdbcUtils.tryToClose;
|
||||||
|
|
||||||
class Migration38_39 implements Migration<Connection> {
|
class Migration38_39 implements Migration<Connection> {
|
||||||
|
|
||||||
@@ -40,16 +38,8 @@ class Migration38_39 implements Migration<Connection> {
|
|||||||
+ " ALTER COLUMN contactId"
|
+ " ALTER COLUMN contactId"
|
||||||
+ " SET NOT NULL");
|
+ " SET NOT NULL");
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(s);
|
tryToClose(s, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tryToClose(@Nullable Statement s) {
|
|
||||||
try {
|
|
||||||
if (s != null) s.close();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
logException(LOG, WARNING, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,10 +7,8 @@ import java.sql.SQLException;
|
|||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
import static org.briarproject.bramble.db.JdbcUtils.tryToClose;
|
||||||
|
|
||||||
class Migration39_40 implements Migration<Connection> {
|
class Migration39_40 implements Migration<Connection> {
|
||||||
|
|
||||||
@@ -39,16 +37,8 @@ class Migration39_40 implements Migration<Connection> {
|
|||||||
+ " ALTER COLUMN eta"
|
+ " ALTER COLUMN eta"
|
||||||
+ " SET NOT NULL");
|
+ " SET NOT NULL");
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(s);
|
tryToClose(s, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tryToClose(@Nullable Statement s) {
|
|
||||||
try {
|
|
||||||
if (s != null) s.close();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
logException(LOG, WARNING, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,9 @@ import java.sql.SQLException;
|
|||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static java.util.logging.Logger.getLogger;
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
import static org.briarproject.bramble.db.JdbcUtils.tryToClose;
|
||||||
|
|
||||||
class Migration40_41 implements Migration<Connection> {
|
class Migration40_41 implements Migration<Connection> {
|
||||||
|
|
||||||
@@ -39,18 +37,10 @@ class Migration40_41 implements Migration<Connection> {
|
|||||||
try {
|
try {
|
||||||
s = txn.createStatement();
|
s = txn.createStatement();
|
||||||
s.execute("ALTER TABLE contacts"
|
s.execute("ALTER TABLE contacts"
|
||||||
+ dbTypes.replaceTypes(" ADD alias VARCHAR"));
|
+ dbTypes.replaceTypes(" ADD alias _STRING"));
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(s);
|
tryToClose(s, LOG, WARNING);
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tryToClose(@Nullable Statement s) {
|
|
||||||
try {
|
|
||||||
if (s != null) s.close();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
logException(LOG, WARNING, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,27 +67,16 @@ class IdentityManagerImpl implements IdentityManager {
|
|||||||
LOG.info("No local author to store");
|
LOG.info("No local author to store");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Transaction txn = db.startTransaction(false);
|
db.transaction(false, txn -> db.addLocalAuthor(txn, cached));
|
||||||
try {
|
|
||||||
db.addLocalAuthor(txn, cached);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
LOG.info("Local author stored");
|
LOG.info("Local author stored");
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LocalAuthor getLocalAuthor() throws DbException {
|
public LocalAuthor getLocalAuthor() throws DbException {
|
||||||
if (cachedAuthor == null) {
|
if (cachedAuthor == null) {
|
||||||
Transaction txn = db.startTransaction(true);
|
cachedAuthor =
|
||||||
try {
|
db.transactionWithResult(true, this::loadLocalAuthor);
|
||||||
cachedAuthor = loadLocalAuthor(txn);
|
|
||||||
LOG.info("Local author loaded");
|
LOG.info("Local author loaded");
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
LocalAuthor cached = cachedAuthor;
|
LocalAuthor cached = cachedAuthor;
|
||||||
if (cached == null) throw new AssertionError();
|
if (cached == null) throw new AssertionError();
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import org.briarproject.bramble.api.db.DataTooOldException;
|
|||||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.db.MigrationListener;
|
import org.briarproject.bramble.api.db.MigrationListener;
|
||||||
import org.briarproject.bramble.api.db.Transaction;
|
|
||||||
import org.briarproject.bramble.api.event.EventBus;
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||||
@@ -115,20 +114,16 @@ class LifecycleManagerImpl implements LifecycleManager, MigrationListener {
|
|||||||
dbLatch.countDown();
|
dbLatch.countDown();
|
||||||
eventBus.broadcast(new LifecycleEvent(STARTING_SERVICES));
|
eventBus.broadcast(new LifecycleEvent(STARTING_SERVICES));
|
||||||
|
|
||||||
Transaction txn = db.startTransaction(false);
|
db.transaction(false, txn -> {
|
||||||
try {
|
|
||||||
for (Client c : clients) {
|
for (Client c : clients) {
|
||||||
start = now();
|
long start1 = now();
|
||||||
c.createLocalState(txn);
|
c.createLocalState(txn);
|
||||||
if (LOG.isLoggable(FINE)) {
|
if (LOG.isLoggable(FINE)) {
|
||||||
logDuration(LOG, "Starting client "
|
logDuration(LOG, "Starting client "
|
||||||
+ c.getClass().getSimpleName(), start);
|
+ c.getClass().getSimpleName(), start1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
db.commitTransaction(txn);
|
});
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
for (Service s : services) {
|
for (Service s : services) {
|
||||||
start = now();
|
start = now();
|
||||||
s.startService();
|
s.startService();
|
||||||
|
|||||||
@@ -4,12 +4,11 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|||||||
import org.briarproject.bramble.api.plugin.TransportConnectionReader;
|
import org.briarproject.bramble.api.plugin.TransportConnectionReader;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
import static org.briarproject.bramble.util.IoUtils.tryToClose;
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class FileTransportReader implements TransportConnectionReader {
|
class FileTransportReader implements TransportConnectionReader {
|
||||||
@@ -34,11 +33,7 @@ class FileTransportReader implements TransportConnectionReader {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose(boolean exception, boolean recognised) {
|
public void dispose(boolean exception, boolean recognised) {
|
||||||
try {
|
tryToClose(in, LOG, WARNING);
|
||||||
in.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
logException(LOG, WARNING, e);
|
|
||||||
}
|
|
||||||
plugin.readerFinished(file, exception, recognised);
|
plugin.readerFinished(file, exception, recognised);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,12 +4,11 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|||||||
import org.briarproject.bramble.api.plugin.TransportConnectionWriter;
|
import org.briarproject.bramble.api.plugin.TransportConnectionWriter;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
import static org.briarproject.bramble.util.IoUtils.tryToClose;
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class FileTransportWriter implements TransportConnectionWriter {
|
class FileTransportWriter implements TransportConnectionWriter {
|
||||||
@@ -44,11 +43,7 @@ class FileTransportWriter implements TransportConnectionWriter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose(boolean exception) {
|
public void dispose(boolean exception) {
|
||||||
try {
|
tryToClose(out, LOG, WARNING);
|
||||||
out.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
logException(LOG, WARNING, e);
|
|
||||||
}
|
|
||||||
plugin.writerFinished(file, exception);
|
plugin.writerFinished(file, exception);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback;
|
|||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
||||||
import org.briarproject.bramble.api.properties.TransportProperties;
|
import org.briarproject.bramble.api.properties.TransportProperties;
|
||||||
import org.briarproject.bramble.api.settings.Settings;
|
import org.briarproject.bramble.api.settings.Settings;
|
||||||
|
import org.briarproject.bramble.util.IoUtils;
|
||||||
import org.briarproject.bramble.util.StringUtils;
|
import org.briarproject.bramble.util.StringUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -35,7 +36,6 @@ 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.PREF_LAN_IP_PORTS;
|
||||||
import static org.briarproject.bramble.api.plugin.LanTcpConstants.PROP_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.ByteUtils.MAX_16_BIT_UNSIGNED;
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
|
||||||
import static org.briarproject.bramble.util.PrivacyUtils.scrubSocketAddress;
|
import static org.briarproject.bramble.util.PrivacyUtils.scrubSocketAddress;
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
@@ -293,11 +293,7 @@ class LanTcpPlugin extends TcpPlugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
try {
|
IoUtils.tryToClose(ss, LOG, WARNING);
|
||||||
ss.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
logException(LOG, WARNING, e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
|||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback;
|
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback;
|
||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
||||||
import org.briarproject.bramble.api.properties.TransportProperties;
|
import org.briarproject.bramble.api.properties.TransportProperties;
|
||||||
|
import org.briarproject.bramble.util.IoUtils;
|
||||||
import org.briarproject.bramble.util.StringUtils;
|
import org.briarproject.bramble.util.StringUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -153,14 +154,9 @@ abstract class TcpPlugin implements DuplexPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void tryToClose(@Nullable ServerSocket ss) {
|
protected void tryToClose(@Nullable ServerSocket ss) {
|
||||||
try {
|
IoUtils.tryToClose(ss, LOG, WARNING);
|
||||||
if (ss != null) ss.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
logException(LOG, WARNING, e);
|
|
||||||
} finally {
|
|
||||||
callback.transportDisabled();
|
callback.transportDisabled();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
String getIpPortString(InetSocketAddress a) {
|
String getIpPortString(InetSocketAddress a) {
|
||||||
String addr = a.getAddress().getHostAddress();
|
String addr = a.getAddress().getHostAddress();
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import net.freehaven.tor.control.EventHandler;
|
|||||||
import net.freehaven.tor.control.TorControlConnection;
|
import net.freehaven.tor.control.TorControlConnection;
|
||||||
|
|
||||||
import org.briarproject.bramble.PoliteExecutor;
|
import org.briarproject.bramble.PoliteExecutor;
|
||||||
|
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.contact.ContactId;
|
||||||
import org.briarproject.bramble.api.data.BdfList;
|
import org.briarproject.bramble.api.data.BdfList;
|
||||||
import org.briarproject.bramble.api.event.Event;
|
import org.briarproject.bramble.api.event.Event;
|
||||||
@@ -29,7 +31,6 @@ import org.briarproject.bramble.api.system.LocationUtils;
|
|||||||
import org.briarproject.bramble.api.system.ResourceProvider;
|
import org.briarproject.bramble.api.system.ResourceProvider;
|
||||||
import org.briarproject.bramble.util.IoUtils;
|
import org.briarproject.bramble.util.IoUtils;
|
||||||
|
|
||||||
import java.io.Closeable;
|
|
||||||
import java.io.EOFException;
|
import java.io.EOFException;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
@@ -68,6 +69,7 @@ import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK;
|
|||||||
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_AUTOMATIC;
|
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_AUTOMATIC;
|
||||||
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_NEVER;
|
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_NEVER;
|
||||||
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_WITH_BRIDGES;
|
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_WITH_BRIDGES;
|
||||||
|
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_ONLY_WHEN_CHARGING;
|
||||||
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_PORT;
|
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_PORT;
|
||||||
import static org.briarproject.bramble.api.plugin.TorConstants.PROP_ONION_V2;
|
import static org.briarproject.bramble.api.plugin.TorConstants.PROP_ONION_V2;
|
||||||
import static org.briarproject.bramble.api.plugin.TorConstants.PROP_ONION_V3;
|
import static org.briarproject.bramble.api.plugin.TorConstants.PROP_ONION_V3;
|
||||||
@@ -96,13 +98,14 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
private final LocationUtils locationUtils;
|
private final LocationUtils locationUtils;
|
||||||
private final SocketFactory torSocketFactory;
|
private final SocketFactory torSocketFactory;
|
||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
|
private final BatteryManager batteryManager;
|
||||||
private final Backoff backoff;
|
private final Backoff backoff;
|
||||||
private final DuplexPluginCallback callback;
|
private final DuplexPluginCallback callback;
|
||||||
private final String architecture;
|
private final String architecture;
|
||||||
private final CircumventionProvider circumventionProvider;
|
private final CircumventionProvider circumventionProvider;
|
||||||
private final ResourceProvider resourceProvider;
|
private final ResourceProvider resourceProvider;
|
||||||
private final int maxLatency, maxIdleTime, socketTimeout;
|
private final int maxLatency, maxIdleTime, socketTimeout;
|
||||||
private final File torDirectory, torFile, geoIpFile, configFile;
|
private final File torDirectory, torFile, geoIpFile, obfs4File, configFile;
|
||||||
private final File doneFile, cookieFile;
|
private final File doneFile, cookieFile;
|
||||||
private final ConnectionStatus connectionStatus;
|
private final ConnectionStatus connectionStatus;
|
||||||
private final AtomicBoolean used = new AtomicBoolean(false);
|
private final AtomicBoolean used = new AtomicBoolean(false);
|
||||||
@@ -121,7 +124,8 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
TorPlugin(Executor ioExecutor, NetworkManager networkManager,
|
TorPlugin(Executor ioExecutor, NetworkManager networkManager,
|
||||||
LocationUtils locationUtils, SocketFactory torSocketFactory,
|
LocationUtils locationUtils, SocketFactory torSocketFactory,
|
||||||
Clock clock, ResourceProvider resourceProvider,
|
Clock clock, ResourceProvider resourceProvider,
|
||||||
CircumventionProvider circumventionProvider, Backoff backoff,
|
CircumventionProvider circumventionProvider,
|
||||||
|
BatteryManager batteryManager, Backoff backoff,
|
||||||
DuplexPluginCallback callback, String architecture, int maxLatency,
|
DuplexPluginCallback callback, String architecture, int maxLatency,
|
||||||
int maxIdleTime, File torDirectory) {
|
int maxIdleTime, File torDirectory) {
|
||||||
this.ioExecutor = ioExecutor;
|
this.ioExecutor = ioExecutor;
|
||||||
@@ -131,6 +135,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
this.clock = clock;
|
this.clock = clock;
|
||||||
this.resourceProvider = resourceProvider;
|
this.resourceProvider = resourceProvider;
|
||||||
this.circumventionProvider = circumventionProvider;
|
this.circumventionProvider = circumventionProvider;
|
||||||
|
this.batteryManager = batteryManager;
|
||||||
this.backoff = backoff;
|
this.backoff = backoff;
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
this.architecture = architecture;
|
this.architecture = architecture;
|
||||||
@@ -142,6 +147,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
this.torDirectory = torDirectory;
|
this.torDirectory = torDirectory;
|
||||||
torFile = new File(torDirectory, "tor");
|
torFile = new File(torDirectory, "tor");
|
||||||
geoIpFile = new File(torDirectory, "geoip");
|
geoIpFile = new File(torDirectory, "geoip");
|
||||||
|
obfs4File = new File(torDirectory, "obfs4proxy");
|
||||||
configFile = new File(torDirectory, "torrc");
|
configFile = new File(torDirectory, "torrc");
|
||||||
doneFile = new File(torDirectory, "done");
|
doneFile = new File(torDirectory, "done");
|
||||||
cookieFile = new File(torDirectory, ".tor/control_auth_cookie");
|
cookieFile = new File(torDirectory, ".tor/control_auth_cookie");
|
||||||
@@ -260,7 +266,8 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
throw new PluginException(e);
|
throw new PluginException(e);
|
||||||
}
|
}
|
||||||
// Check whether we're online
|
// Check whether we're online
|
||||||
updateConnectionStatus(networkManager.getNetworkStatus());
|
updateConnectionStatus(networkManager.getNetworkStatus(),
|
||||||
|
batteryManager.isCharging());
|
||||||
// Bind a server socket to receive incoming hidden service connections
|
// Bind a server socket to receive incoming hidden service connections
|
||||||
bind();
|
bind();
|
||||||
}
|
}
|
||||||
@@ -284,14 +291,20 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
in = getGeoIpInputStream();
|
in = getGeoIpInputStream();
|
||||||
out = new FileOutputStream(geoIpFile);
|
out = new FileOutputStream(geoIpFile);
|
||||||
IoUtils.copyAndClose(in, out);
|
IoUtils.copyAndClose(in, out);
|
||||||
|
// Unzip the Obfs4 proxy to the filesystem
|
||||||
|
in = getObfs4InputStream();
|
||||||
|
out = new FileOutputStream(obfs4File);
|
||||||
|
IoUtils.copyAndClose(in, out);
|
||||||
|
// Make the Obfs4 proxy executable
|
||||||
|
if (!obfs4File.setExecutable(true, true)) throw new IOException();
|
||||||
// Copy the config file to the filesystem
|
// Copy the config file to the filesystem
|
||||||
in = getConfigInputStream();
|
in = getConfigInputStream();
|
||||||
out = new FileOutputStream(configFile);
|
out = new FileOutputStream(configFile);
|
||||||
IoUtils.copyAndClose(in, out);
|
IoUtils.copyAndClose(in, out);
|
||||||
doneFile.createNewFile();
|
doneFile.createNewFile();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
tryToClose(in);
|
IoUtils.tryToClose(in, LOG, WARNING);
|
||||||
tryToClose(out);
|
IoUtils.tryToClose(out, LOG, WARNING);
|
||||||
throw new PluginException(e);
|
throw new PluginException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -314,26 +327,20 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
return zin;
|
return zin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private InputStream getObfs4InputStream() throws IOException {
|
||||||
|
if (LOG.isLoggable(INFO))
|
||||||
|
LOG.info("Installing obfs4proxy binary for " + architecture);
|
||||||
|
InputStream in = resourceProvider
|
||||||
|
.getResourceInputStream("obfs4proxy_" + architecture, ".zip");
|
||||||
|
ZipInputStream zin = new ZipInputStream(in);
|
||||||
|
if (zin.getNextEntry() == null) throw new IOException();
|
||||||
|
return zin;
|
||||||
|
}
|
||||||
|
|
||||||
private InputStream getConfigInputStream() {
|
private InputStream getConfigInputStream() {
|
||||||
return getClass().getClassLoader().getResourceAsStream("torrc");
|
return getClass().getClassLoader().getResourceAsStream("torrc");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tryToClose(@Nullable Closeable c) {
|
|
||||||
try {
|
|
||||||
if (c != null) c.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
logException(LOG, WARNING, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void tryToClose(@Nullable Socket s) {
|
|
||||||
try {
|
|
||||||
if (s != null) s.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
logException(LOG, WARNING, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void listFiles(File f) {
|
private void listFiles(File f) {
|
||||||
if (f.isDirectory()) {
|
if (f.isDirectory()) {
|
||||||
File[] children = f.listFiles();
|
File[] children = f.listFiles();
|
||||||
@@ -355,7 +362,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
}
|
}
|
||||||
return b;
|
return b;
|
||||||
} finally {
|
} finally {
|
||||||
tryToClose(in);
|
IoUtils.tryToClose(in, LOG, WARNING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -395,14 +402,9 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void tryToClose(@Nullable ServerSocket ss) {
|
private void tryToClose(@Nullable ServerSocket ss) {
|
||||||
try {
|
IoUtils.tryToClose(ss, LOG, WARNING);
|
||||||
if (ss != null) ss.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
logException(LOG, WARNING, e);
|
|
||||||
} finally {
|
|
||||||
callback.transportDisabled();
|
callback.transportDisabled();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void publishHiddenService(String port) {
|
private void publishHiddenService(String port) {
|
||||||
if (!running) return;
|
if (!running) return;
|
||||||
@@ -472,6 +474,8 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
if (enable) {
|
if (enable) {
|
||||||
Collection<String> conf = new ArrayList<>();
|
Collection<String> conf = new ArrayList<>();
|
||||||
conf.add("UseBridges 1");
|
conf.add("UseBridges 1");
|
||||||
|
conf.add("ClientTransportPlugin obfs4 exec " +
|
||||||
|
obfs4File.getAbsolutePath());
|
||||||
conf.addAll(circumventionProvider.getBridges());
|
conf.addAll(circumventionProvider.getBridges());
|
||||||
controlConnection.setConf(conf);
|
controlConnection.setConf(conf);
|
||||||
} else {
|
} else {
|
||||||
@@ -568,7 +572,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
LOG.info("Could not connect to " + scrubOnion(bestOnion)
|
LOG.info("Could not connect to " + scrubOnion(bestOnion)
|
||||||
+ ": " + e.toString());
|
+ ": " + e.toString());
|
||||||
}
|
}
|
||||||
tryToClose(s);
|
IoUtils.tryToClose(s, LOG, WARNING);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -609,7 +613,8 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
LOG.info("OR connection " + status + " " + orName);
|
LOG.info("OR connection " + status + " " + orName);
|
||||||
if (status.equals("CLOSED") || status.equals("FAILED")) {
|
if (status.equals("CLOSED") || status.equals("FAILED")) {
|
||||||
// Check whether we've lost connectivity
|
// Check whether we've lost connectivity
|
||||||
updateConnectionStatus(networkManager.getNetworkStatus());
|
updateConnectionStatus(networkManager.getNetworkStatus(),
|
||||||
|
batteryManager.isCharging());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -644,13 +649,20 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
if (s.getNamespace().equals(ID.getString())) {
|
if (s.getNamespace().equals(ID.getString())) {
|
||||||
LOG.info("Tor settings updated");
|
LOG.info("Tor settings updated");
|
||||||
settings = s.getSettings();
|
settings = s.getSettings();
|
||||||
// Works around a bug introduced in Tor 0.3.4.8. Could be
|
// Works around a bug introduced in Tor 0.3.4.8.
|
||||||
// replaced with callback.transportDisabled() when fixed.
|
// https://trac.torproject.org/projects/tor/ticket/28027
|
||||||
|
// Could be replaced with callback.transportDisabled()
|
||||||
|
// when fixed.
|
||||||
disableNetwork();
|
disableNetwork();
|
||||||
updateConnectionStatus(networkManager.getNetworkStatus());
|
updateConnectionStatus(networkManager.getNetworkStatus(),
|
||||||
|
batteryManager.isCharging());
|
||||||
}
|
}
|
||||||
} else if (e instanceof NetworkStatusEvent) {
|
} else if (e instanceof NetworkStatusEvent) {
|
||||||
updateConnectionStatus(((NetworkStatusEvent) e).getStatus());
|
updateConnectionStatus(((NetworkStatusEvent) e).getStatus(),
|
||||||
|
batteryManager.isCharging());
|
||||||
|
} else if (e instanceof BatteryEvent) {
|
||||||
|
updateConnectionStatus(networkManager.getNetworkStatus(),
|
||||||
|
((BatteryEvent) e).isCharging());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -664,7 +676,8 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateConnectionStatus(NetworkStatus status) {
|
private void updateConnectionStatus(NetworkStatus status,
|
||||||
|
boolean charging) {
|
||||||
connectionStatusExecutor.execute(() -> {
|
connectionStatusExecutor.execute(() -> {
|
||||||
if (!running) return;
|
if (!running) return;
|
||||||
boolean online = status.isConnected();
|
boolean online = status.isConnected();
|
||||||
@@ -675,6 +688,8 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
int network = settings.getInt(PREF_TOR_NETWORK,
|
int network = settings.getInt(PREF_TOR_NETWORK,
|
||||||
PREF_TOR_NETWORK_AUTOMATIC);
|
PREF_TOR_NETWORK_AUTOMATIC);
|
||||||
boolean useMobile = settings.getBoolean(PREF_TOR_MOBILE, true);
|
boolean useMobile = settings.getBoolean(PREF_TOR_MOBILE, true);
|
||||||
|
boolean onlyWhenCharging =
|
||||||
|
settings.getBoolean(PREF_TOR_ONLY_WHEN_CHARGING, false);
|
||||||
boolean bridgesWork = circumventionProvider.doBridgesWork(country);
|
boolean bridgesWork = circumventionProvider.doBridgesWork(country);
|
||||||
boolean automatic = network == PREF_TOR_NETWORK_AUTOMATIC;
|
boolean automatic = network == PREF_TOR_NETWORK_AUTOMATIC;
|
||||||
|
|
||||||
@@ -682,15 +697,19 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
LOG.info("Online: " + online + ", wifi: " + wifi);
|
LOG.info("Online: " + online + ", wifi: " + wifi);
|
||||||
if ("".equals(country)) LOG.info("Country code unknown");
|
if ("".equals(country)) LOG.info("Country code unknown");
|
||||||
else LOG.info("Country code: " + country);
|
else LOG.info("Country code: " + country);
|
||||||
|
LOG.info("Charging: " + charging);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!online) {
|
if (!online) {
|
||||||
LOG.info("Disabling network, device is offline");
|
LOG.info("Disabling network, device is offline");
|
||||||
enableNetwork(false);
|
enableNetwork(false);
|
||||||
|
} else if (!charging && onlyWhenCharging) {
|
||||||
|
LOG.info("Disabling network, device is on battery");
|
||||||
|
enableNetwork(false);
|
||||||
} else if (network == PREF_TOR_NETWORK_NEVER ||
|
} else if (network == PREF_TOR_NETWORK_NEVER ||
|
||||||
(!useMobile && !wifi)) {
|
(!useMobile && !wifi)) {
|
||||||
LOG.info("Disabling network due to setting");
|
LOG.info("Disabling network, device is using mobile data");
|
||||||
enableNetwork(false);
|
enableNetwork(false);
|
||||||
} else if (automatic && blocked && !bridgesWork) {
|
} else if (automatic && blocked && !bridgesWork) {
|
||||||
LOG.info("Disabling network, country is blocked");
|
LOG.info("Disabling network, country is blocked");
|
||||||
@@ -705,12 +724,24 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
enableBridges(false);
|
enableBridges(false);
|
||||||
enableNetwork(true);
|
enableNetwork(true);
|
||||||
}
|
}
|
||||||
|
if (online && wifi && charging) {
|
||||||
|
LOG.info("Enabling connection padding");
|
||||||
|
enableConnectionPadding(true);
|
||||||
|
} else {
|
||||||
|
LOG.info("Disabling connection padding");
|
||||||
|
enableConnectionPadding(false);
|
||||||
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logException(LOG, WARNING, e);
|
logException(LOG, WARNING, e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void enableConnectionPadding(boolean enable) throws IOException {
|
||||||
|
if (!running) return;
|
||||||
|
controlConnection.setConf("ConnectionPadding", enable ? "1" : "0");
|
||||||
|
}
|
||||||
|
|
||||||
// TODO remove when sufficient time has passed. Added 2018-08-15
|
// TODO remove when sufficient time has passed. Added 2018-08-15
|
||||||
private void migrateSettings() {
|
private void migrateSettings() {
|
||||||
Settings sOld = callback.getSettings();
|
Settings sOld = callback.getSettings();
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import org.briarproject.bramble.api.contact.ContactManager;
|
|||||||
import org.briarproject.bramble.api.data.MetadataEncoder;
|
import org.briarproject.bramble.api.data.MetadataEncoder;
|
||||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||||
import org.briarproject.bramble.api.properties.TransportPropertyManager;
|
import org.briarproject.bramble.api.properties.TransportPropertyManager;
|
||||||
import org.briarproject.bramble.api.sync.ValidationManager;
|
import org.briarproject.bramble.api.sync.validation.ValidationManager;
|
||||||
import org.briarproject.bramble.api.system.Clock;
|
import org.briarproject.bramble.api.system.Clock;
|
||||||
import org.briarproject.bramble.api.versioning.ClientVersioningManager;
|
import org.briarproject.bramble.api.versioning.ClientVersioningManager;
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import org.briarproject.bramble.api.sync.GroupId;
|
|||||||
import org.briarproject.bramble.api.sync.InvalidMessageException;
|
import org.briarproject.bramble.api.sync.InvalidMessageException;
|
||||||
import org.briarproject.bramble.api.sync.Message;
|
import org.briarproject.bramble.api.sync.Message;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
import org.briarproject.bramble.api.sync.ValidationManager.IncomingMessageHook;
|
import org.briarproject.bramble.api.sync.validation.IncomingMessageHook;
|
||||||
import org.briarproject.bramble.api.system.Clock;
|
import org.briarproject.bramble.api.system.Clock;
|
||||||
import org.briarproject.bramble.api.versioning.ClientVersioningManager;
|
import org.briarproject.bramble.api.versioning.ClientVersioningManager;
|
||||||
import org.briarproject.bramble.api.versioning.ClientVersioningManager.ClientVersioningHook;
|
import org.briarproject.bramble.api.versioning.ClientVersioningManager.ClientVersioningHook;
|
||||||
@@ -142,15 +142,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
|||||||
@Override
|
@Override
|
||||||
public Map<TransportId, TransportProperties> getLocalProperties()
|
public Map<TransportId, TransportProperties> getLocalProperties()
|
||||||
throws DbException {
|
throws DbException {
|
||||||
Map<TransportId, TransportProperties> local;
|
return db.transactionWithResult(true, this::getLocalProperties);
|
||||||
Transaction txn = db.startTransaction(true);
|
|
||||||
try {
|
|
||||||
local = getLocalProperties(txn);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
return local;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -176,9 +168,8 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
|||||||
public TransportProperties getLocalProperties(TransportId t)
|
public TransportProperties getLocalProperties(TransportId t)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
try {
|
try {
|
||||||
|
return db.transactionWithResult(true, txn -> {
|
||||||
TransportProperties p = null;
|
TransportProperties p = null;
|
||||||
Transaction txn = db.startTransaction(true);
|
|
||||||
try {
|
|
||||||
// Find the latest local update
|
// Find the latest local update
|
||||||
LatestUpdate latest = findLatest(txn, localGroup.getId(), t,
|
LatestUpdate latest = findLatest(txn, localGroup.getId(), t,
|
||||||
true);
|
true);
|
||||||
@@ -188,11 +179,8 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
|||||||
latest.messageId);
|
latest.messageId);
|
||||||
p = parseProperties(message);
|
p = parseProperties(message);
|
||||||
}
|
}
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
return p == null ? new TransportProperties() : p;
|
return p == null ? new TransportProperties() : p;
|
||||||
|
});
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
@@ -201,16 +189,12 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
|||||||
@Override
|
@Override
|
||||||
public Map<ContactId, TransportProperties> getRemoteProperties(
|
public Map<ContactId, TransportProperties> getRemoteProperties(
|
||||||
TransportId t) throws DbException {
|
TransportId t) throws DbException {
|
||||||
|
return db.transactionWithResult(true, txn -> {
|
||||||
Map<ContactId, TransportProperties> remote = new HashMap<>();
|
Map<ContactId, TransportProperties> remote = new HashMap<>();
|
||||||
Transaction txn = db.startTransaction(true);
|
|
||||||
try {
|
|
||||||
for (Contact c : db.getContacts(txn))
|
for (Contact c : db.getContacts(txn))
|
||||||
remote.put(c.getId(), getRemoteProperties(txn, c, t));
|
remote.put(c.getId(), getRemoteProperties(txn, c, t));
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
return remote;
|
return remote;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private TransportProperties getRemoteProperties(Transaction txn, Contact c,
|
private TransportProperties getRemoteProperties(Transaction txn, Contact c,
|
||||||
@@ -234,23 +218,15 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
|||||||
@Override
|
@Override
|
||||||
public TransportProperties getRemoteProperties(ContactId c, TransportId t)
|
public TransportProperties getRemoteProperties(ContactId c, TransportId t)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
TransportProperties p;
|
return db.transactionWithResult(true, txn ->
|
||||||
Transaction txn = db.startTransaction(true);
|
getRemoteProperties(txn, db.getContact(txn, c), t));
|
||||||
try {
|
|
||||||
p = getRemoteProperties(txn, db.getContact(txn, c), t);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mergeLocalProperties(TransportId t, TransportProperties p)
|
public void mergeLocalProperties(TransportId t, TransportProperties p)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
try {
|
try {
|
||||||
Transaction txn = db.startTransaction(false);
|
db.transaction(false, txn -> {
|
||||||
try {
|
|
||||||
// Merge the new properties with any existing properties
|
// Merge the new properties with any existing properties
|
||||||
TransportProperties merged;
|
TransportProperties merged;
|
||||||
boolean changed;
|
boolean changed;
|
||||||
@@ -287,10 +263,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
|||||||
db.removeMessage(txn, latest.messageId);
|
db.removeMessage(txn, latest.messageId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
db.commitTransaction(txn);
|
});
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import org.briarproject.bramble.api.reporting.DevReporter;
|
|||||||
import org.briarproject.bramble.util.IoUtils;
|
import org.briarproject.bramble.util.IoUtils;
|
||||||
import org.briarproject.bramble.util.StringUtils;
|
import org.briarproject.bramble.util.StringUtils;
|
||||||
|
|
||||||
import java.io.Closeable;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
@@ -26,13 +25,12 @@ import java.net.Socket;
|
|||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.net.SocketFactory;
|
import javax.net.SocketFactory;
|
||||||
|
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
import static org.briarproject.bramble.util.IoUtils.tryToClose;
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
@@ -66,7 +64,7 @@ class DevReporterImpl implements DevReporter, EventListener {
|
|||||||
s.setSoTimeout(SOCKET_TIMEOUT);
|
s.setSoTimeout(SOCKET_TIMEOUT);
|
||||||
return s;
|
return s;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
tryToClose(s);
|
tryToClose(s, LOG, WARNING);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,8 +86,7 @@ class DevReporterImpl implements DevReporter, EventListener {
|
|||||||
writer.append(armoured);
|
writer.append(armoured);
|
||||||
writer.flush();
|
writer.flush();
|
||||||
} finally {
|
} finally {
|
||||||
if (writer != null)
|
tryToClose(writer, LOG, WARNING);
|
||||||
writer.close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,27 +118,11 @@ class DevReporterImpl implements DevReporter, EventListener {
|
|||||||
f.delete();
|
f.delete();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LOG.log(WARNING, "Failed to send reports", e);
|
LOG.log(WARNING, "Failed to send reports", e);
|
||||||
tryToClose(out);
|
tryToClose(out, LOG, WARNING);
|
||||||
tryToClose(in);
|
tryToClose(in, LOG, WARNING);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOG.info("Reports sent");
|
LOG.info("Reports sent");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tryToClose(@Nullable Closeable c) {
|
|
||||||
try {
|
|
||||||
if (c != null) c.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
logException(LOG, WARNING, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void tryToClose(@Nullable Socket s) {
|
|
||||||
try {
|
|
||||||
if (s != null) s.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
logException(LOG, WARNING, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,15 +23,8 @@ class SettingsManagerImpl implements SettingsManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Settings getSettings(String namespace) throws DbException {
|
public Settings getSettings(String namespace) throws DbException {
|
||||||
Settings s;
|
return db.transactionWithResult(true, txn ->
|
||||||
Transaction txn = db.startTransaction(true);
|
db.getSettings(txn, namespace));
|
||||||
try {
|
|
||||||
s = db.getSettings(txn, namespace);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -42,12 +35,6 @@ class SettingsManagerImpl implements SettingsManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mergeSettings(Settings s, String namespace) throws DbException {
|
public void mergeSettings(Settings s, String namespace) throws DbException {
|
||||||
Transaction txn = db.startTransaction(false);
|
db.transaction(false, txn -> db.mergeSettings(txn, s, namespace));
|
||||||
try {
|
|
||||||
db.mergeSettings(txn, s, namespace);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import org.briarproject.bramble.api.contact.event.ContactRemovedEvent;
|
|||||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.db.Transaction;
|
|
||||||
import org.briarproject.bramble.api.event.Event;
|
import org.briarproject.bramble.api.event.Event;
|
||||||
import org.briarproject.bramble.api.event.EventBus;
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
import org.briarproject.bramble.api.event.EventListener;
|
import org.briarproject.bramble.api.event.EventListener;
|
||||||
@@ -230,14 +229,8 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
|
|||||||
if (interrupted) return;
|
if (interrupted) return;
|
||||||
if (!generateAckQueued.getAndSet(false)) throw new AssertionError();
|
if (!generateAckQueued.getAndSet(false)) throw new AssertionError();
|
||||||
try {
|
try {
|
||||||
Ack a;
|
Ack a = db.transactionWithNullableResult(false, txn ->
|
||||||
Transaction txn = db.startTransaction(false);
|
db.generateAck(txn, contactId, MAX_MESSAGE_IDS));
|
||||||
try {
|
|
||||||
a = db.generateAck(txn, contactId, MAX_MESSAGE_IDS);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO))
|
||||||
LOG.info("Generated ack: " + (a != null));
|
LOG.info("Generated ack: " + (a != null));
|
||||||
if (a != null) writerTasks.add(new WriteAck(a));
|
if (a != null) writerTasks.add(new WriteAck(a));
|
||||||
@@ -275,16 +268,15 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
|
|||||||
if (!generateBatchQueued.getAndSet(false))
|
if (!generateBatchQueued.getAndSet(false))
|
||||||
throw new AssertionError();
|
throw new AssertionError();
|
||||||
try {
|
try {
|
||||||
Collection<Message> b;
|
Collection<Message> b =
|
||||||
Transaction txn = db.startTransaction(false);
|
db.transactionWithNullableResult(false, txn -> {
|
||||||
try {
|
Collection<Message> batch =
|
||||||
b = db.generateRequestedBatch(txn, contactId,
|
db.generateRequestedBatch(txn, contactId,
|
||||||
MAX_RECORD_PAYLOAD_BYTES, maxLatency);
|
MAX_RECORD_PAYLOAD_BYTES,
|
||||||
|
maxLatency);
|
||||||
setNextSendTime(db.getNextSendTime(txn, contactId));
|
setNextSendTime(db.getNextSendTime(txn, contactId));
|
||||||
db.commitTransaction(txn);
|
return batch;
|
||||||
} finally {
|
});
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO))
|
||||||
LOG.info("Generated batch: " + (b != null));
|
LOG.info("Generated batch: " + (b != null));
|
||||||
if (b != null) writerTasks.add(new WriteBatch(b));
|
if (b != null) writerTasks.add(new WriteBatch(b));
|
||||||
@@ -322,16 +314,12 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
|
|||||||
if (!generateOfferQueued.getAndSet(false))
|
if (!generateOfferQueued.getAndSet(false))
|
||||||
throw new AssertionError();
|
throw new AssertionError();
|
||||||
try {
|
try {
|
||||||
Offer o;
|
Offer o = db.transactionWithNullableResult(false, txn -> {
|
||||||
Transaction txn = db.startTransaction(false);
|
Offer offer = db.generateOffer(txn, contactId,
|
||||||
try {
|
MAX_MESSAGE_IDS, maxLatency);
|
||||||
o = db.generateOffer(txn, contactId, MAX_MESSAGE_IDS,
|
|
||||||
maxLatency);
|
|
||||||
setNextSendTime(db.getNextSendTime(txn, contactId));
|
setNextSendTime(db.getNextSendTime(txn, contactId));
|
||||||
db.commitTransaction(txn);
|
return offer;
|
||||||
} finally {
|
});
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO))
|
||||||
LOG.info("Generated offer: " + (o != null));
|
LOG.info("Generated offer: " + (o != null));
|
||||||
if (o != null) writerTasks.add(new WriteOffer(o));
|
if (o != null) writerTasks.add(new WriteOffer(o));
|
||||||
@@ -369,14 +357,8 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
|
|||||||
if (!generateRequestQueued.getAndSet(false))
|
if (!generateRequestQueued.getAndSet(false))
|
||||||
throw new AssertionError();
|
throw new AssertionError();
|
||||||
try {
|
try {
|
||||||
Request r;
|
Request r = db.transactionWithNullableResult(false, txn ->
|
||||||
Transaction txn = db.startTransaction(false);
|
db.generateRequest(txn, contactId, MAX_MESSAGE_IDS));
|
||||||
try {
|
|
||||||
r = db.generateRequest(txn, contactId, MAX_MESSAGE_IDS);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO))
|
||||||
LOG.info("Generated request: " + (r != null));
|
LOG.info("Generated request: " + (r != null));
|
||||||
if (r != null) writerTasks.add(new WriteRequest(r));
|
if (r != null) writerTasks.add(new WriteRequest(r));
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import org.briarproject.bramble.api.contact.event.ContactRemovedEvent;
|
|||||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.db.Transaction;
|
|
||||||
import org.briarproject.bramble.api.event.Event;
|
import org.briarproject.bramble.api.event.Event;
|
||||||
import org.briarproject.bramble.api.event.EventBus;
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
import org.briarproject.bramble.api.event.EventListener;
|
import org.briarproject.bramble.api.event.EventListener;
|
||||||
@@ -120,13 +119,8 @@ class IncomingSession implements SyncSession, EventListener {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
Transaction txn = db.startTransaction(false);
|
db.transaction(false, txn ->
|
||||||
try {
|
db.receiveAck(txn, contactId, ack));
|
||||||
db.receiveAck(txn, contactId, ack);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
logException(LOG, WARNING, e);
|
logException(LOG, WARNING, e);
|
||||||
interrupt();
|
interrupt();
|
||||||
@@ -146,13 +140,8 @@ class IncomingSession implements SyncSession, EventListener {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
Transaction txn = db.startTransaction(false);
|
db.transaction(false, txn ->
|
||||||
try {
|
db.receiveMessage(txn, contactId, message));
|
||||||
db.receiveMessage(txn, contactId, message);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
logException(LOG, WARNING, e);
|
logException(LOG, WARNING, e);
|
||||||
interrupt();
|
interrupt();
|
||||||
@@ -172,13 +161,8 @@ class IncomingSession implements SyncSession, EventListener {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
Transaction txn = db.startTransaction(false);
|
db.transaction(false, txn ->
|
||||||
try {
|
db.receiveOffer(txn, contactId, offer));
|
||||||
db.receiveOffer(txn, contactId, offer);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
logException(LOG, WARNING, e);
|
logException(LOG, WARNING, e);
|
||||||
interrupt();
|
interrupt();
|
||||||
@@ -198,13 +182,8 @@ class IncomingSession implements SyncSession, EventListener {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
Transaction txn = db.startTransaction(false);
|
db.transaction(false, txn ->
|
||||||
try {
|
db.receiveRequest(txn, contactId, request));
|
||||||
db.receiveRequest(txn, contactId, request);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
logException(LOG, WARNING, e);
|
logException(LOG, WARNING, e);
|
||||||
interrupt();
|
interrupt();
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import org.briarproject.bramble.api.contact.event.ContactRemovedEvent;
|
|||||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.db.Transaction;
|
|
||||||
import org.briarproject.bramble.api.event.Event;
|
import org.briarproject.bramble.api.event.Event;
|
||||||
import org.briarproject.bramble.api.event.EventBus;
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
import org.briarproject.bramble.api.event.EventListener;
|
import org.briarproject.bramble.api.event.EventListener;
|
||||||
@@ -47,7 +46,8 @@ class SimplexOutgoingSession implements SyncSession, EventListener {
|
|||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(SimplexOutgoingSession.class.getName());
|
Logger.getLogger(SimplexOutgoingSession.class.getName());
|
||||||
|
|
||||||
private static final ThrowingRunnable<IOException> CLOSE = () -> {};
|
private static final ThrowingRunnable<IOException> CLOSE = () -> {
|
||||||
|
};
|
||||||
|
|
||||||
private final DatabaseComponent db;
|
private final DatabaseComponent db;
|
||||||
private final Executor dbExecutor;
|
private final Executor dbExecutor;
|
||||||
@@ -128,14 +128,8 @@ class SimplexOutgoingSession implements SyncSession, EventListener {
|
|||||||
public void run() {
|
public void run() {
|
||||||
if (interrupted) return;
|
if (interrupted) return;
|
||||||
try {
|
try {
|
||||||
Ack a;
|
Ack a = db.transactionWithNullableResult(false, txn ->
|
||||||
Transaction txn = db.startTransaction(false);
|
db.generateAck(txn, contactId, MAX_MESSAGE_IDS));
|
||||||
try {
|
|
||||||
a = db.generateAck(txn, contactId, MAX_MESSAGE_IDS);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO))
|
||||||
LOG.info("Generated ack: " + (a != null));
|
LOG.info("Generated ack: " + (a != null));
|
||||||
if (a == null) decrementOutstandingQueries();
|
if (a == null) decrementOutstandingQueries();
|
||||||
@@ -172,15 +166,10 @@ class SimplexOutgoingSession implements SyncSession, EventListener {
|
|||||||
public void run() {
|
public void run() {
|
||||||
if (interrupted) return;
|
if (interrupted) return;
|
||||||
try {
|
try {
|
||||||
Collection<Message> b;
|
Collection<Message> b =
|
||||||
Transaction txn = db.startTransaction(false);
|
db.transactionWithNullableResult(false, txn ->
|
||||||
try {
|
db.generateBatch(txn, contactId,
|
||||||
b = db.generateBatch(txn, contactId,
|
MAX_RECORD_PAYLOAD_BYTES, maxLatency));
|
||||||
MAX_RECORD_PAYLOAD_BYTES, maxLatency);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO))
|
||||||
LOG.info("Generated batch: " + (b != null));
|
LOG.info("Generated batch: " + (b != null));
|
||||||
if (b == null) decrementOutstandingQueries();
|
if (b == null) decrementOutstandingQueries();
|
||||||
|
|||||||
@@ -1,23 +1,11 @@
|
|||||||
package org.briarproject.bramble.sync;
|
package org.briarproject.bramble.sync;
|
||||||
|
|
||||||
import org.briarproject.bramble.PoliteExecutor;
|
|
||||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
|
||||||
import org.briarproject.bramble.api.crypto.CryptoExecutor;
|
|
||||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
|
||||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
|
||||||
import org.briarproject.bramble.api.event.EventBus;
|
|
||||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
|
||||||
import org.briarproject.bramble.api.sync.GroupFactory;
|
import org.briarproject.bramble.api.sync.GroupFactory;
|
||||||
import org.briarproject.bramble.api.sync.MessageFactory;
|
import org.briarproject.bramble.api.sync.MessageFactory;
|
||||||
import org.briarproject.bramble.api.sync.SyncRecordReaderFactory;
|
import org.briarproject.bramble.api.sync.SyncRecordReaderFactory;
|
||||||
import org.briarproject.bramble.api.sync.SyncRecordWriterFactory;
|
import org.briarproject.bramble.api.sync.SyncRecordWriterFactory;
|
||||||
import org.briarproject.bramble.api.sync.SyncSessionFactory;
|
import org.briarproject.bramble.api.sync.SyncSessionFactory;
|
||||||
import org.briarproject.bramble.api.sync.ValidationManager;
|
|
||||||
import org.briarproject.bramble.api.system.Clock;
|
|
||||||
|
|
||||||
import java.util.concurrent.Executor;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import dagger.Module;
|
import dagger.Module;
|
||||||
@@ -26,29 +14,14 @@ import dagger.Provides;
|
|||||||
@Module
|
@Module
|
||||||
public class SyncModule {
|
public class SyncModule {
|
||||||
|
|
||||||
public static class EagerSingletons {
|
|
||||||
@Inject
|
|
||||||
ValidationManager validationManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The maximum number of validation tasks to delegate to the crypto
|
|
||||||
* executor concurrently.
|
|
||||||
* <p>
|
|
||||||
* The number of available processors can change during the lifetime of the
|
|
||||||
* JVM, so this is just a reasonable guess.
|
|
||||||
*/
|
|
||||||
private static final int MAX_CONCURRENT_VALIDATION_TASKS =
|
|
||||||
Math.max(1, Runtime.getRuntime().availableProcessors() - 1);
|
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
GroupFactory provideGroupFactory(CryptoComponent crypto) {
|
GroupFactory provideGroupFactory(GroupFactoryImpl groupFactory) {
|
||||||
return new GroupFactoryImpl(crypto);
|
return groupFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
MessageFactory provideMessageFactory(CryptoComponent crypto) {
|
MessageFactory provideMessageFactory(MessageFactoryImpl messageFactory) {
|
||||||
return new MessageFactoryImpl(crypto);
|
return messageFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@@ -65,30 +38,8 @@ public class SyncModule {
|
|||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
SyncSessionFactory provideSyncSessionFactory(DatabaseComponent db,
|
SyncSessionFactory provideSyncSessionFactory(
|
||||||
@DatabaseExecutor Executor dbExecutor, EventBus eventBus,
|
SyncSessionFactoryImpl syncSessionFactory) {
|
||||||
Clock clock, SyncRecordReaderFactory recordReaderFactory,
|
return syncSessionFactory;
|
||||||
SyncRecordWriterFactory recordWriterFactory) {
|
|
||||||
return new SyncSessionFactoryImpl(db, dbExecutor, eventBus, clock,
|
|
||||||
recordReaderFactory, recordWriterFactory);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
ValidationManager provideValidationManager(
|
|
||||||
LifecycleManager lifecycleManager, EventBus eventBus,
|
|
||||||
ValidationManagerImpl validationManager) {
|
|
||||||
lifecycleManager.registerService(validationManager);
|
|
||||||
eventBus.addListener(validationManager);
|
|
||||||
return validationManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
@ValidationExecutor
|
|
||||||
Executor provideValidationExecutor(
|
|
||||||
@CryptoExecutor Executor cryptoExecutor) {
|
|
||||||
return new PoliteExecutor("ValidationExecutor", cryptoExecutor,
|
|
||||||
MAX_CONCURRENT_VALIDATION_TASKS);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.briarproject.bramble.sync;
|
package org.briarproject.bramble.sync.validation;
|
||||||
|
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.briarproject.bramble.sync;
|
package org.briarproject.bramble.sync.validation;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.Pair;
|
||||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
@@ -17,8 +18,11 @@ import org.briarproject.bramble.api.sync.InvalidMessageException;
|
|||||||
import org.briarproject.bramble.api.sync.Message;
|
import org.briarproject.bramble.api.sync.Message;
|
||||||
import org.briarproject.bramble.api.sync.MessageContext;
|
import org.briarproject.bramble.api.sync.MessageContext;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
import org.briarproject.bramble.api.sync.ValidationManager;
|
|
||||||
import org.briarproject.bramble.api.sync.event.MessageAddedEvent;
|
import org.briarproject.bramble.api.sync.event.MessageAddedEvent;
|
||||||
|
import org.briarproject.bramble.api.sync.validation.IncomingMessageHook;
|
||||||
|
import org.briarproject.bramble.api.sync.validation.MessageState;
|
||||||
|
import org.briarproject.bramble.api.sync.validation.MessageValidator;
|
||||||
|
import org.briarproject.bramble.api.sync.validation.ValidationManager;
|
||||||
import org.briarproject.bramble.api.versioning.ClientMajorVersion;
|
import org.briarproject.bramble.api.versioning.ClientMajorVersion;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -36,9 +40,9 @@ import javax.inject.Inject;
|
|||||||
|
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static org.briarproject.bramble.api.sync.ValidationManager.State.DELIVERED;
|
import static org.briarproject.bramble.api.sync.validation.MessageState.DELIVERED;
|
||||||
import static org.briarproject.bramble.api.sync.ValidationManager.State.INVALID;
|
import static org.briarproject.bramble.api.sync.validation.MessageState.INVALID;
|
||||||
import static org.briarproject.bramble.api.sync.ValidationManager.State.PENDING;
|
import static org.briarproject.bramble.api.sync.validation.MessageState.PENDING;
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
|
|
||||||
@ThreadSafe
|
@ThreadSafe
|
||||||
@@ -97,14 +101,8 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
|||||||
@DatabaseExecutor
|
@DatabaseExecutor
|
||||||
private void validateOutstandingMessages() {
|
private void validateOutstandingMessages() {
|
||||||
try {
|
try {
|
||||||
Queue<MessageId> unvalidated = new LinkedList<>();
|
Queue<MessageId> unvalidated = new LinkedList<>(
|
||||||
Transaction txn = db.startTransaction(true);
|
db.transactionWithResult(true, db::getMessagesToValidate));
|
||||||
try {
|
|
||||||
unvalidated.addAll(db.getMessagesToValidate(txn));
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
validateNextMessageAsync(unvalidated);
|
validateNextMessageAsync(unvalidated);
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
logException(LOG, WARNING, e);
|
logException(LOG, WARNING, e);
|
||||||
@@ -119,18 +117,14 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
|||||||
@DatabaseExecutor
|
@DatabaseExecutor
|
||||||
private void validateNextMessage(Queue<MessageId> unvalidated) {
|
private void validateNextMessage(Queue<MessageId> unvalidated) {
|
||||||
try {
|
try {
|
||||||
Message m;
|
Pair<Message, Group> mg = db.transactionWithResult(true, txn -> {
|
||||||
Group g;
|
|
||||||
Transaction txn = db.startTransaction(true);
|
|
||||||
try {
|
|
||||||
MessageId id = unvalidated.poll();
|
MessageId id = unvalidated.poll();
|
||||||
m = db.getMessage(txn, id);
|
if (id == null) throw new AssertionError();
|
||||||
g = db.getGroup(txn, m.getGroupId());
|
Message m = db.getMessage(txn, id);
|
||||||
db.commitTransaction(txn);
|
Group g = db.getGroup(txn, m.getGroupId());
|
||||||
} finally {
|
return new Pair<>(m, g);
|
||||||
db.endTransaction(txn);
|
});
|
||||||
}
|
validateMessageAsync(mg.getFirst(), mg.getSecond());
|
||||||
validateMessageAsync(m, g);
|
|
||||||
validateNextMessageAsync(unvalidated);
|
validateNextMessageAsync(unvalidated);
|
||||||
} catch (NoSuchMessageException e) {
|
} catch (NoSuchMessageException e) {
|
||||||
LOG.info("Message removed before validation");
|
LOG.info("Message removed before validation");
|
||||||
@@ -150,14 +144,8 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
|||||||
@DatabaseExecutor
|
@DatabaseExecutor
|
||||||
private void deliverOutstandingMessages() {
|
private void deliverOutstandingMessages() {
|
||||||
try {
|
try {
|
||||||
Queue<MessageId> pending = new LinkedList<>();
|
Queue<MessageId> pending = new LinkedList<>(
|
||||||
Transaction txn = db.startTransaction(true);
|
db.transactionWithResult(true, db::getPendingMessages));
|
||||||
try {
|
|
||||||
pending.addAll(db.getPendingMessages(txn));
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
deliverNextPendingMessageAsync(pending);
|
deliverNextPendingMessageAsync(pending);
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
logException(LOG, WARNING, e);
|
logException(LOG, WARNING, e);
|
||||||
@@ -172,24 +160,24 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
|||||||
@DatabaseExecutor
|
@DatabaseExecutor
|
||||||
private void deliverNextPendingMessage(Queue<MessageId> pending) {
|
private void deliverNextPendingMessage(Queue<MessageId> pending) {
|
||||||
try {
|
try {
|
||||||
|
Queue<MessageId> toShare = new LinkedList<>();
|
||||||
|
Queue<MessageId> invalidate = new LinkedList<>();
|
||||||
|
db.transaction(false, txn -> {
|
||||||
boolean anyInvalid = false, allDelivered = true;
|
boolean anyInvalid = false, allDelivered = true;
|
||||||
Queue<MessageId> toShare = null;
|
|
||||||
Queue<MessageId> invalidate = null;
|
|
||||||
Transaction txn = db.startTransaction(false);
|
|
||||||
try {
|
|
||||||
MessageId id = pending.poll();
|
MessageId id = pending.poll();
|
||||||
|
if (id == null) throw new AssertionError();
|
||||||
// Check if message is still pending
|
// Check if message is still pending
|
||||||
if (db.getMessageState(txn, id) == PENDING) {
|
if (db.getMessageState(txn, id) == PENDING) {
|
||||||
// Check if dependencies are valid and delivered
|
// Check if dependencies are valid and delivered
|
||||||
Map<MessageId, State> states =
|
Map<MessageId, MessageState> states =
|
||||||
db.getMessageDependencies(txn, id);
|
db.getMessageDependencies(txn, id);
|
||||||
for (Entry<MessageId, State> e : states.entrySet()) {
|
for (Entry<MessageId, MessageState> e : states.entrySet()) {
|
||||||
if (e.getValue() == INVALID) anyInvalid = true;
|
if (e.getValue() == INVALID) anyInvalid = true;
|
||||||
if (e.getValue() != DELIVERED) allDelivered = false;
|
if (e.getValue() != DELIVERED) allDelivered = false;
|
||||||
}
|
}
|
||||||
if (anyInvalid) {
|
if (anyInvalid) {
|
||||||
invalidateMessage(txn, id);
|
invalidateMessage(txn, id);
|
||||||
invalidate = getDependentsToInvalidate(txn, id);
|
addDependentsToInvalidate(txn, id, invalidate);
|
||||||
} else if (allDelivered) {
|
} else if (allDelivered) {
|
||||||
Message m = db.getMessage(txn, id);
|
Message m = db.getMessage(txn, id);
|
||||||
Group g = db.getGroup(txn, m.getGroupId());
|
Group g = db.getGroup(txn, m.getGroupId());
|
||||||
@@ -200,22 +188,19 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
|||||||
DeliveryResult result =
|
DeliveryResult result =
|
||||||
deliverMessage(txn, m, c, majorVersion, meta);
|
deliverMessage(txn, m, c, majorVersion, meta);
|
||||||
if (result.valid) {
|
if (result.valid) {
|
||||||
pending.addAll(getPendingDependents(txn, id));
|
addPendingDependents(txn, id, pending);
|
||||||
if (result.share) {
|
if (result.share) {
|
||||||
db.setMessageShared(txn, id);
|
db.setMessageShared(txn, id);
|
||||||
toShare = new LinkedList<>(states.keySet());
|
toShare.addAll(states.keySet());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
invalidate = getDependentsToInvalidate(txn, id);
|
addDependentsToInvalidate(txn, id, invalidate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
db.commitTransaction(txn);
|
});
|
||||||
} finally {
|
if (!invalidate.isEmpty()) invalidateNextMessageAsync(invalidate);
|
||||||
db.endTransaction(txn);
|
if (!toShare.isEmpty()) shareNextMessageAsync(toShare);
|
||||||
}
|
|
||||||
if (invalidate != null) invalidateNextMessageAsync(invalidate);
|
|
||||||
if (toShare != null) shareNextMessageAsync(toShare);
|
|
||||||
deliverNextPendingMessageAsync(pending);
|
deliverNextPendingMessageAsync(pending);
|
||||||
} catch (NoSuchMessageException e) {
|
} catch (NoSuchMessageException e) {
|
||||||
LOG.info("Message removed before delivery");
|
LOG.info("Message removed before delivery");
|
||||||
@@ -264,20 +249,19 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
|||||||
MessageContext context) {
|
MessageContext context) {
|
||||||
try {
|
try {
|
||||||
MessageId id = m.getId();
|
MessageId id = m.getId();
|
||||||
|
Queue<MessageId> invalidate = new LinkedList<>();
|
||||||
|
Queue<MessageId> pending = new LinkedList<>();
|
||||||
|
Queue<MessageId> toShare = new LinkedList<>();
|
||||||
|
db.transaction(false, txn -> {
|
||||||
boolean anyInvalid = false, allDelivered = true;
|
boolean anyInvalid = false, allDelivered = true;
|
||||||
Queue<MessageId> invalidate = null;
|
|
||||||
Queue<MessageId> pending = null;
|
|
||||||
Queue<MessageId> toShare = null;
|
|
||||||
Transaction txn = db.startTransaction(false);
|
|
||||||
try {
|
|
||||||
// Check if message has any dependencies
|
// Check if message has any dependencies
|
||||||
Collection<MessageId> dependencies = context.getDependencies();
|
Collection<MessageId> dependencies = context.getDependencies();
|
||||||
if (!dependencies.isEmpty()) {
|
if (!dependencies.isEmpty()) {
|
||||||
db.addMessageDependencies(txn, m, dependencies);
|
db.addMessageDependencies(txn, m, dependencies);
|
||||||
// Check if dependencies are valid and delivered
|
// Check if dependencies are valid and delivered
|
||||||
Map<MessageId, State> states =
|
Map<MessageId, MessageState> states =
|
||||||
db.getMessageDependencies(txn, id);
|
db.getMessageDependencies(txn, id);
|
||||||
for (Entry<MessageId, State> e : states.entrySet()) {
|
for (Entry<MessageId, MessageState> e : states.entrySet()) {
|
||||||
if (e.getValue() == INVALID) anyInvalid = true;
|
if (e.getValue() == INVALID) anyInvalid = true;
|
||||||
if (e.getValue() != DELIVERED) allDelivered = false;
|
if (e.getValue() != DELIVERED) allDelivered = false;
|
||||||
}
|
}
|
||||||
@@ -285,7 +269,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
|||||||
if (anyInvalid) {
|
if (anyInvalid) {
|
||||||
if (db.getMessageState(txn, id) != INVALID) {
|
if (db.getMessageState(txn, id) != INVALID) {
|
||||||
invalidateMessage(txn, id);
|
invalidateMessage(txn, id);
|
||||||
invalidate = getDependentsToInvalidate(txn, id);
|
addDependentsToInvalidate(txn, id, invalidate);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Metadata meta = context.getMetadata();
|
Metadata meta = context.getMetadata();
|
||||||
@@ -294,25 +278,22 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
|||||||
DeliveryResult result =
|
DeliveryResult result =
|
||||||
deliverMessage(txn, m, c, majorVersion, meta);
|
deliverMessage(txn, m, c, majorVersion, meta);
|
||||||
if (result.valid) {
|
if (result.valid) {
|
||||||
pending = getPendingDependents(txn, id);
|
addPendingDependents(txn, id, pending);
|
||||||
if (result.share) {
|
if (result.share) {
|
||||||
db.setMessageShared(txn, id);
|
db.setMessageShared(txn, id);
|
||||||
toShare = new LinkedList<>(dependencies);
|
toShare.addAll(dependencies);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
invalidate = getDependentsToInvalidate(txn, id);
|
addDependentsToInvalidate(txn, id, invalidate);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
db.setMessageState(txn, id, PENDING);
|
db.setMessageState(txn, id, PENDING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
db.commitTransaction(txn);
|
});
|
||||||
} finally {
|
if (!invalidate.isEmpty()) invalidateNextMessageAsync(invalidate);
|
||||||
db.endTransaction(txn);
|
if (!pending.isEmpty()) deliverNextPendingMessageAsync(pending);
|
||||||
}
|
if (!toShare.isEmpty()) shareNextMessageAsync(toShare);
|
||||||
if (invalidate != null) invalidateNextMessageAsync(invalidate);
|
|
||||||
if (pending != null) deliverNextPendingMessageAsync(pending);
|
|
||||||
if (toShare != null) shareNextMessageAsync(toShare);
|
|
||||||
} catch (NoSuchMessageException e) {
|
} catch (NoSuchMessageException e) {
|
||||||
LOG.info("Message removed during validation");
|
LOG.info("Message removed during validation");
|
||||||
} catch (NoSuchGroupException e) {
|
} catch (NoSuchGroupException e) {
|
||||||
@@ -342,14 +323,12 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@DatabaseExecutor
|
@DatabaseExecutor
|
||||||
private Queue<MessageId> getPendingDependents(Transaction txn, MessageId m)
|
private void addPendingDependents(Transaction txn, MessageId m,
|
||||||
throws DbException {
|
Queue<MessageId> pending) throws DbException {
|
||||||
Queue<MessageId> pending = new LinkedList<>();
|
Map<MessageId, MessageState> states = db.getMessageDependents(txn, m);
|
||||||
Map<MessageId, State> states = db.getMessageDependents(txn, m);
|
for (Entry<MessageId, MessageState> e : states.entrySet()) {
|
||||||
for (Entry<MessageId, State> e : states.entrySet()) {
|
|
||||||
if (e.getValue() == PENDING) pending.add(e.getKey());
|
if (e.getValue() == PENDING) pending.add(e.getKey());
|
||||||
}
|
}
|
||||||
return pending;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void shareOutstandingMessagesAsync() {
|
private void shareOutstandingMessagesAsync() {
|
||||||
@@ -359,14 +338,8 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
|||||||
@DatabaseExecutor
|
@DatabaseExecutor
|
||||||
private void shareOutstandingMessages() {
|
private void shareOutstandingMessages() {
|
||||||
try {
|
try {
|
||||||
Queue<MessageId> toShare = new LinkedList<>();
|
Queue<MessageId> toShare = new LinkedList<>(
|
||||||
Transaction txn = db.startTransaction(true);
|
db.transactionWithResult(true, db::getMessagesToShare));
|
||||||
try {
|
|
||||||
toShare.addAll(db.getMessagesToShare(txn));
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
shareNextMessageAsync(toShare);
|
shareNextMessageAsync(toShare);
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
logException(LOG, WARNING, e);
|
logException(LOG, WARNING, e);
|
||||||
@@ -387,15 +360,12 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
|||||||
@DatabaseExecutor
|
@DatabaseExecutor
|
||||||
private void shareNextMessage(Queue<MessageId> toShare) {
|
private void shareNextMessage(Queue<MessageId> toShare) {
|
||||||
try {
|
try {
|
||||||
Transaction txn = db.startTransaction(false);
|
db.transaction(false, txn -> {
|
||||||
try {
|
|
||||||
MessageId id = toShare.poll();
|
MessageId id = toShare.poll();
|
||||||
|
if (id == null) throw new AssertionError();
|
||||||
db.setMessageShared(txn, id);
|
db.setMessageShared(txn, id);
|
||||||
toShare.addAll(db.getMessageDependencies(txn, id).keySet());
|
toShare.addAll(db.getMessageDependencies(txn, id).keySet());
|
||||||
db.commitTransaction(txn);
|
});
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
shareNextMessageAsync(toShare);
|
shareNextMessageAsync(toShare);
|
||||||
} catch (NoSuchMessageException e) {
|
} catch (NoSuchMessageException e) {
|
||||||
LOG.info("Message removed before sharing");
|
LOG.info("Message removed before sharing");
|
||||||
@@ -416,17 +386,14 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
|||||||
@DatabaseExecutor
|
@DatabaseExecutor
|
||||||
private void invalidateNextMessage(Queue<MessageId> invalidate) {
|
private void invalidateNextMessage(Queue<MessageId> invalidate) {
|
||||||
try {
|
try {
|
||||||
Transaction txn = db.startTransaction(false);
|
db.transaction(false, txn -> {
|
||||||
try {
|
|
||||||
MessageId id = invalidate.poll();
|
MessageId id = invalidate.poll();
|
||||||
|
if (id == null) throw new AssertionError();
|
||||||
if (db.getMessageState(txn, id) != INVALID) {
|
if (db.getMessageState(txn, id) != INVALID) {
|
||||||
invalidateMessage(txn, id);
|
invalidateMessage(txn, id);
|
||||||
invalidate.addAll(getDependentsToInvalidate(txn, id));
|
addDependentsToInvalidate(txn, id, invalidate);
|
||||||
}
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
invalidateNextMessageAsync(invalidate);
|
invalidateNextMessageAsync(invalidate);
|
||||||
} catch (NoSuchMessageException e) {
|
} catch (NoSuchMessageException e) {
|
||||||
LOG.info("Message removed before invalidation");
|
LOG.info("Message removed before invalidation");
|
||||||
@@ -445,14 +412,12 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@DatabaseExecutor
|
@DatabaseExecutor
|
||||||
private Queue<MessageId> getDependentsToInvalidate(Transaction txn,
|
private void addDependentsToInvalidate(Transaction txn,
|
||||||
MessageId m) throws DbException {
|
MessageId m, Queue<MessageId> invalidate) throws DbException {
|
||||||
Queue<MessageId> invalidate = new LinkedList<>();
|
Map<MessageId, MessageState> states = db.getMessageDependents(txn, m);
|
||||||
Map<MessageId, State> states = db.getMessageDependents(txn, m);
|
for (Entry<MessageId, MessageState> e : states.entrySet()) {
|
||||||
for (Entry<MessageId, State> e : states.entrySet()) {
|
|
||||||
if (e.getValue() != INVALID) invalidate.add(e.getKey());
|
if (e.getValue() != INVALID) invalidate.add(e.getKey());
|
||||||
}
|
}
|
||||||
return invalidate;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -472,14 +437,8 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
|||||||
@DatabaseExecutor
|
@DatabaseExecutor
|
||||||
private void loadGroupAndValidate(Message m) {
|
private void loadGroupAndValidate(Message m) {
|
||||||
try {
|
try {
|
||||||
Group g;
|
Group g = db.transactionWithResult(true, txn ->
|
||||||
Transaction txn = db.startTransaction(true);
|
db.getGroup(txn, m.getGroupId()));
|
||||||
try {
|
|
||||||
g = db.getGroup(txn, m.getGroupId());
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
validateMessageAsync(m, g);
|
validateMessageAsync(m, g);
|
||||||
} catch (NoSuchGroupException e) {
|
} catch (NoSuchGroupException e) {
|
||||||
LOG.info("Group removed before validation");
|
LOG.info("Group removed before validation");
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package org.briarproject.bramble.sync.validation;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.PoliteExecutor;
|
||||||
|
import org.briarproject.bramble.api.crypto.CryptoExecutor;
|
||||||
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||||
|
import org.briarproject.bramble.api.sync.validation.ValidationManager;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import dagger.Module;
|
||||||
|
import dagger.Provides;
|
||||||
|
|
||||||
|
@Module
|
||||||
|
public class ValidationModule {
|
||||||
|
|
||||||
|
public static class EagerSingletons {
|
||||||
|
@Inject
|
||||||
|
ValidationManager validationManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum number of validation tasks to delegate to the crypto
|
||||||
|
* executor concurrently.
|
||||||
|
* <p>
|
||||||
|
* The number of available processors can change during the lifetime of the
|
||||||
|
* JVM, so this is just a reasonable guess.
|
||||||
|
*/
|
||||||
|
private static final int MAX_CONCURRENT_VALIDATION_TASKS =
|
||||||
|
Math.max(1, Runtime.getRuntime().availableProcessors() - 1);
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
ValidationManager provideValidationManager(
|
||||||
|
LifecycleManager lifecycleManager, EventBus eventBus,
|
||||||
|
ValidationManagerImpl validationManager) {
|
||||||
|
lifecycleManager.registerService(validationManager);
|
||||||
|
eventBus.addListener(validationManager);
|
||||||
|
return validationManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@ValidationExecutor
|
||||||
|
Executor provideValidationExecutor(
|
||||||
|
@CryptoExecutor Executor cryptoExecutor) {
|
||||||
|
return new PoliteExecutor("ValidationExecutor", cryptoExecutor,
|
||||||
|
MAX_CONCURRENT_VALIDATION_TASKS);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,32 +13,33 @@ import java.util.logging.Logger;
|
|||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
import static java.util.logging.Level.WARNING;
|
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.LogUtils.logException;
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class LinuxSecureRandomProvider extends AbstractSecureRandomProvider {
|
class UnixSecureRandomProvider extends AbstractSecureRandomProvider {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(LinuxSecureRandomProvider.class.getName());
|
getLogger(UnixSecureRandomProvider.class.getName());
|
||||||
|
|
||||||
private static final File RANDOM_DEVICE = new File("/dev/urandom");
|
private static final File RANDOM_DEVICE = new File("/dev/urandom");
|
||||||
|
|
||||||
private final AtomicBoolean seeded = new AtomicBoolean(false);
|
private final AtomicBoolean seeded = new AtomicBoolean(false);
|
||||||
private final File outputDevice;
|
private final File outputDevice;
|
||||||
|
|
||||||
LinuxSecureRandomProvider() {
|
UnixSecureRandomProvider() {
|
||||||
this(RANDOM_DEVICE);
|
this(RANDOM_DEVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
LinuxSecureRandomProvider(File outputDevice) {
|
UnixSecureRandomProvider(File outputDevice) {
|
||||||
this.outputDevice = outputDevice;
|
this.outputDevice = outputDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Provider getProvider() {
|
public Provider getProvider() {
|
||||||
if (!seeded.getAndSet(true)) writeSeed();
|
if (!seeded.getAndSet(true)) writeSeed();
|
||||||
return new LinuxProvider();
|
return new UnixProvider();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void writeSeed() {
|
protected void writeSeed() {
|
||||||
@@ -55,15 +56,15 @@ class LinuxSecureRandomProvider extends AbstractSecureRandomProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Based on https://android-developers.googleblog.com/2013/08/some-securerandom-thoughts.html
|
// Based on https://android-developers.googleblog.com/2013/08/some-securerandom-thoughts.html
|
||||||
private static class LinuxProvider extends Provider {
|
private static class UnixProvider extends Provider {
|
||||||
|
|
||||||
private LinuxProvider() {
|
private UnixProvider() {
|
||||||
super("LinuxPRNG", 1.1, "A Linux-specific PRNG using /dev/urandom");
|
super("UnixPRNG", 1.0, "A Unix-specific PRNG using /dev/urandom");
|
||||||
// Although /dev/urandom is not a SHA-1 PRNG, some callers
|
// Although /dev/urandom is not a SHA-1 PRNG, some callers
|
||||||
// explicitly request a SHA1PRNG SecureRandom and we need to
|
// explicitly request a SHA1PRNG SecureRandom and we need to
|
||||||
// prevent them from getting the default implementation whose
|
// prevent them from getting the default implementation whose
|
||||||
// output may have low entropy.
|
// output may have low entropy.
|
||||||
put("SecureRandom.SHA1PRNG", LinuxSecureRandomSpi.class.getName());
|
put("SecureRandom.SHA1PRNG", UnixSecureRandomSpi.class.getName());
|
||||||
put("SecureRandom.SHA1PRNG ImplementedIn", "Software");
|
put("SecureRandom.SHA1PRNG ImplementedIn", "Software");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,22 +10,24 @@ import java.security.SecureRandomSpi;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import static java.util.logging.Level.WARNING;
|
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.LogUtils.logException;
|
||||||
|
|
||||||
public class LinuxSecureRandomSpi extends SecureRandomSpi {
|
public class UnixSecureRandomSpi extends SecureRandomSpi {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(LinuxSecureRandomSpi.class.getName());
|
getLogger(UnixSecureRandomSpi.class.getName());
|
||||||
|
|
||||||
private static final File RANDOM_DEVICE = new File("/dev/urandom");
|
private static final File RANDOM_DEVICE = new File("/dev/urandom");
|
||||||
|
|
||||||
private final File inputDevice, outputDevice;
|
private final File inputDevice, outputDevice;
|
||||||
|
|
||||||
public LinuxSecureRandomSpi() {
|
@SuppressWarnings("WeakerAccess")
|
||||||
|
public UnixSecureRandomSpi() {
|
||||||
this(RANDOM_DEVICE, RANDOM_DEVICE);
|
this(RANDOM_DEVICE, RANDOM_DEVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
LinuxSecureRandomSpi(File inputDevice, File outputDevice) {
|
UnixSecureRandomSpi(File inputDevice, File outputDevice) {
|
||||||
this.inputDevice = inputDevice;
|
this.inputDevice = inputDevice;
|
||||||
this.outputDevice = outputDevice;
|
this.outputDevice = outputDevice;
|
||||||
}
|
}
|
||||||
@@ -72,8 +72,7 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
|
|||||||
for (DuplexPluginFactory f : pluginConfig.getDuplexFactories())
|
for (DuplexPluginFactory f : pluginConfig.getDuplexFactories())
|
||||||
transports.put(f.getId(), f.getMaxLatency());
|
transports.put(f.getId(), f.getMaxLatency());
|
||||||
try {
|
try {
|
||||||
Transaction txn = db.startTransaction(false);
|
db.transaction(false, txn -> {
|
||||||
try {
|
|
||||||
for (Contact c : db.getContacts(txn))
|
for (Contact c : db.getContacts(txn))
|
||||||
if (c.isActive()) activeContacts.put(c.getId(), true);
|
if (c.isActive()) activeContacts.put(c.getId(), true);
|
||||||
for (Entry<TransportId, Integer> e : transports.entrySet())
|
for (Entry<TransportId, Integer> e : transports.entrySet())
|
||||||
@@ -85,10 +84,7 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
|
|||||||
managers.put(e.getKey(), m);
|
managers.put(e.getKey(), m);
|
||||||
m.start(txn);
|
m.start(txn);
|
||||||
}
|
}
|
||||||
db.commitTransaction(txn);
|
});
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
throw new ServiceException(e);
|
throw new ServiceException(e);
|
||||||
}
|
}
|
||||||
@@ -141,15 +137,8 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
|
|||||||
if (LOG.isLoggable(INFO)) LOG.info("No key manager for " + t);
|
if (LOG.isLoggable(INFO)) LOG.info("No key manager for " + t);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
StreamContext ctx;
|
return db.transactionWithNullableResult(false, txn ->
|
||||||
Transaction txn = db.startTransaction(false);
|
m.getStreamContext(txn, c));
|
||||||
try {
|
|
||||||
ctx = m.getStreamContext(txn, c);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
return ctx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -160,15 +149,8 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
|
|||||||
if (LOG.isLoggable(INFO)) LOG.info("No key manager for " + t);
|
if (LOG.isLoggable(INFO)) LOG.info("No key manager for " + t);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
StreamContext ctx;
|
return db.transactionWithNullableResult(false, txn ->
|
||||||
Transaction txn = db.startTransaction(false);
|
m.getStreamContext(txn, tag));
|
||||||
try {
|
|
||||||
ctx = m.getStreamContext(txn, tag);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
return ctx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -162,13 +162,7 @@ class TransportKeyManagerImpl implements TransportKeyManager {
|
|||||||
private void rotateKeys() {
|
private void rotateKeys() {
|
||||||
dbExecutor.execute(() -> {
|
dbExecutor.execute(() -> {
|
||||||
try {
|
try {
|
||||||
Transaction txn = db.startTransaction(false);
|
db.transaction(false, this::rotateKeys);
|
||||||
try {
|
|
||||||
rotateKeys(txn);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
logException(LOG, WARNING, e);
|
logException(LOG, WARNING, e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import org.briarproject.bramble.api.sync.GroupId;
|
|||||||
import org.briarproject.bramble.api.sync.InvalidMessageException;
|
import org.briarproject.bramble.api.sync.InvalidMessageException;
|
||||||
import org.briarproject.bramble.api.sync.Message;
|
import org.briarproject.bramble.api.sync.Message;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
import org.briarproject.bramble.api.sync.ValidationManager.IncomingMessageHook;
|
import org.briarproject.bramble.api.sync.validation.IncomingMessageHook;
|
||||||
import org.briarproject.bramble.api.system.Clock;
|
import org.briarproject.bramble.api.system.Clock;
|
||||||
import org.briarproject.bramble.api.versioning.ClientMajorVersion;
|
import org.briarproject.bramble.api.versioning.ClientMajorVersion;
|
||||||
import org.briarproject.bramble.api.versioning.ClientVersioningManager;
|
import org.briarproject.bramble.api.versioning.ClientVersioningManager;
|
||||||
@@ -89,14 +89,9 @@ class ClientVersioningManagerImpl implements ClientVersioningManager, Client,
|
|||||||
public Visibility getClientVisibility(Transaction txn, ContactId contactId,
|
public Visibility getClientVisibility(Transaction txn, ContactId contactId,
|
||||||
ClientId clientId, int majorVersion) throws DbException {
|
ClientId clientId, int majorVersion) throws DbException {
|
||||||
try {
|
try {
|
||||||
Contact contact = db.getContact(txn, contactId);
|
LatestUpdates latest = findLatestUpdates(txn, contactId);
|
||||||
Group g = getContactGroup(contact);
|
if (latest == null || latest.remote == null) return INVISIBLE;
|
||||||
// Contact may be in the process of being added or removed, so
|
|
||||||
// contact group may not exist
|
|
||||||
if (!db.containsGroup(txn, g.getId())) return INVISIBLE;
|
|
||||||
LatestUpdates latest = findLatestUpdates(txn, g.getId());
|
|
||||||
if (latest.local == null) throw new DbException();
|
if (latest.local == null) throw new DbException();
|
||||||
if (latest.remote == null) return INVISIBLE;
|
|
||||||
Update localUpdate = loadUpdate(txn, latest.local.messageId);
|
Update localUpdate = loadUpdate(txn, latest.local.messageId);
|
||||||
Update remoteUpdate = loadUpdate(txn, latest.remote.messageId);
|
Update remoteUpdate = loadUpdate(txn, latest.remote.messageId);
|
||||||
Map<ClientMajorVersion, Visibility> visibilities =
|
Map<ClientMajorVersion, Visibility> visibilities =
|
||||||
@@ -110,6 +105,24 @@ class ClientVersioningManagerImpl implements ClientVersioningManager, Client,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getClientMinorVersion(Transaction txn, ContactId contactId,
|
||||||
|
ClientId clientId, int majorVersion) throws DbException {
|
||||||
|
try {
|
||||||
|
LatestUpdates latest = findLatestUpdates(txn, contactId);
|
||||||
|
if (latest == null || latest.remote == null) return -1;
|
||||||
|
Update remoteUpdate = loadUpdate(txn, latest.remote.messageId);
|
||||||
|
ClientMajorVersion cv =
|
||||||
|
new ClientMajorVersion(clientId, majorVersion);
|
||||||
|
for (ClientState remote : remoteUpdate.states) {
|
||||||
|
if (remote.majorVersion.equals(cv)) return remote.minorVersion;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
} catch (FormatException e) {
|
||||||
|
throw new DbException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createLocalState(Transaction txn) throws DbException {
|
public void createLocalState(Transaction txn) throws DbException {
|
||||||
if (db.containsGroup(txn, localGroup.getId())) return;
|
if (db.containsGroup(txn, localGroup.getId())) return;
|
||||||
@@ -123,16 +136,12 @@ class ClientVersioningManagerImpl implements ClientVersioningManager, Client,
|
|||||||
List<ClientVersion> versions = new ArrayList<>(clients);
|
List<ClientVersion> versions = new ArrayList<>(clients);
|
||||||
Collections.sort(versions);
|
Collections.sort(versions);
|
||||||
try {
|
try {
|
||||||
Transaction txn = db.startTransaction(false);
|
db.transaction(false, txn -> {
|
||||||
try {
|
|
||||||
if (updateClientVersions(txn, versions)) {
|
if (updateClientVersions(txn, versions)) {
|
||||||
for (Contact c : db.getContacts(txn))
|
for (Contact c : db.getContacts(txn))
|
||||||
clientVersionsUpdated(txn, c, versions);
|
clientVersionsUpdated(txn, c, versions);
|
||||||
}
|
}
|
||||||
db.commitTransaction(txn);
|
});
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
throw new ServiceException(e);
|
throw new ServiceException(e);
|
||||||
}
|
}
|
||||||
@@ -340,6 +349,17 @@ class ClientVersioningManagerImpl implements ClientVersioningManager, Client,
|
|||||||
MAJOR_VERSION, c);
|
MAJOR_VERSION, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private LatestUpdates findLatestUpdates(Transaction txn, ContactId c)
|
||||||
|
throws DbException, FormatException {
|
||||||
|
Contact contact = db.getContact(txn, c);
|
||||||
|
Group g = getContactGroup(contact);
|
||||||
|
// Contact may be in the process of being added or removed, so
|
||||||
|
// contact group may not exist
|
||||||
|
if (!db.containsGroup(txn, g.getId())) return null;
|
||||||
|
return findLatestUpdates(txn, g.getId());
|
||||||
|
}
|
||||||
|
|
||||||
private LatestUpdates findLatestUpdates(Transaction txn, GroupId g)
|
private LatestUpdates findLatestUpdates(Transaction txn, GroupId g)
|
||||||
throws DbException, FormatException {
|
throws DbException, FormatException {
|
||||||
Map<MessageId, BdfDictionary> metadata =
|
Map<MessageId, BdfDictionary> metadata =
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import org.briarproject.bramble.api.client.ClientHelper;
|
|||||||
import org.briarproject.bramble.api.contact.ContactManager;
|
import org.briarproject.bramble.api.contact.ContactManager;
|
||||||
import org.briarproject.bramble.api.data.MetadataEncoder;
|
import org.briarproject.bramble.api.data.MetadataEncoder;
|
||||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||||
import org.briarproject.bramble.api.sync.ValidationManager;
|
import org.briarproject.bramble.api.sync.validation.ValidationManager;
|
||||||
import org.briarproject.bramble.api.system.Clock;
|
import org.briarproject.bramble.api.system.Clock;
|
||||||
import org.briarproject.bramble.api.versioning.ClientVersioningManager;
|
import org.briarproject.bramble.api.versioning.ClientVersioningManager;
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
Bridge 131.252.210.150:8081 0E858AC201BF0F3FA3C462F64844CBFFC7297A42
|
Bridge obfs4 78.46.188.239:37356 5A2D2F4158D0453E00C7C176978D3F41D69C45DB cert=3c0SwxpOisbohNxEc4tb875RVW8eOu1opRTVXJhafaKA/PNNtI7ElQIVOVZg1AdL5bxGCw iat-mode=0
|
||||||
Bridge 67.205.189.122:8443 12D64D5D44E20169585E7378580C0D33A872AD98
|
Bridge obfs4 52.15.78.72:9443 02069A3C5362476936B62BA6F5ACC41ABD573A9B cert=ijYG/OKc7kqu2YzKNFfeXN7/BG2BOgfEP2KyYEiGDQthnHbsOiTWHeIG0WJVW+BckzDgKw iat-mode=0
|
||||||
Bridge 45.32.148.146:8443 0CE016FB2462D8BF179AE71F7D702D09DEAC3F1D
|
Bridge obfs4 13.58.29.242:9443 0C58939A77DA6B6B29D4B5236A75865659607AE0 cert=OylWIEHb/ezpq1zWxW0sgKRn+9ARH2eOcQOZ8/Gew+4l+oKOhQ2jUX/Y+FSl61JorXZUWA iat-mode=0
|
||||||
Bridge 148.251.90.59:7510 019F727CA6DCA6CA5C90B55E477B7D87981E75BC
|
Bridge obfs4 45.33.37.112:9443 60A609BB4ABE8D46E634AE81ED29ADAB7776B399 cert=t5v19WmNv5Sc2YPNr8RQids365W7MY8zJwQVkOxBjUMFomMWARDzsbYpcWLLcw0J9Gm+BQ iat-mode=0
|
||||||
Bridge 45.55.1.74:8443 6F18FEFBB0CAECD5ABA755312FCCB34FC11A7AB8
|
|
||||||
Bridge 85.229.131.78:444 50E433CCC5FEC11CC34CB4D92033561E065EA106
|
|
||||||
Bridge 178.62.62.193:8443 391B1F9B6A28A1C5FAE1872283985F975E5DB029
|
|
||||||
Bridge 45.76.29.92:8443 ECF1DD51A46FDEF2C50CED992EEEAE8DED18DA0C
|
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
package org.briarproject.bramble;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.test.BrambleTestCase;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Vector;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
import static java.util.Arrays.asList;
|
||||||
|
import static java.util.concurrent.Executors.newSingleThreadExecutor;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
public class PriorityExecutorTest extends BrambleTestCase {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHighPriorityTasksAreDelegatedInOrderOfSubmission()
|
||||||
|
throws Exception {
|
||||||
|
Executor delegate = newSingleThreadExecutor();
|
||||||
|
PriorityExecutor priority = new PriorityExecutor(delegate);
|
||||||
|
Executor high = priority.getHighPriorityExecutor();
|
||||||
|
testTasksAreDelegatedInOrderOfSubmission(high);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLowPriorityTasksAreDelegatedInOrderOfSubmission()
|
||||||
|
throws Exception {
|
||||||
|
Executor delegate = newSingleThreadExecutor();
|
||||||
|
PriorityExecutor priority = new PriorityExecutor(delegate);
|
||||||
|
Executor low = priority.getLowPriorityExecutor();
|
||||||
|
testTasksAreDelegatedInOrderOfSubmission(low);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHighPriorityTasksAreRunFirst() throws Exception {
|
||||||
|
Executor delegate = newSingleThreadExecutor();
|
||||||
|
PriorityExecutor priority = new PriorityExecutor(delegate);
|
||||||
|
Executor high = priority.getHighPriorityExecutor();
|
||||||
|
Executor low = priority.getLowPriorityExecutor();
|
||||||
|
// Submit a task that will block, causing other tasks to be queued
|
||||||
|
CountDownLatch cork = new CountDownLatch(1);
|
||||||
|
low.execute(() -> {
|
||||||
|
try {
|
||||||
|
cork.await();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Submit alternating tasks to the high and low priority executors
|
||||||
|
List<Integer> results = new Vector<>();
|
||||||
|
CountDownLatch tasksFinished = new CountDownLatch(10);
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
int result = i;
|
||||||
|
Runnable task = () -> {
|
||||||
|
results.add(result);
|
||||||
|
tasksFinished.countDown();
|
||||||
|
};
|
||||||
|
if (i % 2 == 0) high.execute(task);
|
||||||
|
else low.execute(task);
|
||||||
|
}
|
||||||
|
// Release the cork and wait for all tasks to finish
|
||||||
|
cork.countDown();
|
||||||
|
tasksFinished.await();
|
||||||
|
// The high-priority tasks should have run before the low-priority tasks
|
||||||
|
assertEquals(asList(0, 2, 4, 6, 8, 1, 3, 5, 7, 9), results);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testTasksAreDelegatedInOrderOfSubmission(Executor e)
|
||||||
|
throws Exception {
|
||||||
|
List<Integer> results = new Vector<>();
|
||||||
|
CountDownLatch tasksFinished = new CountDownLatch(10);
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
int result = i;
|
||||||
|
e.execute(() -> {
|
||||||
|
results.add(result);
|
||||||
|
tasksFinished.countDown();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Wait for all the tasks to finish
|
||||||
|
tasksFinished.await();
|
||||||
|
// The tasks should have run in the order they were submitted
|
||||||
|
assertEquals(asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), results);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,6 +22,7 @@ import org.briarproject.bramble.api.sync.Message;
|
|||||||
import org.briarproject.bramble.api.sync.MessageFactory;
|
import org.briarproject.bramble.api.sync.MessageFactory;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
import org.briarproject.bramble.test.BrambleTestCase;
|
import org.briarproject.bramble.test.BrambleTestCase;
|
||||||
|
import org.briarproject.bramble.test.DbExpectations;
|
||||||
import org.briarproject.bramble.util.StringUtils;
|
import org.briarproject.bramble.util.StringUtils;
|
||||||
import org.jmock.Expectations;
|
import org.jmock.Expectations;
|
||||||
import org.jmock.Mockery;
|
import org.jmock.Mockery;
|
||||||
@@ -85,14 +86,11 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
|||||||
boolean shared = new Random().nextBoolean();
|
boolean shared = new Random().nextBoolean();
|
||||||
Transaction txn = new Transaction(null, false);
|
Transaction txn = new Transaction(null, false);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(metadataEncoder).encode(dictionary);
|
oneOf(metadataEncoder).encode(dictionary);
|
||||||
will(returnValue(metadata));
|
will(returnValue(metadata));
|
||||||
oneOf(db).addLocalMessage(txn, message, metadata, shared);
|
oneOf(db).addLocalMessage(txn, message, metadata, shared);
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
clientHelper.addLocalMessage(message, dictionary, shared);
|
clientHelper.addLocalMessage(message, dictionary, shared);
|
||||||
@@ -116,13 +114,10 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
|||||||
Transaction txn = new Transaction(null, true);
|
Transaction txn = new Transaction(null, true);
|
||||||
|
|
||||||
expectToList(true);
|
expectToList(true);
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).getMessage(txn, messageId);
|
oneOf(db).getMessage(txn, messageId);
|
||||||
will(returnValue(message));
|
will(returnValue(message));
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
clientHelper.getMessageAsList(messageId);
|
clientHelper.getMessageAsList(messageId);
|
||||||
@@ -133,15 +128,12 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
|||||||
public void testGetGroupMetadataAsDictionary() throws Exception {
|
public void testGetGroupMetadataAsDictionary() throws Exception {
|
||||||
Transaction txn = new Transaction(null, true);
|
Transaction txn = new Transaction(null, true);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).getGroupMetadata(txn, groupId);
|
oneOf(db).getGroupMetadata(txn, groupId);
|
||||||
will(returnValue(metadata));
|
will(returnValue(metadata));
|
||||||
oneOf(metadataParser).parse(metadata);
|
oneOf(metadataParser).parse(metadata);
|
||||||
will(returnValue(dictionary));
|
will(returnValue(dictionary));
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
assertEquals(dictionary,
|
assertEquals(dictionary,
|
||||||
@@ -153,15 +145,12 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
|||||||
public void testGetMessageMetadataAsDictionary() throws Exception {
|
public void testGetMessageMetadataAsDictionary() throws Exception {
|
||||||
Transaction txn = new Transaction(null, true);
|
Transaction txn = new Transaction(null, true);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).getMessageMetadata(txn, messageId);
|
oneOf(db).getMessageMetadata(txn, messageId);
|
||||||
will(returnValue(metadata));
|
will(returnValue(metadata));
|
||||||
oneOf(metadataParser).parse(metadata);
|
oneOf(metadataParser).parse(metadata);
|
||||||
will(returnValue(dictionary));
|
will(returnValue(dictionary));
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
assertEquals(dictionary,
|
assertEquals(dictionary,
|
||||||
@@ -175,15 +164,12 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
|||||||
map.put(messageId, dictionary);
|
map.put(messageId, dictionary);
|
||||||
Transaction txn = new Transaction(null, true);
|
Transaction txn = new Transaction(null, true);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).getMessageMetadata(txn, groupId);
|
oneOf(db).getMessageMetadata(txn, groupId);
|
||||||
will(returnValue(Collections.singletonMap(messageId, metadata)));
|
will(returnValue(Collections.singletonMap(messageId, metadata)));
|
||||||
oneOf(metadataParser).parse(metadata);
|
oneOf(metadataParser).parse(metadata);
|
||||||
will(returnValue(dictionary));
|
will(returnValue(dictionary));
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
assertEquals(map, clientHelper.getMessageMetadataAsDictionary(groupId));
|
assertEquals(map, clientHelper.getMessageMetadataAsDictionary(groupId));
|
||||||
@@ -200,17 +186,14 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
|||||||
queryMetadata.put("query", getRandomBytes(42));
|
queryMetadata.put("query", getRandomBytes(42));
|
||||||
Transaction txn = new Transaction(null, true);
|
Transaction txn = new Transaction(null, true);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(metadataEncoder).encode(query);
|
oneOf(metadataEncoder).encode(query);
|
||||||
will(returnValue(queryMetadata));
|
will(returnValue(queryMetadata));
|
||||||
oneOf(db).getMessageMetadata(txn, groupId, queryMetadata);
|
oneOf(db).getMessageMetadata(txn, groupId, queryMetadata);
|
||||||
will(returnValue(Collections.singletonMap(messageId, metadata)));
|
will(returnValue(Collections.singletonMap(messageId, metadata)));
|
||||||
oneOf(metadataParser).parse(metadata);
|
oneOf(metadataParser).parse(metadata);
|
||||||
will(returnValue(dictionary));
|
will(returnValue(dictionary));
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
assertEquals(map,
|
assertEquals(map,
|
||||||
@@ -222,14 +205,11 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
|||||||
public void testMergeGroupMetadata() throws Exception {
|
public void testMergeGroupMetadata() throws Exception {
|
||||||
Transaction txn = new Transaction(null, false);
|
Transaction txn = new Transaction(null, false);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(metadataEncoder).encode(dictionary);
|
oneOf(metadataEncoder).encode(dictionary);
|
||||||
will(returnValue(metadata));
|
will(returnValue(metadata));
|
||||||
oneOf(db).mergeGroupMetadata(txn, groupId, metadata);
|
oneOf(db).mergeGroupMetadata(txn, groupId, metadata);
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
clientHelper.mergeGroupMetadata(groupId, dictionary);
|
clientHelper.mergeGroupMetadata(groupId, dictionary);
|
||||||
@@ -240,14 +220,11 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
|||||||
public void testMergeMessageMetadata() throws Exception {
|
public void testMergeMessageMetadata() throws Exception {
|
||||||
Transaction txn = new Transaction(null, false);
|
Transaction txn = new Transaction(null, false);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(metadataEncoder).encode(dictionary);
|
oneOf(metadataEncoder).encode(dictionary);
|
||||||
will(returnValue(metadata));
|
will(returnValue(metadata));
|
||||||
oneOf(db).mergeMessageMetadata(txn, messageId, metadata);
|
oneOf(db).mergeMessageMetadata(txn, messageId, metadata);
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
clientHelper.mergeMessageMetadata(messageId, dictionary);
|
clientHelper.mergeMessageMetadata(messageId, dictionary);
|
||||||
|
|||||||
@@ -69,17 +69,14 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
|||||||
boolean alice = new Random().nextBoolean();
|
boolean alice = new Random().nextBoolean();
|
||||||
Transaction txn = new Transaction(null, false);
|
Transaction txn = new Transaction(null, false);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transactionWithResult(with(false), withDbCallable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).addContact(txn, remote, local, verified, active);
|
oneOf(db).addContact(txn, remote, local, verified, active);
|
||||||
will(returnValue(contactId));
|
will(returnValue(contactId));
|
||||||
oneOf(keyManager).addContact(txn, contactId, master, timestamp,
|
oneOf(keyManager).addContact(txn, contactId, master, timestamp,
|
||||||
alice, active);
|
alice, active);
|
||||||
oneOf(db).getContact(txn, contactId);
|
oneOf(db).getContact(txn, contactId);
|
||||||
will(returnValue(contact));
|
will(returnValue(contact));
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
assertEquals(contactId, contactManager.addContact(remote, local,
|
assertEquals(contactId, contactManager.addContact(remote, local,
|
||||||
@@ -89,13 +86,10 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testGetContact() throws Exception {
|
public void testGetContact() throws Exception {
|
||||||
Transaction txn = new Transaction(null, true);
|
Transaction txn = new Transaction(null, true);
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).getContact(txn, contactId);
|
oneOf(db).getContact(txn, contactId);
|
||||||
will(returnValue(contact));
|
will(returnValue(contact));
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
assertEquals(contact, contactManager.getContact(contactId));
|
assertEquals(contact, contactManager.getContact(contactId));
|
||||||
@@ -105,13 +99,10 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
|||||||
public void testGetContactByAuthor() throws Exception {
|
public void testGetContactByAuthor() throws Exception {
|
||||||
Transaction txn = new Transaction(null, true);
|
Transaction txn = new Transaction(null, true);
|
||||||
Collection<Contact> contacts = Collections.singleton(contact);
|
Collection<Contact> contacts = Collections.singleton(contact);
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).getContactsByAuthorId(txn, remote.getId());
|
oneOf(db).getContactsByAuthorId(txn, remote.getId());
|
||||||
will(returnValue(contacts));
|
will(returnValue(contacts));
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
assertEquals(contact, contactManager.getContact(remote.getId(), local));
|
assertEquals(contact, contactManager.getContact(remote.getId(), local));
|
||||||
@@ -120,12 +111,10 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
|||||||
@Test(expected = NoSuchContactException.class)
|
@Test(expected = NoSuchContactException.class)
|
||||||
public void testGetContactByUnknownAuthor() throws Exception {
|
public void testGetContactByUnknownAuthor() throws Exception {
|
||||||
Transaction txn = new Transaction(null, true);
|
Transaction txn = new Transaction(null, true);
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).getContactsByAuthorId(txn, remote.getId());
|
oneOf(db).getContactsByAuthorId(txn, remote.getId());
|
||||||
will(returnValue(emptyList()));
|
will(returnValue(emptyList()));
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
contactManager.getContact(remote.getId(), local);
|
contactManager.getContact(remote.getId(), local);
|
||||||
@@ -135,31 +124,26 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
|||||||
public void testGetContactByUnknownLocalAuthor() throws Exception {
|
public void testGetContactByUnknownLocalAuthor() throws Exception {
|
||||||
Transaction txn = new Transaction(null, true);
|
Transaction txn = new Transaction(null, true);
|
||||||
Collection<Contact> contacts = Collections.singleton(contact);
|
Collection<Contact> contacts = Collections.singleton(contact);
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).getContactsByAuthorId(txn, remote.getId());
|
oneOf(db).getContactsByAuthorId(txn, remote.getId());
|
||||||
will(returnValue(contacts));
|
will(returnValue(contacts));
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
contactManager.getContact(remote.getId(), new AuthorId(getRandomId()));
|
contactManager.getContact(remote.getId(), new AuthorId(getRandomId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testActiveContacts() throws Exception {
|
public void testGetActiveContacts() throws Exception {
|
||||||
Collection<Contact> activeContacts = Collections.singletonList(contact);
|
Collection<Contact> activeContacts = Collections.singletonList(contact);
|
||||||
Collection<Contact> contacts = new ArrayList<>(activeContacts);
|
Collection<Contact> contacts = new ArrayList<>(activeContacts);
|
||||||
contacts.add(new Contact(new ContactId(3), remote, local, alias, true,
|
contacts.add(new Contact(new ContactId(3), remote, local, alias, true,
|
||||||
false));
|
false));
|
||||||
Transaction txn = new Transaction(null, true);
|
Transaction txn = new Transaction(null, true);
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).getContacts(txn);
|
oneOf(db).getContacts(txn);
|
||||||
will(returnValue(contacts));
|
will(returnValue(contacts));
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
assertEquals(activeContacts, contactManager.getActiveContacts());
|
assertEquals(activeContacts, contactManager.getActiveContacts());
|
||||||
@@ -168,14 +152,11 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testRemoveContact() throws Exception {
|
public void testRemoveContact() throws Exception {
|
||||||
Transaction txn = new Transaction(null, false);
|
Transaction txn = new Transaction(null, false);
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).getContact(txn, contactId);
|
oneOf(db).getContact(txn, contactId);
|
||||||
will(returnValue(contact));
|
will(returnValue(contact));
|
||||||
oneOf(db).removeContact(txn, contactId);
|
oneOf(db).removeContact(txn, contactId);
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
contactManager.removeContact(contactId);
|
contactManager.removeContact(contactId);
|
||||||
@@ -195,7 +176,7 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
|||||||
public void testSetContactAlias() throws Exception {
|
public void testSetContactAlias() throws Exception {
|
||||||
Transaction txn = new Transaction(null, false);
|
Transaction txn = new Transaction(null, false);
|
||||||
context.checking(new DbExpectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
oneOf(db).transaction(with(equal(false)), withDbRunnable(txn));
|
oneOf(db).transaction(with(false), withDbRunnable(txn));
|
||||||
oneOf(db).setContactAlias(txn, contactId, alias);
|
oneOf(db).setContactAlias(txn, contactId, alias);
|
||||||
}});
|
}});
|
||||||
|
|
||||||
@@ -204,35 +185,32 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
|||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test(expected = IllegalArgumentException.class)
|
||||||
public void testSetContactAliasTooLong() throws Exception {
|
public void testSetContactAliasTooLong() throws Exception {
|
||||||
contactManager.setContactAlias(contactId,
|
Transaction txn = new Transaction(null, false);
|
||||||
|
contactManager.setContactAlias(txn, contactId,
|
||||||
getRandomString(MAX_AUTHOR_NAME_LENGTH + 1));
|
getRandomString(MAX_AUTHOR_NAME_LENGTH + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testContactExists() throws Exception {
|
public void testContactExists() throws Exception {
|
||||||
Transaction txn = new Transaction(null, true);
|
Transaction txn = new Transaction(null, true);
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).containsContact(txn, remote.getId(), local);
|
oneOf(db).containsContact(txn, remote.getId(), local);
|
||||||
will(returnValue(true));
|
will(returnValue(true));
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
assertTrue(contactManager.contactExists(remote.getId(), local));
|
assertTrue(contactManager.contactExists(remote.getId(), local));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetAuthorStatus() throws Exception {
|
public void testGetAuthorInfo() throws Exception {
|
||||||
Transaction txn = new Transaction(null, true);
|
Transaction txn = new Transaction(null, true);
|
||||||
Collection<Contact> contacts = singletonList(
|
Collection<Contact> contacts = singletonList(
|
||||||
new Contact(new ContactId(1), remote, localAuthor.getId(),
|
new Contact(new ContactId(1), remote, localAuthor.getId(),
|
||||||
alias, false, true));
|
alias, false, true));
|
||||||
|
|
||||||
context.checking(new DbExpectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
oneOf(db).transactionWithResult(with(equal(true)),
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||||
withDbCallable(txn));
|
|
||||||
oneOf(identityManager).getLocalAuthor(txn);
|
oneOf(identityManager).getLocalAuthor(txn);
|
||||||
will(returnValue(localAuthor));
|
will(returnValue(localAuthor));
|
||||||
oneOf(db).getContactsByAuthorId(txn, remote.getId());
|
oneOf(db).getContactsByAuthorId(txn, remote.getId());
|
||||||
@@ -245,7 +223,7 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetAuthorStatusTransaction() throws DbException {
|
public void testGetAuthorInfoTransaction() throws DbException {
|
||||||
Transaction txn = new Transaction(null, true);
|
Transaction txn = new Transaction(null, true);
|
||||||
|
|
||||||
// check unknown author
|
// check unknown author
|
||||||
@@ -264,7 +242,7 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
|||||||
Collection<Contact> contacts = singletonList(
|
Collection<Contact> contacts = singletonList(
|
||||||
new Contact(new ContactId(1), remote, localAuthor.getId(),
|
new Contact(new ContactId(1), remote, localAuthor.getId(),
|
||||||
alias, false, true));
|
alias, false, true));
|
||||||
checkAuthorStatusContext(txn, remote.getId(), contacts);
|
checkAuthorInfoContext(txn, remote.getId(), contacts);
|
||||||
authorInfo = contactManager.getAuthorInfo(txn, remote.getId());
|
authorInfo = contactManager.getAuthorInfo(txn, remote.getId());
|
||||||
assertEquals(UNVERIFIED, authorInfo.getStatus());
|
assertEquals(UNVERIFIED, authorInfo.getStatus());
|
||||||
assertEquals(alias, contact.getAlias());
|
assertEquals(alias, contact.getAlias());
|
||||||
@@ -272,7 +250,7 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
|||||||
// check verified contact
|
// check verified contact
|
||||||
contacts = singletonList(new Contact(new ContactId(1), remote,
|
contacts = singletonList(new Contact(new ContactId(1), remote,
|
||||||
localAuthor.getId(), alias, true, true));
|
localAuthor.getId(), alias, true, true));
|
||||||
checkAuthorStatusContext(txn, remote.getId(), contacts);
|
checkAuthorInfoContext(txn, remote.getId(), contacts);
|
||||||
authorInfo = contactManager.getAuthorInfo(txn, remote.getId());
|
authorInfo = contactManager.getAuthorInfo(txn, remote.getId());
|
||||||
assertEquals(VERIFIED, authorInfo.getStatus());
|
assertEquals(VERIFIED, authorInfo.getStatus());
|
||||||
assertEquals(alias, contact.getAlias());
|
assertEquals(alias, contact.getAlias());
|
||||||
@@ -288,7 +266,7 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
|||||||
assertNull(authorInfo.getAlias());
|
assertNull(authorInfo.getAlias());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkAuthorStatusContext(Transaction txn, AuthorId authorId,
|
private void checkAuthorInfoContext(Transaction txn, AuthorId authorId,
|
||||||
Collection<Contact> contacts) throws DbException {
|
Collection<Contact> contacts) throws DbException {
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(identityManager).getLocalAuthor(txn);
|
oneOf(identityManager).getLocalAuthor(txn);
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package org.briarproject.bramble.data;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.test.BrambleTestCase;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import static org.briarproject.bramble.api.data.BdfReader.DEFAULT_MAX_BUFFER_SIZE;
|
||||||
|
import static org.briarproject.bramble.api.data.BdfReader.DEFAULT_NESTED_LIMIT;
|
||||||
|
import static org.briarproject.bramble.test.TestUtils.isOptionalTestEnabled;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assume.assumeTrue;
|
||||||
|
|
||||||
|
public class BdfReaderImplFuzzingTest extends BrambleTestCase {
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
assumeTrue(isOptionalTestEnabled(BdfReaderImplFuzzingTest.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStringFuzzing() throws Exception {
|
||||||
|
Random random = new Random();
|
||||||
|
byte[] buf = new byte[22];
|
||||||
|
ByteArrayInputStream in = new ByteArrayInputStream(buf);
|
||||||
|
for (int i = 0; i < 100_000_000; i++) {
|
||||||
|
random.nextBytes(buf);
|
||||||
|
buf[0] = 0x41; // String with 1-byte length
|
||||||
|
buf[1] = 0x14; // Length 20 bytes
|
||||||
|
in.reset();
|
||||||
|
BdfReaderImpl r = new BdfReaderImpl(in, DEFAULT_NESTED_LIMIT,
|
||||||
|
DEFAULT_MAX_BUFFER_SIZE);
|
||||||
|
int length = r.readString().length();
|
||||||
|
assertTrue(length >= 0);
|
||||||
|
assertTrue(length <= 20);
|
||||||
|
assertTrue(r.eof());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -11,7 +11,7 @@ import org.briarproject.bramble.api.sync.Group;
|
|||||||
import org.briarproject.bramble.api.sync.GroupId;
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
import org.briarproject.bramble.api.sync.Message;
|
import org.briarproject.bramble.api.sync.Message;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
import org.briarproject.bramble.api.sync.ValidationManager.State;
|
import org.briarproject.bramble.api.sync.validation.MessageState;
|
||||||
import org.briarproject.bramble.test.BrambleTestCase;
|
import org.briarproject.bramble.test.BrambleTestCase;
|
||||||
import org.briarproject.bramble.test.UTest;
|
import org.briarproject.bramble.test.UTest;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
@@ -33,7 +33,7 @@ import java.util.logging.Logger;
|
|||||||
|
|
||||||
import static java.util.logging.Level.OFF;
|
import static java.util.logging.Level.OFF;
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_IDS;
|
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_IDS;
|
||||||
import static org.briarproject.bramble.api.sync.ValidationManager.State.DELIVERED;
|
import static org.briarproject.bramble.api.sync.validation.MessageState.DELIVERED;
|
||||||
import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory;
|
import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getAuthor;
|
import static org.briarproject.bramble.test.TestUtils.getAuthor;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getGroup;
|
import static org.briarproject.bramble.test.TestUtils.getGroup;
|
||||||
@@ -565,7 +565,8 @@ public abstract class DatabasePerformanceTest extends BrambleTestCase {
|
|||||||
for (int k = 0; k < MESSAGES_PER_GROUP; k++) {
|
for (int k = 0; k < MESSAGES_PER_GROUP; k++) {
|
||||||
Message m = getMessage(g.getId());
|
Message m = getMessage(g.getId());
|
||||||
messages.add(m);
|
messages.add(m);
|
||||||
State state = State.fromValue(random.nextInt(4));
|
MessageState state =
|
||||||
|
MessageState.fromValue(random.nextInt(4));
|
||||||
boolean shared = random.nextBoolean();
|
boolean shared = random.nextBoolean();
|
||||||
ContactId sender = random.nextBoolean() ? c : null;
|
ContactId sender = random.nextBoolean() ? c : null;
|
||||||
db.addMessage(txn, m, state, shared, sender);
|
db.addMessage(txn, m, state, shared, sender);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import org.briarproject.bramble.api.sync.Message;
|
|||||||
import org.briarproject.bramble.api.sync.MessageFactory;
|
import org.briarproject.bramble.api.sync.MessageFactory;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
import org.briarproject.bramble.api.sync.MessageStatus;
|
import org.briarproject.bramble.api.sync.MessageStatus;
|
||||||
import org.briarproject.bramble.api.sync.ValidationManager.State;
|
import org.briarproject.bramble.api.sync.validation.MessageState;
|
||||||
import org.briarproject.bramble.api.system.Clock;
|
import org.briarproject.bramble.api.system.Clock;
|
||||||
import org.briarproject.bramble.api.transport.IncomingKeys;
|
import org.briarproject.bramble.api.transport.IncomingKeys;
|
||||||
import org.briarproject.bramble.api.transport.KeySet;
|
import org.briarproject.bramble.api.transport.KeySet;
|
||||||
@@ -58,10 +58,10 @@ import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
|
|||||||
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
|
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
|
||||||
import static org.briarproject.bramble.api.sync.Group.Visibility.VISIBLE;
|
import static org.briarproject.bramble.api.sync.Group.Visibility.VISIBLE;
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
|
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
|
||||||
import static org.briarproject.bramble.api.sync.ValidationManager.State.DELIVERED;
|
import static org.briarproject.bramble.api.sync.validation.MessageState.DELIVERED;
|
||||||
import static org.briarproject.bramble.api.sync.ValidationManager.State.INVALID;
|
import static org.briarproject.bramble.api.sync.validation.MessageState.INVALID;
|
||||||
import static org.briarproject.bramble.api.sync.ValidationManager.State.PENDING;
|
import static org.briarproject.bramble.api.sync.validation.MessageState.PENDING;
|
||||||
import static org.briarproject.bramble.api.sync.ValidationManager.State.UNKNOWN;
|
import static org.briarproject.bramble.api.sync.validation.MessageState.UNKNOWN;
|
||||||
import static org.briarproject.bramble.db.DatabaseConstants.DB_SETTINGS_NAMESPACE;
|
import static org.briarproject.bramble.db.DatabaseConstants.DB_SETTINGS_NAMESPACE;
|
||||||
import static org.briarproject.bramble.db.DatabaseConstants.LAST_COMPACTED_KEY;
|
import static org.briarproject.bramble.db.DatabaseConstants.LAST_COMPACTED_KEY;
|
||||||
import static org.briarproject.bramble.db.DatabaseConstants.MAX_COMPACTION_INTERVAL_MS;
|
import static org.briarproject.bramble.db.DatabaseConstants.MAX_COMPACTION_INTERVAL_MS;
|
||||||
@@ -1309,7 +1309,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
db.addMessageDependency(txn, message1, messageId3, PENDING);
|
db.addMessageDependency(txn, message1, messageId3, PENDING);
|
||||||
db.addMessageDependency(txn, message2, messageId4, INVALID);
|
db.addMessageDependency(txn, message2, messageId4, INVALID);
|
||||||
|
|
||||||
Map<MessageId, State> dependencies;
|
Map<MessageId, MessageState> dependencies;
|
||||||
|
|
||||||
// Retrieve dependencies for root
|
// Retrieve dependencies for root
|
||||||
dependencies = db.getMessageDependencies(txn, messageId);
|
dependencies = db.getMessageDependencies(txn, messageId);
|
||||||
@@ -1333,7 +1333,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
dependencies = db.getMessageDependencies(txn, messageId4);
|
dependencies = db.getMessageDependencies(txn, messageId4);
|
||||||
assertEquals(0, dependencies.size());
|
assertEquals(0, dependencies.size());
|
||||||
|
|
||||||
Map<MessageId, State> dependents;
|
Map<MessageId, MessageState> dependents;
|
||||||
|
|
||||||
// Root message does not have dependents
|
// Root message does not have dependents
|
||||||
dependents = db.getMessageDependents(txn, messageId);
|
dependents = db.getMessageDependents(txn, messageId);
|
||||||
@@ -1408,7 +1408,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
db.addMessageDependency(txn, message, messageId3, PENDING);
|
db.addMessageDependency(txn, message, messageId3, PENDING);
|
||||||
|
|
||||||
// Retrieve the dependencies for the root
|
// Retrieve the dependencies for the root
|
||||||
Map<MessageId, State> dependencies;
|
Map<MessageId, MessageState> dependencies;
|
||||||
dependencies = db.getMessageDependencies(txn, messageId);
|
dependencies = db.getMessageDependencies(txn, messageId);
|
||||||
|
|
||||||
// The cross-group dependency should have state UNKNOWN
|
// The cross-group dependency should have state UNKNOWN
|
||||||
@@ -1421,7 +1421,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
assertEquals(DELIVERED, dependencies.get(messageId3));
|
assertEquals(DELIVERED, dependencies.get(messageId3));
|
||||||
|
|
||||||
// Retrieve the dependents for the message in the second group
|
// Retrieve the dependents for the message in the second group
|
||||||
Map<MessageId, State> dependents;
|
Map<MessageId, MessageState> dependents;
|
||||||
dependents = db.getMessageDependents(txn, messageId1);
|
dependents = db.getMessageDependents(txn, messageId1);
|
||||||
|
|
||||||
// The cross-group dependent should be excluded
|
// The cross-group dependent should be excluded
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import org.briarproject.bramble.api.identity.AuthorFactory;
|
|||||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||||
|
import org.briarproject.bramble.test.DbExpectations;
|
||||||
import org.jmock.Expectations;
|
import org.jmock.Expectations;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -64,13 +65,10 @@ public class IdentityManagerImplTest extends BrambleMockTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRegisterAndStoreLocalAuthor() throws DbException {
|
public void testRegisterAndStoreLocalAuthor() throws Exception {
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).addLocalAuthor(txn, localAuthor);
|
oneOf(db).addLocalAuthor(txn, localAuthor);
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
identityManager.registerLocalAuthor(localAuthor);
|
identityManager.registerLocalAuthor(localAuthor);
|
||||||
@@ -79,14 +77,11 @@ public class IdentityManagerImplTest extends BrambleMockTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetLocalAuthor() throws DbException {
|
public void testGetLocalAuthor() throws Exception {
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).getLocalAuthors(txn);
|
oneOf(db).getLocalAuthors(txn);
|
||||||
will(returnValue(localAuthors));
|
will(returnValue(localAuthors));
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
}});
|
}});
|
||||||
assertEquals(localAuthor, identityManager.getLocalAuthor());
|
assertEquals(localAuthor, identityManager.getLocalAuthor());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,16 +21,18 @@ import org.briarproject.bramble.api.sync.MessageId;
|
|||||||
import org.briarproject.bramble.api.system.Clock;
|
import org.briarproject.bramble.api.system.Clock;
|
||||||
import org.briarproject.bramble.api.versioning.ClientVersioningManager;
|
import org.briarproject.bramble.api.versioning.ClientVersioningManager;
|
||||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||||
|
import org.briarproject.bramble.test.DbExpectations;
|
||||||
import org.jmock.Expectations;
|
import org.jmock.Expectations;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static java.util.Arrays.asList;
|
||||||
import static java.util.Collections.singletonList;
|
import static java.util.Collections.singletonList;
|
||||||
|
import static java.util.Collections.singletonMap;
|
||||||
import static org.briarproject.bramble.api.properties.TransportPropertyManager.CLIENT_ID;
|
import static org.briarproject.bramble.api.properties.TransportPropertyManager.CLIENT_ID;
|
||||||
import static org.briarproject.bramble.api.properties.TransportPropertyManager.MAJOR_VERSION;
|
import static org.briarproject.bramble.api.properties.TransportPropertyManager.MAJOR_VERSION;
|
||||||
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
|
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
|
||||||
@@ -351,14 +353,11 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
|||||||
new BdfEntry("local", true)
|
new BdfEntry("local", true)
|
||||||
));
|
));
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||||
localGroup.getId());
|
localGroup.getId());
|
||||||
will(returnValue(messageMetadata));
|
will(returnValue(messageMetadata));
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
TransportPropertyManagerImpl t = createInstance();
|
TransportPropertyManagerImpl t = createInstance();
|
||||||
@@ -386,9 +385,8 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
|||||||
));
|
));
|
||||||
BdfList fooUpdate = BdfList.of("foo", 1, fooPropertiesDict);
|
BdfList fooUpdate = BdfList.of("foo", 1, fooPropertiesDict);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||||
localGroup.getId());
|
localGroup.getId());
|
||||||
will(returnValue(messageMetadata));
|
will(returnValue(messageMetadata));
|
||||||
@@ -397,8 +395,6 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
|||||||
oneOf(clientHelper).parseAndValidateTransportProperties(
|
oneOf(clientHelper).parseAndValidateTransportProperties(
|
||||||
fooPropertiesDict);
|
fooPropertiesDict);
|
||||||
will(returnValue(fooProperties));
|
will(returnValue(fooProperties));
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
TransportPropertyManagerImpl t = createInstance();
|
TransportPropertyManagerImpl t = createInstance();
|
||||||
@@ -413,8 +409,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
|||||||
Contact contact1 = getContact(false);
|
Contact contact1 = getContact(false);
|
||||||
Contact contact2 = getContact(true);
|
Contact contact2 = getContact(true);
|
||||||
Contact contact3 = getContact(true);
|
Contact contact3 = getContact(true);
|
||||||
List<Contact> contacts =
|
List<Contact> contacts = asList(contact1, contact2, contact3);
|
||||||
Arrays.asList(contact1, contact2, contact3);
|
|
||||||
Group contactGroup2 = getGroup(CLIENT_ID, MAJOR_VERSION);
|
Group contactGroup2 = getGroup(CLIENT_ID, MAJOR_VERSION);
|
||||||
Group contactGroup3 = getGroup(CLIENT_ID, MAJOR_VERSION);
|
Group contactGroup3 = getGroup(CLIENT_ID, MAJOR_VERSION);
|
||||||
Map<MessageId, BdfDictionary> messageMetadata3 =
|
Map<MessageId, BdfDictionary> messageMetadata3 =
|
||||||
@@ -442,9 +437,8 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
|||||||
));
|
));
|
||||||
BdfList fooUpdate = BdfList.of("foo", 1, fooPropertiesDict);
|
BdfList fooUpdate = BdfList.of("foo", 1, fooPropertiesDict);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).getContacts(txn);
|
oneOf(db).getContacts(txn);
|
||||||
will(returnValue(contacts));
|
will(returnValue(contacts));
|
||||||
// First contact: skipped because not active
|
// First contact: skipped because not active
|
||||||
@@ -467,8 +461,6 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
|||||||
oneOf(clientHelper).parseAndValidateTransportProperties(
|
oneOf(clientHelper).parseAndValidateTransportProperties(
|
||||||
fooPropertiesDict);
|
fooPropertiesDict);
|
||||||
will(returnValue(fooProperties));
|
will(returnValue(fooProperties));
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
TransportPropertyManagerImpl t = createInstance();
|
TransportPropertyManagerImpl t = createInstance();
|
||||||
@@ -485,17 +477,16 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
|||||||
throws Exception {
|
throws Exception {
|
||||||
Transaction txn = new Transaction(null, false);
|
Transaction txn = new Transaction(null, false);
|
||||||
MessageId updateId = new MessageId(getRandomId());
|
MessageId updateId = new MessageId(getRandomId());
|
||||||
Map<MessageId, BdfDictionary> messageMetadata =
|
Map<MessageId, BdfDictionary> messageMetadata = singletonMap(updateId,
|
||||||
Collections.singletonMap(updateId, BdfDictionary.of(
|
BdfDictionary.of(
|
||||||
new BdfEntry("transportId", "foo"),
|
new BdfEntry("transportId", "foo"),
|
||||||
new BdfEntry("version", 1),
|
new BdfEntry("version", 1),
|
||||||
new BdfEntry("local", true)
|
new BdfEntry("local", true)
|
||||||
));
|
));
|
||||||
BdfList update = BdfList.of("foo", 1, fooPropertiesDict);
|
BdfList update = BdfList.of("foo", 1, fooPropertiesDict);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
// Merge the new properties with the existing properties
|
// Merge the new properties with the existing properties
|
||||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||||
localGroup.getId());
|
localGroup.getId());
|
||||||
@@ -506,8 +497,6 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
|||||||
fooPropertiesDict);
|
fooPropertiesDict);
|
||||||
will(returnValue(fooProperties));
|
will(returnValue(fooProperties));
|
||||||
// Properties are unchanged so we're done
|
// Properties are unchanged so we're done
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
TransportPropertyManagerImpl t = createInstance();
|
TransportPropertyManagerImpl t = createInstance();
|
||||||
@@ -520,9 +509,8 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
|||||||
Contact contact = getContact(true);
|
Contact contact = getContact(true);
|
||||||
Group contactGroup = getGroup(CLIENT_ID, MAJOR_VERSION);
|
Group contactGroup = getGroup(CLIENT_ID, MAJOR_VERSION);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
// There are no existing properties to merge with
|
// There are no existing properties to merge with
|
||||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||||
localGroup.getId());
|
localGroup.getId());
|
||||||
@@ -541,8 +529,6 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
|||||||
will(returnValue(Collections.emptyMap()));
|
will(returnValue(Collections.emptyMap()));
|
||||||
expectStoreMessage(txn, contactGroup.getId(), "foo",
|
expectStoreMessage(txn, contactGroup.getId(), "foo",
|
||||||
fooPropertiesDict, 1, true, true);
|
fooPropertiesDict, 1, true, true);
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
TransportPropertyManagerImpl t = createInstance();
|
TransportPropertyManagerImpl t = createInstance();
|
||||||
@@ -561,10 +547,10 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
|||||||
);
|
);
|
||||||
MessageId localGroupUpdateId = new MessageId(getRandomId());
|
MessageId localGroupUpdateId = new MessageId(getRandomId());
|
||||||
Map<MessageId, BdfDictionary> localGroupMessageMetadata =
|
Map<MessageId, BdfDictionary> localGroupMessageMetadata =
|
||||||
Collections.singletonMap(localGroupUpdateId, oldMetadata);
|
singletonMap(localGroupUpdateId, oldMetadata);
|
||||||
MessageId contactGroupUpdateId = new MessageId(getRandomId());
|
MessageId contactGroupUpdateId = new MessageId(getRandomId());
|
||||||
Map<MessageId, BdfDictionary> contactGroupMessageMetadata =
|
Map<MessageId, BdfDictionary> contactGroupMessageMetadata =
|
||||||
Collections.singletonMap(contactGroupUpdateId, oldMetadata);
|
singletonMap(contactGroupUpdateId, oldMetadata);
|
||||||
TransportProperties oldProperties = new TransportProperties();
|
TransportProperties oldProperties = new TransportProperties();
|
||||||
oldProperties.put("fooKey1", "oldFooValue1");
|
oldProperties.put("fooKey1", "oldFooValue1");
|
||||||
BdfDictionary oldPropertiesDict = BdfDictionary.of(
|
BdfDictionary oldPropertiesDict = BdfDictionary.of(
|
||||||
@@ -572,9 +558,8 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
|||||||
);
|
);
|
||||||
BdfList oldUpdate = BdfList.of("foo", 1, oldPropertiesDict);
|
BdfList oldUpdate = BdfList.of("foo", 1, oldPropertiesDict);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
// Merge the new properties with the existing properties
|
// Merge the new properties with the existing properties
|
||||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||||
localGroup.getId());
|
localGroup.getId());
|
||||||
@@ -602,8 +587,6 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
|||||||
fooPropertiesDict, 2, true, true);
|
fooPropertiesDict, 2, true, true);
|
||||||
// Delete the previous update
|
// Delete the previous update
|
||||||
oneOf(db).removeMessage(txn, contactGroupUpdateId);
|
oneOf(db).removeMessage(txn, contactGroupUpdateId);
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
TransportPropertyManagerImpl t = createInstance();
|
TransportPropertyManagerImpl t = createInstance();
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ import org.briarproject.bramble.api.sync.MessageId;
|
|||||||
import org.briarproject.bramble.api.sync.SyncRecordWriter;
|
import org.briarproject.bramble.api.sync.SyncRecordWriter;
|
||||||
import org.briarproject.bramble.api.transport.StreamWriter;
|
import org.briarproject.bramble.api.transport.StreamWriter;
|
||||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||||
|
import org.briarproject.bramble.test.DbExpectations;
|
||||||
import org.briarproject.bramble.test.ImmediateExecutor;
|
import org.briarproject.bramble.test.ImmediateExecutor;
|
||||||
import org.jmock.Expectations;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
@@ -45,24 +45,20 @@ public class SimplexOutgoingSessionTest extends BrambleMockTestCase {
|
|||||||
Transaction noAckTxn = new Transaction(null, false);
|
Transaction noAckTxn = new Transaction(null, false);
|
||||||
Transaction noMsgTxn = new Transaction(null, false);
|
Transaction noMsgTxn = new Transaction(null, false);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
// Add listener
|
// Add listener
|
||||||
oneOf(eventBus).addListener(session);
|
oneOf(eventBus).addListener(session);
|
||||||
// No acks to send
|
// No acks to send
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transactionWithNullableResult(with(false),
|
||||||
will(returnValue(noAckTxn));
|
withNullableDbCallable(noAckTxn));
|
||||||
oneOf(db).generateAck(noAckTxn, contactId, MAX_MESSAGE_IDS);
|
oneOf(db).generateAck(noAckTxn, contactId, MAX_MESSAGE_IDS);
|
||||||
will(returnValue(null));
|
will(returnValue(null));
|
||||||
oneOf(db).commitTransaction(noAckTxn);
|
|
||||||
oneOf(db).endTransaction(noAckTxn);
|
|
||||||
// No messages to send
|
// No messages to send
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transactionWithNullableResult(with(false),
|
||||||
will(returnValue(noMsgTxn));
|
withNullableDbCallable(noMsgTxn));
|
||||||
oneOf(db).generateBatch(with(noMsgTxn), with(contactId),
|
oneOf(db).generateBatch(with(noMsgTxn), with(contactId),
|
||||||
with(any(int.class)), with(MAX_LATENCY));
|
with(any(int.class)), with(MAX_LATENCY));
|
||||||
will(returnValue(null));
|
will(returnValue(null));
|
||||||
oneOf(db).commitTransaction(noMsgTxn);
|
|
||||||
oneOf(db).endTransaction(noMsgTxn);
|
|
||||||
// Send the end of stream marker
|
// Send the end of stream marker
|
||||||
oneOf(streamWriter).sendEndOfStream();
|
oneOf(streamWriter).sendEndOfStream();
|
||||||
// Remove listener
|
// Remove listener
|
||||||
@@ -83,41 +79,33 @@ public class SimplexOutgoingSessionTest extends BrambleMockTestCase {
|
|||||||
Transaction msgTxn = new Transaction(null, false);
|
Transaction msgTxn = new Transaction(null, false);
|
||||||
Transaction noMsgTxn = new Transaction(null, false);
|
Transaction noMsgTxn = new Transaction(null, false);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
// Add listener
|
// Add listener
|
||||||
oneOf(eventBus).addListener(session);
|
oneOf(eventBus).addListener(session);
|
||||||
// One ack to send
|
// One ack to send
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transactionWithNullableResult(with(false),
|
||||||
will(returnValue(ackTxn));
|
withNullableDbCallable(ackTxn));
|
||||||
oneOf(db).generateAck(ackTxn, contactId, MAX_MESSAGE_IDS);
|
oneOf(db).generateAck(ackTxn, contactId, MAX_MESSAGE_IDS);
|
||||||
will(returnValue(ack));
|
will(returnValue(ack));
|
||||||
oneOf(db).commitTransaction(ackTxn);
|
|
||||||
oneOf(db).endTransaction(ackTxn);
|
|
||||||
oneOf(recordWriter).writeAck(ack);
|
oneOf(recordWriter).writeAck(ack);
|
||||||
// One message to send
|
// One message to send
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transactionWithNullableResult(with(false),
|
||||||
will(returnValue(msgTxn));
|
withNullableDbCallable(msgTxn));
|
||||||
oneOf(db).generateBatch(with(msgTxn), with(contactId),
|
oneOf(db).generateBatch(with(msgTxn), with(contactId),
|
||||||
with(any(int.class)), with(MAX_LATENCY));
|
with(any(int.class)), with(MAX_LATENCY));
|
||||||
will(returnValue(singletonList(message)));
|
will(returnValue(singletonList(message)));
|
||||||
oneOf(db).commitTransaction(msgTxn);
|
|
||||||
oneOf(db).endTransaction(msgTxn);
|
|
||||||
oneOf(recordWriter).writeMessage(message);
|
oneOf(recordWriter).writeMessage(message);
|
||||||
// No more acks
|
// No more acks
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transactionWithNullableResult(with(false),
|
||||||
will(returnValue(noAckTxn));
|
withNullableDbCallable(noAckTxn));
|
||||||
oneOf(db).generateAck(noAckTxn, contactId, MAX_MESSAGE_IDS);
|
oneOf(db).generateAck(noAckTxn, contactId, MAX_MESSAGE_IDS);
|
||||||
will(returnValue(null));
|
will(returnValue(null));
|
||||||
oneOf(db).commitTransaction(noAckTxn);
|
|
||||||
oneOf(db).endTransaction(noAckTxn);
|
|
||||||
// No more messages
|
// No more messages
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transactionWithNullableResult(with(false),
|
||||||
will(returnValue(noMsgTxn));
|
withNullableDbCallable(noMsgTxn));
|
||||||
oneOf(db).generateBatch(with(noMsgTxn), with(contactId),
|
oneOf(db).generateBatch(with(noMsgTxn), with(contactId),
|
||||||
with(any(int.class)), with(MAX_LATENCY));
|
with(any(int.class)), with(MAX_LATENCY));
|
||||||
will(returnValue(null));
|
will(returnValue(null));
|
||||||
oneOf(db).commitTransaction(noMsgTxn);
|
|
||||||
oneOf(db).endTransaction(noMsgTxn);
|
|
||||||
// Send the end of stream marker
|
// Send the end of stream marker
|
||||||
oneOf(streamWriter).sendEndOfStream();
|
oneOf(streamWriter).sendEndOfStream();
|
||||||
// Remove listener
|
// Remove listener
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package org.briarproject.bramble.sync;
|
|||||||
|
|
||||||
import org.briarproject.bramble.crypto.CryptoModule;
|
import org.briarproject.bramble.crypto.CryptoModule;
|
||||||
import org.briarproject.bramble.record.RecordModule;
|
import org.briarproject.bramble.record.RecordModule;
|
||||||
|
import org.briarproject.bramble.sync.validation.ValidationModule;
|
||||||
import org.briarproject.bramble.system.SystemModule;
|
import org.briarproject.bramble.system.SystemModule;
|
||||||
import org.briarproject.bramble.test.TestSecureRandomModule;
|
import org.briarproject.bramble.test.TestSecureRandomModule;
|
||||||
import org.briarproject.bramble.transport.TransportModule;
|
import org.briarproject.bramble.transport.TransportModule;
|
||||||
@@ -17,6 +18,7 @@ import dagger.Component;
|
|||||||
RecordModule.class,
|
RecordModule.class,
|
||||||
SyncModule.class,
|
SyncModule.class,
|
||||||
SystemModule.class,
|
SystemModule.class,
|
||||||
|
ValidationModule.class,
|
||||||
TransportModule.class
|
TransportModule.class
|
||||||
})
|
})
|
||||||
interface SyncIntegrationTestComponent {
|
interface SyncIntegrationTestComponent {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.briarproject.bramble.sync;
|
package org.briarproject.bramble.sync.validation;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.contact.ContactId;
|
import org.briarproject.bramble.api.contact.ContactId;
|
||||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||||
@@ -13,29 +13,29 @@ import org.briarproject.bramble.api.sync.InvalidMessageException;
|
|||||||
import org.briarproject.bramble.api.sync.Message;
|
import org.briarproject.bramble.api.sync.Message;
|
||||||
import org.briarproject.bramble.api.sync.MessageContext;
|
import org.briarproject.bramble.api.sync.MessageContext;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
import org.briarproject.bramble.api.sync.ValidationManager.IncomingMessageHook;
|
|
||||||
import org.briarproject.bramble.api.sync.ValidationManager.MessageValidator;
|
|
||||||
import org.briarproject.bramble.api.sync.ValidationManager.State;
|
|
||||||
import org.briarproject.bramble.api.sync.event.MessageAddedEvent;
|
import org.briarproject.bramble.api.sync.event.MessageAddedEvent;
|
||||||
|
import org.briarproject.bramble.api.sync.validation.IncomingMessageHook;
|
||||||
|
import org.briarproject.bramble.api.sync.validation.MessageState;
|
||||||
|
import org.briarproject.bramble.api.sync.validation.MessageValidator;
|
||||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||||
|
import org.briarproject.bramble.test.DbExpectations;
|
||||||
import org.briarproject.bramble.test.ImmediateExecutor;
|
import org.briarproject.bramble.test.ImmediateExecutor;
|
||||||
import org.jmock.Expectations;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
import static java.util.Arrays.asList;
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
import static java.util.Collections.emptyMap;
|
import static java.util.Collections.emptyMap;
|
||||||
import static java.util.Collections.singletonList;
|
import static java.util.Collections.singletonList;
|
||||||
import static java.util.Collections.singletonMap;
|
import static java.util.Collections.singletonMap;
|
||||||
import static org.briarproject.bramble.api.sync.ValidationManager.State.DELIVERED;
|
import static org.briarproject.bramble.api.sync.validation.MessageState.DELIVERED;
|
||||||
import static org.briarproject.bramble.api.sync.ValidationManager.State.INVALID;
|
import static org.briarproject.bramble.api.sync.validation.MessageState.INVALID;
|
||||||
import static org.briarproject.bramble.api.sync.ValidationManager.State.PENDING;
|
import static org.briarproject.bramble.api.sync.validation.MessageState.PENDING;
|
||||||
import static org.briarproject.bramble.api.sync.ValidationManager.State.UNKNOWN;
|
import static org.briarproject.bramble.api.sync.validation.MessageState.UNKNOWN;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getClientId;
|
import static org.briarproject.bramble.test.TestUtils.getClientId;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getGroup;
|
import static org.briarproject.bramble.test.TestUtils.getGroup;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getMessage;
|
import static org.briarproject.bramble.test.TestUtils.getMessage;
|
||||||
@@ -83,28 +83,19 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
Transaction txn1 = new Transaction(null, true);
|
Transaction txn1 = new Transaction(null, true);
|
||||||
Transaction txn2 = new Transaction(null, true);
|
Transaction txn2 = new Transaction(null, true);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
// validateOutstandingMessages()
|
// validateOutstandingMessages()
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).getMessagesToValidate(txn);
|
oneOf(db).getMessagesToValidate(txn);
|
||||||
will(returnValue(emptyList()));
|
will(returnValue(emptyList()));
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
// deliverOutstandingMessages()
|
// deliverOutstandingMessages()
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn1));
|
||||||
will(returnValue(txn1));
|
|
||||||
oneOf(db).getPendingMessages(txn1);
|
oneOf(db).getPendingMessages(txn1);
|
||||||
will(returnValue(emptyList()));
|
will(returnValue(emptyList()));
|
||||||
oneOf(db).commitTransaction(txn1);
|
|
||||||
oneOf(db).endTransaction(txn1);
|
|
||||||
// shareOutstandingMessages()
|
// shareOutstandingMessages()
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn2));
|
||||||
will(returnValue(txn2));
|
|
||||||
oneOf(db).getMessagesToShare(txn2);
|
oneOf(db).getMessagesToShare(txn2);
|
||||||
will(returnValue(emptyList()));
|
will(returnValue(emptyList()));
|
||||||
oneOf(db).commitTransaction(txn2);
|
|
||||||
oneOf(db).endTransaction(txn2);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
vm.startService();
|
vm.startService();
|
||||||
@@ -121,29 +112,22 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
Transaction txn5 = new Transaction(null, true);
|
Transaction txn5 = new Transaction(null, true);
|
||||||
Transaction txn6 = new Transaction(null, true);
|
Transaction txn6 = new Transaction(null, true);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
// Get messages to validate
|
// Get messages to validate
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).getMessagesToValidate(txn);
|
oneOf(db).getMessagesToValidate(txn);
|
||||||
will(returnValue(Arrays.asList(messageId, messageId1)));
|
will(returnValue(asList(messageId, messageId1)));
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
// Load the first raw message and group
|
// Load the first raw message and group
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn1));
|
||||||
will(returnValue(txn1));
|
|
||||||
oneOf(db).getMessage(txn1, messageId);
|
oneOf(db).getMessage(txn1, messageId);
|
||||||
will(returnValue(message));
|
will(returnValue(message));
|
||||||
oneOf(db).getGroup(txn1, groupId);
|
oneOf(db).getGroup(txn1, groupId);
|
||||||
will(returnValue(group));
|
will(returnValue(group));
|
||||||
oneOf(db).commitTransaction(txn1);
|
|
||||||
oneOf(db).endTransaction(txn1);
|
|
||||||
// Validate the first message: valid
|
// Validate the first message: valid
|
||||||
oneOf(validator).validateMessage(message, group);
|
oneOf(validator).validateMessage(message, group);
|
||||||
will(returnValue(validResult));
|
will(returnValue(validResult));
|
||||||
// Store the validation result for the first message
|
// Store the validation result for the first message
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn2));
|
||||||
will(returnValue(txn2));
|
|
||||||
oneOf(db).mergeMessageMetadata(txn2, messageId, metadata);
|
oneOf(db).mergeMessageMetadata(txn2, messageId, metadata);
|
||||||
// Deliver the first message
|
// Deliver the first message
|
||||||
oneOf(hook).incomingMessage(txn2, message, metadata);
|
oneOf(hook).incomingMessage(txn2, message, metadata);
|
||||||
@@ -152,23 +136,17 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
// Get any pending dependents
|
// Get any pending dependents
|
||||||
oneOf(db).getMessageDependents(txn2, messageId);
|
oneOf(db).getMessageDependents(txn2, messageId);
|
||||||
will(returnValue(emptyMap()));
|
will(returnValue(emptyMap()));
|
||||||
oneOf(db).commitTransaction(txn2);
|
|
||||||
oneOf(db).endTransaction(txn2);
|
|
||||||
// Load the second raw message and group
|
// Load the second raw message and group
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn3));
|
||||||
will(returnValue(txn3));
|
|
||||||
oneOf(db).getMessage(txn3, messageId1);
|
oneOf(db).getMessage(txn3, messageId1);
|
||||||
will(returnValue(message1));
|
will(returnValue(message1));
|
||||||
oneOf(db).getGroup(txn3, groupId);
|
oneOf(db).getGroup(txn3, groupId);
|
||||||
will(returnValue(group));
|
will(returnValue(group));
|
||||||
oneOf(db).commitTransaction(txn3);
|
|
||||||
oneOf(db).endTransaction(txn3);
|
|
||||||
// Validate the second message: invalid
|
// Validate the second message: invalid
|
||||||
oneOf(validator).validateMessage(message1, group);
|
oneOf(validator).validateMessage(message1, group);
|
||||||
will(throwException(new InvalidMessageException()));
|
will(throwException(new InvalidMessageException()));
|
||||||
// Store the validation result for the second message
|
// Store the validation result for the second message
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn4));
|
||||||
will(returnValue(txn4));
|
|
||||||
oneOf(db).getMessageState(txn4, messageId1);
|
oneOf(db).getMessageState(txn4, messageId1);
|
||||||
will(returnValue(UNKNOWN));
|
will(returnValue(UNKNOWN));
|
||||||
oneOf(db).setMessageState(txn4, messageId1, INVALID);
|
oneOf(db).setMessageState(txn4, messageId1, INVALID);
|
||||||
@@ -177,22 +155,14 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
// Recursively invalidate any dependents
|
// Recursively invalidate any dependents
|
||||||
oneOf(db).getMessageDependents(txn4, messageId1);
|
oneOf(db).getMessageDependents(txn4, messageId1);
|
||||||
will(returnValue(emptyMap()));
|
will(returnValue(emptyMap()));
|
||||||
oneOf(db).commitTransaction(txn4);
|
|
||||||
oneOf(db).endTransaction(txn4);
|
|
||||||
// Get pending messages to deliver
|
// Get pending messages to deliver
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn5));
|
||||||
will(returnValue(txn5));
|
|
||||||
oneOf(db).getPendingMessages(txn5);
|
oneOf(db).getPendingMessages(txn5);
|
||||||
will(returnValue(emptyList()));
|
will(returnValue(emptyList()));
|
||||||
oneOf(db).commitTransaction(txn5);
|
|
||||||
oneOf(db).endTransaction(txn5);
|
|
||||||
// Get messages to share
|
// Get messages to share
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn6));
|
||||||
will(returnValue(txn6));
|
|
||||||
oneOf(db).getMessagesToShare(txn6);
|
oneOf(db).getMessagesToShare(txn6);
|
||||||
will(returnValue(emptyList()));
|
will(returnValue(emptyList()));
|
||||||
oneOf(db).commitTransaction(txn6);
|
|
||||||
oneOf(db).endTransaction(txn6);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
vm.startService();
|
vm.startService();
|
||||||
@@ -206,24 +176,17 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
Transaction txn3 = new Transaction(null, false);
|
Transaction txn3 = new Transaction(null, false);
|
||||||
Transaction txn4 = new Transaction(null, true);
|
Transaction txn4 = new Transaction(null, true);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
// Get messages to validate
|
// Get messages to validate
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).getMessagesToValidate(txn);
|
oneOf(db).getMessagesToValidate(txn);
|
||||||
will(returnValue(emptyList()));
|
will(returnValue(emptyList()));
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
// Get pending messages to deliver
|
// Get pending messages to deliver
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn1));
|
||||||
will(returnValue(txn1));
|
|
||||||
oneOf(db).getPendingMessages(txn1);
|
oneOf(db).getPendingMessages(txn1);
|
||||||
will(returnValue(singletonList(messageId)));
|
will(returnValue(singletonList(messageId)));
|
||||||
oneOf(db).commitTransaction(txn1);
|
|
||||||
oneOf(db).endTransaction(txn1);
|
|
||||||
// Check whether the message is ready to deliver
|
// Check whether the message is ready to deliver
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn2));
|
||||||
will(returnValue(txn2));
|
|
||||||
oneOf(db).getMessageState(txn2, messageId);
|
oneOf(db).getMessageState(txn2, messageId);
|
||||||
will(returnValue(PENDING));
|
will(returnValue(PENDING));
|
||||||
oneOf(db).getMessageDependencies(txn2, messageId);
|
oneOf(db).getMessageDependencies(txn2, messageId);
|
||||||
@@ -242,11 +205,8 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
// Get any pending dependents
|
// Get any pending dependents
|
||||||
oneOf(db).getMessageDependents(txn2, messageId);
|
oneOf(db).getMessageDependents(txn2, messageId);
|
||||||
will(returnValue(singletonMap(messageId2, PENDING)));
|
will(returnValue(singletonMap(messageId2, PENDING)));
|
||||||
oneOf(db).commitTransaction(txn2);
|
|
||||||
oneOf(db).endTransaction(txn2);
|
|
||||||
// Check whether the dependent is ready to deliver
|
// Check whether the dependent is ready to deliver
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn3));
|
||||||
will(returnValue(txn3));
|
|
||||||
oneOf(db).getMessageState(txn3, messageId2);
|
oneOf(db).getMessageState(txn3, messageId2);
|
||||||
will(returnValue(PENDING));
|
will(returnValue(PENDING));
|
||||||
oneOf(db).getMessageDependencies(txn3, messageId2);
|
oneOf(db).getMessageDependencies(txn3, messageId2);
|
||||||
@@ -265,16 +225,11 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
// Get any pending dependents
|
// Get any pending dependents
|
||||||
oneOf(db).getMessageDependents(txn3, messageId2);
|
oneOf(db).getMessageDependents(txn3, messageId2);
|
||||||
will(returnValue(emptyMap()));
|
will(returnValue(emptyMap()));
|
||||||
oneOf(db).commitTransaction(txn3);
|
|
||||||
oneOf(db).endTransaction(txn3);
|
|
||||||
|
|
||||||
// Get messages to share
|
// Get messages to share
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn4));
|
||||||
will(returnValue(txn4));
|
|
||||||
oneOf(db).getMessagesToShare(txn4);
|
oneOf(db).getMessagesToShare(txn4);
|
||||||
will(returnValue(emptyList()));
|
will(returnValue(emptyList()));
|
||||||
oneOf(db).commitTransaction(txn4);
|
|
||||||
oneOf(db).endTransaction(txn4);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
vm.startService();
|
vm.startService();
|
||||||
@@ -288,45 +243,30 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
Transaction txn3 = new Transaction(null, false);
|
Transaction txn3 = new Transaction(null, false);
|
||||||
Transaction txn4 = new Transaction(null, false);
|
Transaction txn4 = new Transaction(null, false);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
// No messages to validate
|
// No messages to validate
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).getMessagesToValidate(txn);
|
oneOf(db).getMessagesToValidate(txn);
|
||||||
will(returnValue(emptyList()));
|
will(returnValue(emptyList()));
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
// No pending messages to deliver
|
// No pending messages to deliver
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn1));
|
||||||
will(returnValue(txn1));
|
|
||||||
oneOf(db).getPendingMessages(txn1);
|
oneOf(db).getPendingMessages(txn1);
|
||||||
will(returnValue(emptyList()));
|
will(returnValue(emptyList()));
|
||||||
oneOf(db).commitTransaction(txn1);
|
|
||||||
oneOf(db).endTransaction(txn1);
|
|
||||||
|
|
||||||
// Get messages to share
|
// Get messages to share
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn2));
|
||||||
will(returnValue(txn2));
|
|
||||||
oneOf(db).getMessagesToShare(txn2);
|
oneOf(db).getMessagesToShare(txn2);
|
||||||
will(returnValue(singletonList(messageId)));
|
will(returnValue(singletonList(messageId)));
|
||||||
oneOf(db).commitTransaction(txn2);
|
|
||||||
oneOf(db).endTransaction(txn2);
|
|
||||||
// Share message and get dependencies
|
// Share message and get dependencies
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn3));
|
||||||
will(returnValue(txn3));
|
|
||||||
oneOf(db).setMessageShared(txn3, messageId);
|
oneOf(db).setMessageShared(txn3, messageId);
|
||||||
oneOf(db).getMessageDependencies(txn3, messageId);
|
oneOf(db).getMessageDependencies(txn3, messageId);
|
||||||
will(returnValue(singletonMap(messageId2, DELIVERED)));
|
will(returnValue(singletonMap(messageId2, DELIVERED)));
|
||||||
oneOf(db).commitTransaction(txn3);
|
|
||||||
oneOf(db).endTransaction(txn3);
|
|
||||||
// Share dependency
|
// Share dependency
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn4));
|
||||||
will(returnValue(txn4));
|
|
||||||
oneOf(db).setMessageShared(txn4, messageId2);
|
oneOf(db).setMessageShared(txn4, messageId2);
|
||||||
oneOf(db).getMessageDependencies(txn4, messageId2);
|
oneOf(db).getMessageDependencies(txn4, messageId2);
|
||||||
will(returnValue(emptyMap()));
|
will(returnValue(emptyMap()));
|
||||||
oneOf(db).commitTransaction(txn4);
|
|
||||||
oneOf(db).endTransaction(txn4);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
vm.startService();
|
vm.startService();
|
||||||
@@ -338,20 +278,16 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
Transaction txn1 = new Transaction(null, false);
|
Transaction txn1 = new Transaction(null, false);
|
||||||
Transaction txn2 = new Transaction(null, false);
|
Transaction txn2 = new Transaction(null, false);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
// Load the group
|
// Load the group
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).getGroup(txn, groupId);
|
oneOf(db).getGroup(txn, groupId);
|
||||||
will(returnValue(group));
|
will(returnValue(group));
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
// Validate the message: valid
|
// Validate the message: valid
|
||||||
oneOf(validator).validateMessage(message, group);
|
oneOf(validator).validateMessage(message, group);
|
||||||
will(returnValue(validResultWithDependencies));
|
will(returnValue(validResultWithDependencies));
|
||||||
// Store the validation result
|
// Store the validation result
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn1));
|
||||||
will(returnValue(txn1));
|
|
||||||
oneOf(db).addMessageDependencies(txn1, message,
|
oneOf(db).addMessageDependencies(txn1, message,
|
||||||
validResultWithDependencies.getDependencies());
|
validResultWithDependencies.getDependencies());
|
||||||
oneOf(db).getMessageDependencies(txn1, messageId);
|
oneOf(db).getMessageDependencies(txn1, messageId);
|
||||||
@@ -366,16 +302,11 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
will(returnValue(emptyMap()));
|
will(returnValue(emptyMap()));
|
||||||
// Share message
|
// Share message
|
||||||
oneOf(db).setMessageShared(txn1, messageId);
|
oneOf(db).setMessageShared(txn1, messageId);
|
||||||
oneOf(db).commitTransaction(txn1);
|
|
||||||
oneOf(db).endTransaction(txn1);
|
|
||||||
// Share dependencies
|
// Share dependencies
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn2));
|
||||||
will(returnValue(txn2));
|
|
||||||
oneOf(db).setMessageShared(txn2, messageId1);
|
oneOf(db).setMessageShared(txn2, messageId1);
|
||||||
oneOf(db).getMessageDependencies(txn2, messageId1);
|
oneOf(db).getMessageDependencies(txn2, messageId1);
|
||||||
will(returnValue(emptyMap()));
|
will(returnValue(emptyMap()));
|
||||||
oneOf(db).commitTransaction(txn2);
|
|
||||||
oneOf(db).endTransaction(txn2);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
vm.eventOccurred(new MessageAddedEvent(message, contactId));
|
vm.eventOccurred(new MessageAddedEvent(message, contactId));
|
||||||
@@ -391,36 +322,26 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
Transaction txn4 = new Transaction(null, true);
|
Transaction txn4 = new Transaction(null, true);
|
||||||
Transaction txn5 = new Transaction(null, true);
|
Transaction txn5 = new Transaction(null, true);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
// Get messages to validate
|
// Get messages to validate
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).getMessagesToValidate(txn);
|
oneOf(db).getMessagesToValidate(txn);
|
||||||
will(returnValue(Arrays.asList(messageId, messageId1)));
|
will(returnValue(asList(messageId, messageId1)));
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
// Load the first raw message - *gasp* it's gone!
|
// Load the first raw message - *gasp* it's gone!
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn1));
|
||||||
will(returnValue(txn1));
|
|
||||||
oneOf(db).getMessage(txn1, messageId);
|
oneOf(db).getMessage(txn1, messageId);
|
||||||
will(throwException(new NoSuchMessageException()));
|
will(throwException(new NoSuchMessageException()));
|
||||||
never(db).commitTransaction(txn1);
|
|
||||||
oneOf(db).endTransaction(txn1);
|
|
||||||
// Load the second raw message and group
|
// Load the second raw message and group
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn2));
|
||||||
will(returnValue(txn2));
|
|
||||||
oneOf(db).getMessage(txn2, messageId1);
|
oneOf(db).getMessage(txn2, messageId1);
|
||||||
will(returnValue(message1));
|
will(returnValue(message1));
|
||||||
oneOf(db).getGroup(txn2, groupId);
|
oneOf(db).getGroup(txn2, groupId);
|
||||||
will(returnValue(group));
|
will(returnValue(group));
|
||||||
oneOf(db).commitTransaction(txn2);
|
|
||||||
oneOf(db).endTransaction(txn2);
|
|
||||||
// Validate the second message: invalid
|
// Validate the second message: invalid
|
||||||
oneOf(validator).validateMessage(message1, group);
|
oneOf(validator).validateMessage(message1, group);
|
||||||
will(throwException(new InvalidMessageException()));
|
will(throwException(new InvalidMessageException()));
|
||||||
// Invalidate the second message
|
// Invalidate the second message
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn3));
|
||||||
will(returnValue(txn3));
|
|
||||||
oneOf(db).getMessageState(txn3, messageId1);
|
oneOf(db).getMessageState(txn3, messageId1);
|
||||||
will(returnValue(UNKNOWN));
|
will(returnValue(UNKNOWN));
|
||||||
oneOf(db).setMessageState(txn3, messageId1, INVALID);
|
oneOf(db).setMessageState(txn3, messageId1, INVALID);
|
||||||
@@ -429,22 +350,14 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
// Recursively invalidate dependents
|
// Recursively invalidate dependents
|
||||||
oneOf(db).getMessageDependents(txn3, messageId1);
|
oneOf(db).getMessageDependents(txn3, messageId1);
|
||||||
will(returnValue(emptyMap()));
|
will(returnValue(emptyMap()));
|
||||||
oneOf(db).commitTransaction(txn3);
|
|
||||||
oneOf(db).endTransaction(txn3);
|
|
||||||
// Get pending messages to deliver
|
// Get pending messages to deliver
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn4));
|
||||||
will(returnValue(txn4));
|
|
||||||
oneOf(db).getPendingMessages(txn4);
|
oneOf(db).getPendingMessages(txn4);
|
||||||
will(returnValue(emptyList()));
|
will(returnValue(emptyList()));
|
||||||
oneOf(db).commitTransaction(txn4);
|
|
||||||
oneOf(db).endTransaction(txn4);
|
|
||||||
// Get messages to share
|
// Get messages to share
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn5));
|
||||||
will(returnValue(txn5));
|
|
||||||
oneOf(db).getMessagesToShare(txn5);
|
oneOf(db).getMessagesToShare(txn5);
|
||||||
will(returnValue(emptyList()));
|
will(returnValue(emptyList()));
|
||||||
oneOf(db).commitTransaction(txn5);
|
|
||||||
oneOf(db).endTransaction(txn5);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
vm.startService();
|
vm.startService();
|
||||||
@@ -460,39 +373,29 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
Transaction txn4 = new Transaction(null, true);
|
Transaction txn4 = new Transaction(null, true);
|
||||||
Transaction txn5 = new Transaction(null, true);
|
Transaction txn5 = new Transaction(null, true);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
// Get messages to validate
|
// Get messages to validate
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).getMessagesToValidate(txn);
|
oneOf(db).getMessagesToValidate(txn);
|
||||||
will(returnValue(Arrays.asList(messageId, messageId1)));
|
will(returnValue(asList(messageId, messageId1)));
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
// Load the first raw message
|
// Load the first raw message
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn1));
|
||||||
will(returnValue(txn1));
|
|
||||||
oneOf(db).getMessage(txn1, messageId);
|
oneOf(db).getMessage(txn1, messageId);
|
||||||
will(returnValue(message));
|
will(returnValue(message));
|
||||||
// Load the group - *gasp* it's gone!
|
// Load the group - *gasp* it's gone!
|
||||||
oneOf(db).getGroup(txn1, groupId);
|
oneOf(db).getGroup(txn1, groupId);
|
||||||
will(throwException(new NoSuchGroupException()));
|
will(throwException(new NoSuchGroupException()));
|
||||||
never(db).commitTransaction(txn1);
|
|
||||||
oneOf(db).endTransaction(txn1);
|
|
||||||
// Load the second raw message and group
|
// Load the second raw message and group
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn2));
|
||||||
will(returnValue(txn2));
|
|
||||||
oneOf(db).getMessage(txn2, messageId1);
|
oneOf(db).getMessage(txn2, messageId1);
|
||||||
will(returnValue(message1));
|
will(returnValue(message1));
|
||||||
oneOf(db).getGroup(txn2, groupId);
|
oneOf(db).getGroup(txn2, groupId);
|
||||||
will(returnValue(group));
|
will(returnValue(group));
|
||||||
oneOf(db).commitTransaction(txn2);
|
|
||||||
oneOf(db).endTransaction(txn2);
|
|
||||||
// Validate the second message: invalid
|
// Validate the second message: invalid
|
||||||
oneOf(validator).validateMessage(message1, group);
|
oneOf(validator).validateMessage(message1, group);
|
||||||
will(throwException(new InvalidMessageException()));
|
will(throwException(new InvalidMessageException()));
|
||||||
// Store the validation result for the second message
|
// Store the validation result for the second message
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn3));
|
||||||
will(returnValue(txn3));
|
|
||||||
oneOf(db).getMessageState(txn3, messageId1);
|
oneOf(db).getMessageState(txn3, messageId1);
|
||||||
will(returnValue(UNKNOWN));
|
will(returnValue(UNKNOWN));
|
||||||
oneOf(db).setMessageState(txn3, messageId1, INVALID);
|
oneOf(db).setMessageState(txn3, messageId1, INVALID);
|
||||||
@@ -501,22 +404,14 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
// Recursively invalidate dependents
|
// Recursively invalidate dependents
|
||||||
oneOf(db).getMessageDependents(txn3, messageId1);
|
oneOf(db).getMessageDependents(txn3, messageId1);
|
||||||
will(returnValue(emptyMap()));
|
will(returnValue(emptyMap()));
|
||||||
oneOf(db).commitTransaction(txn3);
|
|
||||||
oneOf(db).endTransaction(txn3);
|
|
||||||
// Get pending messages to deliver
|
// Get pending messages to deliver
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn4));
|
||||||
will(returnValue(txn4));
|
|
||||||
oneOf(db).getPendingMessages(txn4);
|
oneOf(db).getPendingMessages(txn4);
|
||||||
will(returnValue(emptyList()));
|
will(returnValue(emptyList()));
|
||||||
oneOf(db).commitTransaction(txn4);
|
|
||||||
oneOf(db).endTransaction(txn4);
|
|
||||||
// Get messages to share
|
// Get messages to share
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn5));
|
||||||
will(returnValue(txn5));
|
|
||||||
oneOf(db).getMessagesToShare(txn5);
|
oneOf(db).getMessagesToShare(txn5);
|
||||||
will(returnValue(emptyList()));
|
will(returnValue(emptyList()));
|
||||||
oneOf(db).commitTransaction(txn5);
|
|
||||||
oneOf(db).endTransaction(txn5);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
vm.startService();
|
vm.startService();
|
||||||
@@ -527,20 +422,16 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
Transaction txn = new Transaction(null, true);
|
Transaction txn = new Transaction(null, true);
|
||||||
Transaction txn1 = new Transaction(null, false);
|
Transaction txn1 = new Transaction(null, false);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
// Load the group
|
// Load the group
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).getGroup(txn, groupId);
|
oneOf(db).getGroup(txn, groupId);
|
||||||
will(returnValue(group));
|
will(returnValue(group));
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
// Validate the message: valid
|
// Validate the message: valid
|
||||||
oneOf(validator).validateMessage(message, group);
|
oneOf(validator).validateMessage(message, group);
|
||||||
will(returnValue(validResult));
|
will(returnValue(validResult));
|
||||||
// Store the validation result
|
// Store the validation result
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn1));
|
||||||
will(returnValue(txn1));
|
|
||||||
oneOf(db).mergeMessageMetadata(txn1, messageId, metadata);
|
oneOf(db).mergeMessageMetadata(txn1, messageId, metadata);
|
||||||
// Deliver the message
|
// Deliver the message
|
||||||
oneOf(hook).incomingMessage(txn1, message, metadata);
|
oneOf(hook).incomingMessage(txn1, message, metadata);
|
||||||
@@ -549,8 +440,6 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
// Get any pending dependents
|
// Get any pending dependents
|
||||||
oneOf(db).getMessageDependents(txn1, messageId);
|
oneOf(db).getMessageDependents(txn1, messageId);
|
||||||
will(returnValue(emptyMap()));
|
will(returnValue(emptyMap()));
|
||||||
oneOf(db).commitTransaction(txn1);
|
|
||||||
oneOf(db).endTransaction(txn1);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
vm.eventOccurred(new MessageAddedEvent(message, contactId));
|
vm.eventOccurred(new MessageAddedEvent(message, contactId));
|
||||||
@@ -567,28 +456,22 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
Transaction txn = new Transaction(null, true);
|
Transaction txn = new Transaction(null, true);
|
||||||
Transaction txn1 = new Transaction(null, false);
|
Transaction txn1 = new Transaction(null, false);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
// Load the group
|
// Load the group
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).getGroup(txn, groupId);
|
oneOf(db).getGroup(txn, groupId);
|
||||||
will(returnValue(group));
|
will(returnValue(group));
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
// Validate the message: valid
|
// Validate the message: valid
|
||||||
oneOf(validator).validateMessage(message, group);
|
oneOf(validator).validateMessage(message, group);
|
||||||
will(returnValue(validResultWithDependencies));
|
will(returnValue(validResultWithDependencies));
|
||||||
// Store the validation result
|
// Store the validation result
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn1));
|
||||||
will(returnValue(txn1));
|
|
||||||
oneOf(db).addMessageDependencies(txn1, message,
|
oneOf(db).addMessageDependencies(txn1, message,
|
||||||
validResultWithDependencies.getDependencies());
|
validResultWithDependencies.getDependencies());
|
||||||
oneOf(db).getMessageDependencies(txn1, messageId);
|
oneOf(db).getMessageDependencies(txn1, messageId);
|
||||||
will(returnValue(singletonMap(messageId1, UNKNOWN)));
|
will(returnValue(singletonMap(messageId1, UNKNOWN)));
|
||||||
oneOf(db).mergeMessageMetadata(txn1, messageId, metadata);
|
oneOf(db).mergeMessageMetadata(txn1, messageId, metadata);
|
||||||
oneOf(db).setMessageState(txn1, messageId, PENDING);
|
oneOf(db).setMessageState(txn1, messageId, PENDING);
|
||||||
oneOf(db).commitTransaction(txn1);
|
|
||||||
oneOf(db).endTransaction(txn1);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
vm.eventOccurred(new MessageAddedEvent(message, contactId));
|
vm.eventOccurred(new MessageAddedEvent(message, contactId));
|
||||||
@@ -600,20 +483,16 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
Transaction txn = new Transaction(null, true);
|
Transaction txn = new Transaction(null, true);
|
||||||
Transaction txn1 = new Transaction(null, false);
|
Transaction txn1 = new Transaction(null, false);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
// Load the group
|
// Load the group
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).getGroup(txn, groupId);
|
oneOf(db).getGroup(txn, groupId);
|
||||||
will(returnValue(group));
|
will(returnValue(group));
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
// Validate the message: valid
|
// Validate the message: valid
|
||||||
oneOf(validator).validateMessage(message, group);
|
oneOf(validator).validateMessage(message, group);
|
||||||
will(returnValue(validResultWithDependencies));
|
will(returnValue(validResultWithDependencies));
|
||||||
// Store the validation result
|
// Store the validation result
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn1));
|
||||||
will(returnValue(txn1));
|
|
||||||
oneOf(db).addMessageDependencies(txn1, message,
|
oneOf(db).addMessageDependencies(txn1, message,
|
||||||
validResultWithDependencies.getDependencies());
|
validResultWithDependencies.getDependencies());
|
||||||
oneOf(db).getMessageDependencies(txn1, messageId);
|
oneOf(db).getMessageDependencies(txn1, messageId);
|
||||||
@@ -626,8 +505,6 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
// Get any pending dependents
|
// Get any pending dependents
|
||||||
oneOf(db).getMessageDependents(txn1, messageId);
|
oneOf(db).getMessageDependents(txn1, messageId);
|
||||||
will(returnValue(emptyMap()));
|
will(returnValue(emptyMap()));
|
||||||
oneOf(db).commitTransaction(txn1);
|
|
||||||
oneOf(db).endTransaction(txn1);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
vm.eventOccurred(new MessageAddedEvent(message, contactId));
|
vm.eventOccurred(new MessageAddedEvent(message, contactId));
|
||||||
@@ -640,20 +517,16 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
Transaction txn1 = new Transaction(null, false);
|
Transaction txn1 = new Transaction(null, false);
|
||||||
Transaction txn2 = new Transaction(null, false);
|
Transaction txn2 = new Transaction(null, false);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
// Load the group
|
// Load the group
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).getGroup(txn, groupId);
|
oneOf(db).getGroup(txn, groupId);
|
||||||
will(returnValue(group));
|
will(returnValue(group));
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
// Validate the message: valid
|
// Validate the message: valid
|
||||||
oneOf(validator).validateMessage(message, group);
|
oneOf(validator).validateMessage(message, group);
|
||||||
will(returnValue(validResultWithDependencies));
|
will(returnValue(validResultWithDependencies));
|
||||||
// Store the validation result
|
// Store the validation result
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn1));
|
||||||
will(returnValue(txn1));
|
|
||||||
oneOf(db).addMessageDependencies(txn1, message,
|
oneOf(db).addMessageDependencies(txn1, message,
|
||||||
validResultWithDependencies.getDependencies());
|
validResultWithDependencies.getDependencies());
|
||||||
// Check for invalid dependencies
|
// Check for invalid dependencies
|
||||||
@@ -668,11 +541,8 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
// Recursively invalidate dependents
|
// Recursively invalidate dependents
|
||||||
oneOf(db).getMessageDependents(txn1, messageId);
|
oneOf(db).getMessageDependents(txn1, messageId);
|
||||||
will(returnValue(singletonMap(messageId2, UNKNOWN)));
|
will(returnValue(singletonMap(messageId2, UNKNOWN)));
|
||||||
oneOf(db).commitTransaction(txn1);
|
|
||||||
oneOf(db).endTransaction(txn1);
|
|
||||||
// Invalidate dependent in a new transaction
|
// Invalidate dependent in a new transaction
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn2));
|
||||||
will(returnValue(txn2));
|
|
||||||
oneOf(db).getMessageState(txn2, messageId2);
|
oneOf(db).getMessageState(txn2, messageId2);
|
||||||
will(returnValue(UNKNOWN));
|
will(returnValue(UNKNOWN));
|
||||||
oneOf(db).setMessageState(txn2, messageId2, INVALID);
|
oneOf(db).setMessageState(txn2, messageId2, INVALID);
|
||||||
@@ -680,8 +550,6 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
oneOf(db).deleteMessageMetadata(txn2, messageId2);
|
oneOf(db).deleteMessageMetadata(txn2, messageId2);
|
||||||
oneOf(db).getMessageDependents(txn2, messageId2);
|
oneOf(db).getMessageDependents(txn2, messageId2);
|
||||||
will(returnValue(emptyMap()));
|
will(returnValue(emptyMap()));
|
||||||
oneOf(db).commitTransaction(txn2);
|
|
||||||
oneOf(db).endTransaction(txn2);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
vm.eventOccurred(new MessageAddedEvent(message, contactId));
|
vm.eventOccurred(new MessageAddedEvent(message, contactId));
|
||||||
@@ -691,7 +559,7 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
public void testRecursiveInvalidation() throws Exception {
|
public void testRecursiveInvalidation() throws Exception {
|
||||||
MessageId messageId3 = new MessageId(getRandomId());
|
MessageId messageId3 = new MessageId(getRandomId());
|
||||||
MessageId messageId4 = new MessageId(getRandomId());
|
MessageId messageId4 = new MessageId(getRandomId());
|
||||||
Map<MessageId, State> twoDependents = new LinkedHashMap<>();
|
Map<MessageId, MessageState> twoDependents = new LinkedHashMap<>();
|
||||||
twoDependents.put(messageId1, PENDING);
|
twoDependents.put(messageId1, PENDING);
|
||||||
twoDependents.put(messageId2, PENDING);
|
twoDependents.put(messageId2, PENDING);
|
||||||
Transaction txn = new Transaction(null, true);
|
Transaction txn = new Transaction(null, true);
|
||||||
@@ -702,20 +570,16 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
Transaction txn5 = new Transaction(null, false);
|
Transaction txn5 = new Transaction(null, false);
|
||||||
Transaction txn6 = new Transaction(null, false);
|
Transaction txn6 = new Transaction(null, false);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
// Load the group
|
// Load the group
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).getGroup(txn, groupId);
|
oneOf(db).getGroup(txn, groupId);
|
||||||
will(returnValue(group));
|
will(returnValue(group));
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
// Validate the message: invalid
|
// Validate the message: invalid
|
||||||
oneOf(validator).validateMessage(message, group);
|
oneOf(validator).validateMessage(message, group);
|
||||||
will(throwException(new InvalidMessageException()));
|
will(throwException(new InvalidMessageException()));
|
||||||
// Invalidate the message
|
// Invalidate the message
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn1));
|
||||||
will(returnValue(txn1));
|
|
||||||
oneOf(db).getMessageState(txn1, messageId);
|
oneOf(db).getMessageState(txn1, messageId);
|
||||||
will(returnValue(UNKNOWN));
|
will(returnValue(UNKNOWN));
|
||||||
oneOf(db).setMessageState(txn1, messageId, INVALID);
|
oneOf(db).setMessageState(txn1, messageId, INVALID);
|
||||||
@@ -724,11 +588,8 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
// The message has two dependents: 1 and 2
|
// The message has two dependents: 1 and 2
|
||||||
oneOf(db).getMessageDependents(txn1, messageId);
|
oneOf(db).getMessageDependents(txn1, messageId);
|
||||||
will(returnValue(twoDependents));
|
will(returnValue(twoDependents));
|
||||||
oneOf(db).commitTransaction(txn1);
|
|
||||||
oneOf(db).endTransaction(txn1);
|
|
||||||
// Invalidate message 1
|
// Invalidate message 1
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn2));
|
||||||
will(returnValue(txn2));
|
|
||||||
oneOf(db).getMessageState(txn2, messageId1);
|
oneOf(db).getMessageState(txn2, messageId1);
|
||||||
will(returnValue(PENDING));
|
will(returnValue(PENDING));
|
||||||
oneOf(db).setMessageState(txn2, messageId1, INVALID);
|
oneOf(db).setMessageState(txn2, messageId1, INVALID);
|
||||||
@@ -737,11 +598,8 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
// Message 1 has one dependent: 3
|
// Message 1 has one dependent: 3
|
||||||
oneOf(db).getMessageDependents(txn2, messageId1);
|
oneOf(db).getMessageDependents(txn2, messageId1);
|
||||||
will(returnValue(singletonMap(messageId3, PENDING)));
|
will(returnValue(singletonMap(messageId3, PENDING)));
|
||||||
oneOf(db).commitTransaction(txn2);
|
|
||||||
oneOf(db).endTransaction(txn2);
|
|
||||||
// Invalidate message 2
|
// Invalidate message 2
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn3));
|
||||||
will(returnValue(txn3));
|
|
||||||
oneOf(db).getMessageState(txn3, messageId2);
|
oneOf(db).getMessageState(txn3, messageId2);
|
||||||
will(returnValue(PENDING));
|
will(returnValue(PENDING));
|
||||||
oneOf(db).setMessageState(txn3, messageId2, INVALID);
|
oneOf(db).setMessageState(txn3, messageId2, INVALID);
|
||||||
@@ -750,11 +608,8 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
// Message 2 has one dependent: 3 (same dependent as 1)
|
// Message 2 has one dependent: 3 (same dependent as 1)
|
||||||
oneOf(db).getMessageDependents(txn3, messageId2);
|
oneOf(db).getMessageDependents(txn3, messageId2);
|
||||||
will(returnValue(singletonMap(messageId3, PENDING)));
|
will(returnValue(singletonMap(messageId3, PENDING)));
|
||||||
oneOf(db).commitTransaction(txn3);
|
|
||||||
oneOf(db).endTransaction(txn3);
|
|
||||||
// Invalidate message 3 (via 1)
|
// Invalidate message 3 (via 1)
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn4));
|
||||||
will(returnValue(txn4));
|
|
||||||
oneOf(db).getMessageState(txn4, messageId3);
|
oneOf(db).getMessageState(txn4, messageId3);
|
||||||
will(returnValue(PENDING));
|
will(returnValue(PENDING));
|
||||||
oneOf(db).setMessageState(txn4, messageId3, INVALID);
|
oneOf(db).setMessageState(txn4, messageId3, INVALID);
|
||||||
@@ -763,18 +618,12 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
// Message 3 has one dependent: 4
|
// Message 3 has one dependent: 4
|
||||||
oneOf(db).getMessageDependents(txn4, messageId3);
|
oneOf(db).getMessageDependents(txn4, messageId3);
|
||||||
will(returnValue(singletonMap(messageId4, PENDING)));
|
will(returnValue(singletonMap(messageId4, PENDING)));
|
||||||
oneOf(db).commitTransaction(txn4);
|
|
||||||
oneOf(db).endTransaction(txn4);
|
|
||||||
// Invalidate message 3 (again, via 2)
|
// Invalidate message 3 (again, via 2)
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn5));
|
||||||
will(returnValue(txn5));
|
|
||||||
oneOf(db).getMessageState(txn5, messageId3);
|
oneOf(db).getMessageState(txn5, messageId3);
|
||||||
will(returnValue(INVALID)); // Already invalidated
|
will(returnValue(INVALID)); // Already invalidated
|
||||||
oneOf(db).commitTransaction(txn5);
|
|
||||||
oneOf(db).endTransaction(txn5);
|
|
||||||
// Invalidate message 4 (via 1 and 3)
|
// Invalidate message 4 (via 1 and 3)
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn6));
|
||||||
will(returnValue(txn6));
|
|
||||||
oneOf(db).getMessageState(txn6, messageId4);
|
oneOf(db).getMessageState(txn6, messageId4);
|
||||||
will(returnValue(PENDING));
|
will(returnValue(PENDING));
|
||||||
oneOf(db).setMessageState(txn6, messageId4, INVALID);
|
oneOf(db).setMessageState(txn6, messageId4, INVALID);
|
||||||
@@ -783,8 +632,6 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
// Message 4 has no dependents
|
// Message 4 has no dependents
|
||||||
oneOf(db).getMessageDependents(txn6, messageId4);
|
oneOf(db).getMessageDependents(txn6, messageId4);
|
||||||
will(returnValue(emptyMap()));
|
will(returnValue(emptyMap()));
|
||||||
oneOf(db).commitTransaction(txn6);
|
|
||||||
oneOf(db).endTransaction(txn6);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
vm.eventOccurred(new MessageAddedEvent(message, contactId));
|
vm.eventOccurred(new MessageAddedEvent(message, contactId));
|
||||||
@@ -796,10 +643,10 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
Message message4 = getMessage(groupId);
|
Message message4 = getMessage(groupId);
|
||||||
MessageId messageId3 = message3.getId();
|
MessageId messageId3 = message3.getId();
|
||||||
MessageId messageId4 = message4.getId();
|
MessageId messageId4 = message4.getId();
|
||||||
Map<MessageId, State> twoDependents = new LinkedHashMap<>();
|
Map<MessageId, MessageState> twoDependents = new LinkedHashMap<>();
|
||||||
twoDependents.put(messageId1, PENDING);
|
twoDependents.put(messageId1, PENDING);
|
||||||
twoDependents.put(messageId2, PENDING);
|
twoDependents.put(messageId2, PENDING);
|
||||||
Map<MessageId, State> twoDependencies = new LinkedHashMap<>();
|
Map<MessageId, MessageState> twoDependencies = new LinkedHashMap<>();
|
||||||
twoDependencies.put(messageId1, DELIVERED);
|
twoDependencies.put(messageId1, DELIVERED);
|
||||||
twoDependencies.put(messageId2, DELIVERED);
|
twoDependencies.put(messageId2, DELIVERED);
|
||||||
Transaction txn = new Transaction(null, true);
|
Transaction txn = new Transaction(null, true);
|
||||||
@@ -810,20 +657,16 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
Transaction txn5 = new Transaction(null, false);
|
Transaction txn5 = new Transaction(null, false);
|
||||||
Transaction txn6 = new Transaction(null, false);
|
Transaction txn6 = new Transaction(null, false);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
// Load the group
|
// Load the group
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).getGroup(txn, groupId);
|
oneOf(db).getGroup(txn, groupId);
|
||||||
will(returnValue(group));
|
will(returnValue(group));
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
// Validate the message: valid
|
// Validate the message: valid
|
||||||
oneOf(validator).validateMessage(message, group);
|
oneOf(validator).validateMessage(message, group);
|
||||||
will(returnValue(validResult));
|
will(returnValue(validResult));
|
||||||
// Store the validation result
|
// Store the validation result
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn1));
|
||||||
will(returnValue(txn1));
|
|
||||||
oneOf(db).mergeMessageMetadata(txn1, messageId, metadata);
|
oneOf(db).mergeMessageMetadata(txn1, messageId, metadata);
|
||||||
// Deliver the message
|
// Deliver the message
|
||||||
oneOf(hook).incomingMessage(txn1, message, metadata);
|
oneOf(hook).incomingMessage(txn1, message, metadata);
|
||||||
@@ -832,11 +675,8 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
// The message has two pending dependents: 1 and 2
|
// The message has two pending dependents: 1 and 2
|
||||||
oneOf(db).getMessageDependents(txn1, messageId);
|
oneOf(db).getMessageDependents(txn1, messageId);
|
||||||
will(returnValue(twoDependents));
|
will(returnValue(twoDependents));
|
||||||
oneOf(db).commitTransaction(txn1);
|
|
||||||
oneOf(db).endTransaction(txn1);
|
|
||||||
// Check whether message 1 is ready to be delivered
|
// Check whether message 1 is ready to be delivered
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn2));
|
||||||
will(returnValue(txn2));
|
|
||||||
oneOf(db).getMessageState(txn2, messageId1);
|
oneOf(db).getMessageState(txn2, messageId1);
|
||||||
will(returnValue(PENDING));
|
will(returnValue(PENDING));
|
||||||
oneOf(db).getMessageDependencies(txn2, messageId1);
|
oneOf(db).getMessageDependencies(txn2, messageId1);
|
||||||
@@ -855,11 +695,8 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
// Message 1 has one pending dependent: 3
|
// Message 1 has one pending dependent: 3
|
||||||
oneOf(db).getMessageDependents(txn2, messageId1);
|
oneOf(db).getMessageDependents(txn2, messageId1);
|
||||||
will(returnValue(singletonMap(messageId3, PENDING)));
|
will(returnValue(singletonMap(messageId3, PENDING)));
|
||||||
oneOf(db).commitTransaction(txn2);
|
|
||||||
oneOf(db).endTransaction(txn2);
|
|
||||||
// Check whether message 2 is ready to be delivered
|
// Check whether message 2 is ready to be delivered
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn3));
|
||||||
will(returnValue(txn3));
|
|
||||||
oneOf(db).getMessageState(txn3, messageId2);
|
oneOf(db).getMessageState(txn3, messageId2);
|
||||||
will(returnValue(PENDING));
|
will(returnValue(PENDING));
|
||||||
oneOf(db).getMessageDependencies(txn3, messageId2);
|
oneOf(db).getMessageDependencies(txn3, messageId2);
|
||||||
@@ -878,11 +715,8 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
// Message 2 has one pending dependent: 3 (same dependent as 1)
|
// Message 2 has one pending dependent: 3 (same dependent as 1)
|
||||||
oneOf(db).getMessageDependents(txn3, messageId2);
|
oneOf(db).getMessageDependents(txn3, messageId2);
|
||||||
will(returnValue(singletonMap(messageId3, PENDING)));
|
will(returnValue(singletonMap(messageId3, PENDING)));
|
||||||
oneOf(db).commitTransaction(txn3);
|
|
||||||
oneOf(db).endTransaction(txn3);
|
|
||||||
// Check whether message 3 is ready to be delivered (via 1)
|
// Check whether message 3 is ready to be delivered (via 1)
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn4));
|
||||||
will(returnValue(txn4));
|
|
||||||
oneOf(db).getMessageState(txn4, messageId3);
|
oneOf(db).getMessageState(txn4, messageId3);
|
||||||
will(returnValue(PENDING));
|
will(returnValue(PENDING));
|
||||||
oneOf(db).getMessageDependencies(txn4, messageId3);
|
oneOf(db).getMessageDependencies(txn4, messageId3);
|
||||||
@@ -900,18 +734,12 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
// Message 3 has one pending dependent: 4
|
// Message 3 has one pending dependent: 4
|
||||||
oneOf(db).getMessageDependents(txn4, messageId3);
|
oneOf(db).getMessageDependents(txn4, messageId3);
|
||||||
will(returnValue(singletonMap(messageId4, PENDING)));
|
will(returnValue(singletonMap(messageId4, PENDING)));
|
||||||
oneOf(db).commitTransaction(txn4);
|
|
||||||
oneOf(db).endTransaction(txn4);
|
|
||||||
// Check whether message 3 is ready to be delivered (again, via 2)
|
// Check whether message 3 is ready to be delivered (again, via 2)
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn5));
|
||||||
will(returnValue(txn5));
|
|
||||||
oneOf(db).getMessageState(txn5, messageId3);
|
oneOf(db).getMessageState(txn5, messageId3);
|
||||||
will(returnValue(DELIVERED)); // Already delivered
|
will(returnValue(DELIVERED)); // Already delivered
|
||||||
oneOf(db).commitTransaction(txn5);
|
|
||||||
oneOf(db).endTransaction(txn5);
|
|
||||||
// Check whether message 4 is ready to be delivered (via 1 and 3)
|
// Check whether message 4 is ready to be delivered (via 1 and 3)
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn6));
|
||||||
will(returnValue(txn6));
|
|
||||||
oneOf(db).getMessageState(txn6, messageId4);
|
oneOf(db).getMessageState(txn6, messageId4);
|
||||||
will(returnValue(PENDING));
|
will(returnValue(PENDING));
|
||||||
oneOf(db).getMessageDependencies(txn6, messageId4);
|
oneOf(db).getMessageDependencies(txn6, messageId4);
|
||||||
@@ -930,8 +758,6 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
// Message 4 has no pending dependents
|
// Message 4 has no pending dependents
|
||||||
oneOf(db).getMessageDependents(txn6, messageId4);
|
oneOf(db).getMessageDependents(txn6, messageId4);
|
||||||
will(returnValue(emptyMap()));
|
will(returnValue(emptyMap()));
|
||||||
oneOf(db).commitTransaction(txn6);
|
|
||||||
oneOf(db).endTransaction(txn6);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
vm.eventOccurred(new MessageAddedEvent(message, contactId));
|
vm.eventOccurred(new MessageAddedEvent(message, contactId));
|
||||||
@@ -939,27 +765,23 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOnlyReadyPendingDependentsGetDelivered() throws Exception {
|
public void testOnlyReadyPendingDependentsGetDelivered() throws Exception {
|
||||||
Map<MessageId, State> twoDependencies = new LinkedHashMap<>();
|
Map<MessageId, MessageState> twoDependencies = new LinkedHashMap<>();
|
||||||
twoDependencies.put(messageId, DELIVERED);
|
twoDependencies.put(messageId, DELIVERED);
|
||||||
twoDependencies.put(messageId2, UNKNOWN);
|
twoDependencies.put(messageId2, UNKNOWN);
|
||||||
Transaction txn = new Transaction(null, true);
|
Transaction txn = new Transaction(null, true);
|
||||||
Transaction txn1 = new Transaction(null, false);
|
Transaction txn1 = new Transaction(null, false);
|
||||||
Transaction txn2 = new Transaction(null, false);
|
Transaction txn2 = new Transaction(null, false);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
// Load the group
|
// Load the group
|
||||||
oneOf(db).startTransaction(true);
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||||
will(returnValue(txn));
|
|
||||||
oneOf(db).getGroup(txn, groupId);
|
oneOf(db).getGroup(txn, groupId);
|
||||||
will(returnValue(group));
|
will(returnValue(group));
|
||||||
oneOf(db).commitTransaction(txn);
|
|
||||||
oneOf(db).endTransaction(txn);
|
|
||||||
// Validate the message: valid
|
// Validate the message: valid
|
||||||
oneOf(validator).validateMessage(message, group);
|
oneOf(validator).validateMessage(message, group);
|
||||||
will(returnValue(validResult));
|
will(returnValue(validResult));
|
||||||
// Store the validation result
|
// Store the validation result
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn1));
|
||||||
will(returnValue(txn1));
|
|
||||||
oneOf(db).mergeMessageMetadata(txn1, messageId, metadata);
|
oneOf(db).mergeMessageMetadata(txn1, messageId, metadata);
|
||||||
// Deliver the message
|
// Deliver the message
|
||||||
oneOf(hook).incomingMessage(txn1, message, metadata);
|
oneOf(hook).incomingMessage(txn1, message, metadata);
|
||||||
@@ -968,17 +790,12 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
|||||||
// Get any pending dependents
|
// Get any pending dependents
|
||||||
oneOf(db).getMessageDependents(txn1, messageId);
|
oneOf(db).getMessageDependents(txn1, messageId);
|
||||||
will(returnValue(singletonMap(messageId1, PENDING)));
|
will(returnValue(singletonMap(messageId1, PENDING)));
|
||||||
oneOf(db).commitTransaction(txn1);
|
|
||||||
oneOf(db).endTransaction(txn1);
|
|
||||||
// Check whether the pending dependent is ready to be delivered
|
// Check whether the pending dependent is ready to be delivered
|
||||||
oneOf(db).startTransaction(false);
|
oneOf(db).transaction(with(false), withDbRunnable(txn2));
|
||||||
will(returnValue(txn2));
|
|
||||||
oneOf(db).getMessageState(txn2, messageId1);
|
oneOf(db).getMessageState(txn2, messageId1);
|
||||||
will(returnValue(PENDING));
|
will(returnValue(PENDING));
|
||||||
oneOf(db).getMessageDependencies(txn2, messageId1);
|
oneOf(db).getMessageDependencies(txn2, messageId1);
|
||||||
will(returnValue(twoDependencies));
|
will(returnValue(twoDependencies));
|
||||||
oneOf(db).commitTransaction(txn2);
|
|
||||||
oneOf(db).endTransaction(txn2);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
vm.eventOccurred(new MessageAddedEvent(message, contactId));
|
vm.eventOccurred(new MessageAddedEvent(message, contactId));
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
package org.briarproject.bramble.system;
|
package org.briarproject.bramble.system;
|
||||||
|
|
||||||
import org.briarproject.bramble.test.BrambleTestCase;
|
import org.briarproject.bramble.test.BrambleTestCase;
|
||||||
import org.briarproject.bramble.test.TestUtils;
|
|
||||||
import org.briarproject.bramble.util.OsUtils;
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -10,48 +8,50 @@ import org.junit.Test;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.security.Provider;
|
import java.security.Provider;
|
||||||
|
|
||||||
|
import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory;
|
||||||
|
import static org.briarproject.bramble.test.TestUtils.getTestDirectory;
|
||||||
|
import static org.briarproject.bramble.util.OsUtils.isLinux;
|
||||||
|
import static org.briarproject.bramble.util.OsUtils.isMac;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assume.assumeTrue;
|
||||||
|
|
||||||
public class LinuxSecureRandomProviderTest extends BrambleTestCase {
|
public class UnixSecureRandomProviderTest extends BrambleTestCase {
|
||||||
|
|
||||||
private final File testDir = TestUtils.getTestDirectory();
|
private final File testDir = getTestDirectory();
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
testDir.mkdirs();
|
assumeTrue(isLinux() || isMac());
|
||||||
|
assertTrue(testDir.mkdirs());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetProviderWritesToRandomDeviceOnFirstCall()
|
public void testGetProviderWritesToRandomDeviceOnFirstCall()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
if (!(OsUtils.isLinux())) {
|
|
||||||
System.err.println("WARNING: Skipping test, can't run on this OS");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Redirect the provider's output to a file
|
// Redirect the provider's output to a file
|
||||||
File urandom = new File(testDir, "urandom");
|
File urandom = new File(testDir, "urandom");
|
||||||
urandom.delete();
|
if (urandom.exists()) assertTrue(urandom.delete());
|
||||||
assertTrue(urandom.createNewFile());
|
assertTrue(urandom.createNewFile());
|
||||||
assertEquals(0, urandom.length());
|
assertEquals(0, urandom.length());
|
||||||
LinuxSecureRandomProvider p = new LinuxSecureRandomProvider(urandom);
|
UnixSecureRandomProvider p = new UnixSecureRandomProvider(urandom);
|
||||||
// Getting a provider should write entropy to the file
|
// Getting a provider should write entropy to the file
|
||||||
Provider provider = p.getProvider();
|
Provider provider = p.getProvider();
|
||||||
assertNotNull(provider);
|
assertNotNull(provider);
|
||||||
assertEquals("LinuxPRNG", provider.getName());
|
assertEquals("UnixPRNG", provider.getName());
|
||||||
// There should be at least 16 bytes from the clock, 8 from the runtime
|
// There should be at least 16 bytes from the clock, 8 from the runtime
|
||||||
long length = urandom.length();
|
long length = urandom.length();
|
||||||
assertTrue(length >= 24);
|
assertTrue(length >= 24);
|
||||||
// Getting another provider should not write to the file again
|
// Getting another provider should not write to the file again
|
||||||
provider = p.getProvider();
|
provider = p.getProvider();
|
||||||
assertNotNull(provider);
|
assertNotNull(provider);
|
||||||
assertEquals("LinuxPRNG", provider.getName());
|
assertEquals("UnixPRNG", provider.getName());
|
||||||
assertEquals(length, urandom.length());
|
assertEquals(length, urandom.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void tearDown() {
|
public void tearDown() {
|
||||||
TestUtils.deleteTestDirectory(testDir);
|
deleteTestDirectory(testDir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,6 @@ import org.briarproject.bramble.api.Bytes;
|
|||||||
import org.briarproject.bramble.test.BrambleTestCase;
|
import org.briarproject.bramble.test.BrambleTestCase;
|
||||||
import org.briarproject.bramble.test.TestUtils;
|
import org.briarproject.bramble.test.TestUtils;
|
||||||
import org.briarproject.bramble.util.IoUtils;
|
import org.briarproject.bramble.util.IoUtils;
|
||||||
import org.briarproject.bramble.util.OsUtils;
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -15,31 +14,33 @@ import java.io.FileOutputStream;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory;
|
||||||
|
import static org.briarproject.bramble.test.TestUtils.getTestDirectory;
|
||||||
|
import static org.briarproject.bramble.util.OsUtils.isLinux;
|
||||||
|
import static org.briarproject.bramble.util.OsUtils.isMac;
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assume.assumeTrue;
|
||||||
|
|
||||||
|
|
||||||
public class LinuxSecureRandomSpiTest extends BrambleTestCase {
|
public class UnixSecureRandomSpiTest extends BrambleTestCase {
|
||||||
|
|
||||||
private static final File RANDOM_DEVICE = new File("/dev/urandom");
|
private static final File RANDOM_DEVICE = new File("/dev/urandom");
|
||||||
private static final int SEED_BYTES = 32;
|
private static final int SEED_BYTES = 32;
|
||||||
|
|
||||||
private final File testDir = TestUtils.getTestDirectory();
|
private final File testDir = getTestDirectory();
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
testDir.mkdirs();
|
assumeTrue(isLinux() || isMac());
|
||||||
|
assertTrue(testDir.mkdirs());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSeedsAreDistinct() {
|
public void testSeedsAreDistinct() {
|
||||||
if (!(OsUtils.isLinux())) {
|
|
||||||
System.err.println("WARNING: Skipping test, can't run on this OS");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Set<Bytes> seeds = new HashSet<>();
|
Set<Bytes> seeds = new HashSet<>();
|
||||||
LinuxSecureRandomSpi engine = new LinuxSecureRandomSpi();
|
UnixSecureRandomSpi engine = new UnixSecureRandomSpi();
|
||||||
for (int i = 0; i < 1000; i++) {
|
for (int i = 0; i < 1000; i++) {
|
||||||
byte[] seed = engine.engineGenerateSeed(SEED_BYTES);
|
byte[] seed = engine.engineGenerateSeed(SEED_BYTES);
|
||||||
assertEquals(SEED_BYTES, seed.length);
|
assertEquals(SEED_BYTES, seed.length);
|
||||||
@@ -49,19 +50,15 @@ public class LinuxSecureRandomSpiTest extends BrambleTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEngineSetSeedWritesToRandomDevice() throws Exception {
|
public void testEngineSetSeedWritesToRandomDevice() throws Exception {
|
||||||
if (!(OsUtils.isLinux())) {
|
|
||||||
System.err.println("WARNING: Skipping test, can't run on this OS");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Redirect the engine's output to a file
|
// Redirect the engine's output to a file
|
||||||
File urandom = new File(testDir, "urandom");
|
File urandom = new File(testDir, "urandom");
|
||||||
urandom.delete();
|
if (urandom.exists()) assertTrue(urandom.delete());
|
||||||
assertTrue(urandom.createNewFile());
|
assertTrue(urandom.createNewFile());
|
||||||
assertEquals(0, urandom.length());
|
assertEquals(0, urandom.length());
|
||||||
// Generate a seed
|
// Generate a seed
|
||||||
byte[] seed = TestUtils.getRandomBytes(SEED_BYTES);
|
byte[] seed = TestUtils.getRandomBytes(SEED_BYTES);
|
||||||
// Check that the engine writes the seed to the file
|
// Check that the engine writes the seed to the file
|
||||||
LinuxSecureRandomSpi engine = new LinuxSecureRandomSpi(RANDOM_DEVICE,
|
UnixSecureRandomSpi engine = new UnixSecureRandomSpi(RANDOM_DEVICE,
|
||||||
urandom);
|
urandom);
|
||||||
engine.engineSetSeed(seed);
|
engine.engineSetSeed(seed);
|
||||||
assertEquals(SEED_BYTES, urandom.length());
|
assertEquals(SEED_BYTES, urandom.length());
|
||||||
@@ -74,15 +71,11 @@ public class LinuxSecureRandomSpiTest extends BrambleTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEngineNextBytesReadsFromRandomDevice() throws Exception {
|
public void testEngineNextBytesReadsFromRandomDevice() throws Exception {
|
||||||
if (!(OsUtils.isLinux())) {
|
|
||||||
System.err.println("WARNING: Skipping test, can't run on this OS");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Generate some entropy
|
// Generate some entropy
|
||||||
byte[] entropy = TestUtils.getRandomBytes(SEED_BYTES);
|
byte[] entropy = TestUtils.getRandomBytes(SEED_BYTES);
|
||||||
// Write the entropy to a file
|
// Write the entropy to a file
|
||||||
File urandom = new File(testDir, "urandom");
|
File urandom = new File(testDir, "urandom");
|
||||||
urandom.delete();
|
if (urandom.exists()) assertTrue(urandom.delete());
|
||||||
FileOutputStream out = new FileOutputStream(urandom);
|
FileOutputStream out = new FileOutputStream(urandom);
|
||||||
out.write(entropy);
|
out.write(entropy);
|
||||||
out.flush();
|
out.flush();
|
||||||
@@ -90,7 +83,7 @@ public class LinuxSecureRandomSpiTest extends BrambleTestCase {
|
|||||||
assertTrue(urandom.exists());
|
assertTrue(urandom.exists());
|
||||||
assertEquals(SEED_BYTES, urandom.length());
|
assertEquals(SEED_BYTES, urandom.length());
|
||||||
// Check that the engine reads from the file
|
// Check that the engine reads from the file
|
||||||
LinuxSecureRandomSpi engine = new LinuxSecureRandomSpi(urandom,
|
UnixSecureRandomSpi engine = new UnixSecureRandomSpi(urandom,
|
||||||
RANDOM_DEVICE);
|
RANDOM_DEVICE);
|
||||||
byte[] b = new byte[SEED_BYTES];
|
byte[] b = new byte[SEED_BYTES];
|
||||||
engine.engineNextBytes(b);
|
engine.engineNextBytes(b);
|
||||||
@@ -99,15 +92,11 @@ public class LinuxSecureRandomSpiTest extends BrambleTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEngineGenerateSeedReadsFromRandomDevice() throws Exception {
|
public void testEngineGenerateSeedReadsFromRandomDevice() throws Exception {
|
||||||
if (!(OsUtils.isLinux())) {
|
|
||||||
System.err.println("WARNING: Skipping test, can't run on this OS");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Generate some entropy
|
// Generate some entropy
|
||||||
byte[] entropy = TestUtils.getRandomBytes(SEED_BYTES);
|
byte[] entropy = TestUtils.getRandomBytes(SEED_BYTES);
|
||||||
// Write the entropy to a file
|
// Write the entropy to a file
|
||||||
File urandom = new File(testDir, "urandom");
|
File urandom = new File(testDir, "urandom");
|
||||||
urandom.delete();
|
if (urandom.exists()) assertTrue(urandom.delete());
|
||||||
FileOutputStream out = new FileOutputStream(urandom);
|
FileOutputStream out = new FileOutputStream(urandom);
|
||||||
out.write(entropy);
|
out.write(entropy);
|
||||||
out.flush();
|
out.flush();
|
||||||
@@ -115,7 +104,7 @@ public class LinuxSecureRandomSpiTest extends BrambleTestCase {
|
|||||||
assertTrue(urandom.exists());
|
assertTrue(urandom.exists());
|
||||||
assertEquals(SEED_BYTES, urandom.length());
|
assertEquals(SEED_BYTES, urandom.length());
|
||||||
// Check that the engine reads from the file
|
// Check that the engine reads from the file
|
||||||
LinuxSecureRandomSpi engine = new LinuxSecureRandomSpi(urandom,
|
UnixSecureRandomSpi engine = new UnixSecureRandomSpi(urandom,
|
||||||
RANDOM_DEVICE);
|
RANDOM_DEVICE);
|
||||||
byte[] b = engine.engineGenerateSeed(SEED_BYTES);
|
byte[] b = engine.engineGenerateSeed(SEED_BYTES);
|
||||||
assertArrayEquals(entropy, b);
|
assertArrayEquals(entropy, b);
|
||||||
@@ -123,6 +112,6 @@ public class LinuxSecureRandomSpiTest extends BrambleTestCase {
|
|||||||
|
|
||||||
@After
|
@After
|
||||||
public void tearDown() {
|
public void tearDown() {
|
||||||
TestUtils.deleteTestDirectory(testDir);
|
deleteTestDirectory(testDir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user