mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 10:49:06 +01:00
Compare commits
86 Commits
beta-0.16.
...
gradle-lib
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa79a31911 | ||
|
|
8171dd8bc9 | ||
|
|
4b88f0d9f1 | ||
|
|
116419f505 | ||
|
|
87b2624aa8 | ||
|
|
71fe6f3148 | ||
|
|
21df6cb809 | ||
|
|
1f0c385a5c | ||
|
|
986ea05fb2 | ||
|
|
030b52261d | ||
|
|
a50e13c2e3 | ||
|
|
c8326103b4 | ||
|
|
ddea031cbf | ||
|
|
f0d8532f71 | ||
|
|
4883d157dc | ||
|
|
a1bec1e927 | ||
|
|
48918f4727 | ||
|
|
303b5bd395 | ||
|
|
37d4d79c64 | ||
|
|
05bc3f6a71 | ||
|
|
8b3960781a | ||
|
|
97733a52c8 | ||
|
|
89dcbec599 | ||
|
|
6497809fe1 | ||
|
|
f3de4f53c5 | ||
|
|
166fc2948c | ||
|
|
9f3a63d8c4 | ||
|
|
748fa77d94 | ||
|
|
4ca86ee4eb | ||
|
|
ec2f372933 | ||
|
|
4267800db2 | ||
|
|
bb8cb9bcbb | ||
|
|
d5b9e15ee1 | ||
|
|
43ee3246f6 | ||
|
|
b56724dee5 | ||
|
|
92748ac872 | ||
|
|
b89686c287 | ||
|
|
a34692630b | ||
|
|
735208562a | ||
|
|
49826fdc56 | ||
|
|
e8c54a609c | ||
|
|
ece2c51358 | ||
|
|
3ec8af4661 | ||
|
|
77a08596fe | ||
|
|
879f699b2b | ||
|
|
d7383a3361 | ||
|
|
a5b321a93b | ||
|
|
5fa6b0ca1c | ||
|
|
27328afe3c | ||
|
|
2d26af1ae2 | ||
|
|
6db8f33e8f | ||
|
|
d6a7e6d52c | ||
|
|
df99b3b666 | ||
|
|
0f1c9f4fe2 | ||
|
|
5dcd5f79dc | ||
|
|
8a81171739 | ||
|
|
1c4f20f76f | ||
|
|
f84fa588f6 | ||
|
|
e30e34f342 | ||
|
|
fc93ced067 | ||
|
|
bb7df72d31 | ||
|
|
f8425658e4 | ||
|
|
53c8cf09b6 | ||
|
|
9f29bf4949 | ||
|
|
98e2adf794 | ||
|
|
2a43e0b0ed | ||
|
|
773ae73820 | ||
|
|
009db57bc5 | ||
|
|
5e98126e77 | ||
|
|
bd7ebfd83a | ||
|
|
10f41ef157 | ||
|
|
1dd4960109 | ||
|
|
75413b6c86 | ||
|
|
b2180582a7 | ||
|
|
8211ce7ae3 | ||
|
|
e6b1597fa7 | ||
|
|
8937d3cd9c | ||
|
|
51f320d147 | ||
|
|
e402a894bb | ||
|
|
9b577f1219 | ||
|
|
220f678403 | ||
|
|
4173fc4daa | ||
|
|
c6756d2145 | ||
|
|
6731f6eeb5 | ||
|
|
6f7f8b40e3 | ||
|
|
4fe4c298d7 |
@@ -6,8 +6,18 @@ cache:
|
||||
- .gradle/caches
|
||||
|
||||
before_script:
|
||||
- set -e
|
||||
- export GRADLE_USER_HOME=$PWD/.gradle
|
||||
- echo y | /opt/android-sdk/tools/bin/sdkmanager "build-tools;23.0.3"
|
||||
# Accept the license for the Android build tools
|
||||
- echo y | /opt/android-sdk/tools/bin/sdkmanager "build-tools;26.0.2"
|
||||
# Download OpenJDK 6 so we can compile against its standard library
|
||||
- JDK_FILE=openjdk-6-jre-headless_6b38-1.13.10-1~deb7u1_amd64.deb
|
||||
- if [ ! -d openjdk ]
|
||||
- then
|
||||
- wget -q http://ftp.uk.debian.org/debian/pool/main/o/openjdk-6/$JDK_FILE
|
||||
- dpkg-deb -x $JDK_FILE openjdk
|
||||
- fi
|
||||
- export JAVA_6_HOME=$PWD/openjdk/usr/lib/jvm/java-6-openjdk-amd64
|
||||
|
||||
test:
|
||||
script:
|
||||
|
||||
@@ -6,99 +6,89 @@ apply plugin: 'witness'
|
||||
apply plugin: 'de.undercouch.download'
|
||||
|
||||
android {
|
||||
compileSdkVersion 23
|
||||
buildToolsVersion "23.0.3"
|
||||
compileSdkVersion 27
|
||||
buildToolsVersion '26.0.2'
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 22
|
||||
versionCode 1611
|
||||
versionName "0.16.11"
|
||||
targetSdkVersion 26
|
||||
versionCode 1700
|
||||
versionName "0.17.0"
|
||||
consumerProguardFiles 'proguard-rules.txt'
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_7
|
||||
targetCompatibility JavaVersion.VERSION_1_7
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(':bramble-core')
|
||||
compile fileTree(dir: 'libs', include: '*.jar')
|
||||
provided 'javax.annotation:jsr250-api:1.0'
|
||||
implementation project(path: ':bramble-core', configuration: 'default')
|
||||
implementation fileTree(dir: 'libs', include: '*.jar')
|
||||
|
||||
annotationProcessor "com.google.dagger:dagger-compiler:$daggerVersion"
|
||||
|
||||
compileOnly 'javax.annotation:jsr250-api:1.0'
|
||||
}
|
||||
|
||||
def torBinaryDir = 'src/main/res/raw'
|
||||
|
||||
task downloadTorGeoIp(type: Download) {
|
||||
src 'https://briarproject.org/build/geoip-2017-09-06.zip'
|
||||
dest "$torBinaryDir/geoip.zip"
|
||||
onlyIfNewer true
|
||||
dependencyVerification {
|
||||
verify = [
|
||||
'com.google.code.findbugs:jsr305:3.0.2:jsr305-3.0.2.jar:766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7',
|
||||
'com.google.dagger:dagger-compiler:2.0.2:dagger-compiler-2.0.2.jar:b74bc9de063dd4c6400b232231f2ef5056145b8fbecbf5382012007dd1c071b3',
|
||||
'com.google.dagger:dagger-producers:2.0-beta:dagger-producers-2.0-beta.jar:99ec15e8a0507ba569e7655bc1165ee5e5ca5aa914b3c8f7e2c2458f724edd6b',
|
||||
'com.google.dagger:dagger:2.0.2:dagger-2.0.2.jar:84c0282ed8be73a29e0475d639da030b55dee72369e58dd35ae7d4fe6243dcf9',
|
||||
'com.google.guava:guava:18.0:guava-18.0.jar:d664fbfc03d2e5ce9cab2a44fb01f1d0bf9dfebeccc1a473b1f9ea31f79f6f99',
|
||||
'com.h2database:h2:1.4.192:h2-1.4.192.jar:225b22e9857235c46c93861410b60b8c81c10dc8985f4faf188985ba5445126c',
|
||||
'com.madgag.spongycastle:core:1.58.0.0:core-1.58.0.0.jar:199617dd5698c5a9312b898c0a4cec7ce9dd8649d07f65d91629f58229d72728',
|
||||
'javax.annotation:jsr250-api:1.0:jsr250-api-1.0.jar:a1a922d0d9b6d183ed3800dfac01d1e1eb159f0e8c6f94736931c1def54a941f',
|
||||
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
|
||||
'net.i2p.crypto:eddsa:0.2.0:eddsa-0.2.0.jar:a7cb1b85c16e2f0730b9204106929a1d9aaae1df728adc7041a8b8b605692140',
|
||||
'org.bitlet:weupnp:0.1.4:weupnp-0.1.4.jar:88df7e6504929d00bdb832863761385c68ab92af945b04f0770b126270a444fb',
|
||||
'org.jacoco:org.jacoco.agent:0.7.4.201502262128:org.jacoco.agent-0.7.4.201502262128-runtime.jar:e357a0f1d573c2f702a273992b1b6cb661734f66311854efb3778a888515c5b5',
|
||||
'org.jacoco:org.jacoco.agent:0.7.4.201502262128:org.jacoco.agent-0.7.4.201502262128.jar:47b4bec6df11a1118da3953da8b9fa1e7079d6fec857faa1a3cf912e53a6fd4e',
|
||||
'org.jacoco:org.jacoco.ant:0.7.4.201502262128:org.jacoco.ant-0.7.4.201502262128.jar:013ce2a68ba57a3c59215ae0dec4df3498c078062a38c3b94c841fc14450f283',
|
||||
'org.jacoco:org.jacoco.core:0.7.4.201502262128:org.jacoco.core-0.7.4.201502262128.jar:ec4c74554312fac5116350164786f91b35c9e082fa4ea598bfa42b5db05d7abb',
|
||||
'org.jacoco:org.jacoco.report:0.7.4.201502262128:org.jacoco.report-0.7.4.201502262128.jar:7a3554c605e088e7e323b1084656243f0444fa353e2f2dee1f1a4204eb64ff09',
|
||||
'org.ow2.asm:asm-debug-all:5.0.1:asm-debug-all-5.0.1.jar:4734de5b515a454b0096db6971fb068e5f70e6f10bbee2b3bd2fdfe5d978ed57',
|
||||
]
|
||||
}
|
||||
|
||||
task downloadTorBinaryArm(type: Download) {
|
||||
src 'https://briarproject.org/build/tor-0.2.9.12-arm.zip'
|
||||
dest "$torBinaryDir/tor_arm.zip"
|
||||
onlyIfNewer true
|
||||
ext.torBinaryDir = 'src/main/res/raw'
|
||||
ext.torDownloadUrl = 'https://briarproject.org/build/'
|
||||
|
||||
def torBinaries = [
|
||||
"tor_arm" : '8ed0b347ffed1d6a4d2fd14495118eb92be83e9cc06e057e15220dc288b31688',
|
||||
"tor_arm_pie": '64403262511c29f462ca5e7c7621bfc3c944898364d1d5ad35a016bb8a034283',
|
||||
"tor_x86" : '61e014607a2079bcf1646289c67bff6372b1aded6e1d8d83d7791efda9a4d5ab',
|
||||
"tor_x86_pie": '18fbc98356697dd0895836ab46d5c9877d1c539193464f7db1e82a65adaaf288',
|
||||
"geoip" : 'fe49d3adb86d3c512373101422a017dbb86c85a570524663f09dd8ce143a24f3'
|
||||
]
|
||||
|
||||
def downloadBinary(name) {
|
||||
return tasks.create("downloadBinary${name}", Download) {
|
||||
src "${torDownloadUrl}${name}.zip"
|
||||
.replace('tor_', "tor-${torVersion}-")
|
||||
.replace('geoip', "geoip-${geoipVersion}")
|
||||
.replaceAll('_', '-')
|
||||
dest "${torBinaryDir}/${name}.zip"
|
||||
onlyIfNewer true
|
||||
}
|
||||
}
|
||||
|
||||
task downloadTorBinaryArmPie(type: Download) {
|
||||
src 'https://briarproject.org/build/tor-0.2.9.12-arm-pie.zip'
|
||||
dest "$torBinaryDir/tor_arm_pie.zip"
|
||||
onlyIfNewer true
|
||||
}
|
||||
|
||||
task downloadTorBinaryX86(type: Download) {
|
||||
src 'https://briarproject.org/build/tor-0.2.9.12-x86.zip'
|
||||
dest "$torBinaryDir/tor_x86.zip"
|
||||
onlyIfNewer true
|
||||
}
|
||||
|
||||
task downloadTorBinaryX86Pie(type: Download) {
|
||||
src 'https://briarproject.org/build/tor-0.2.9.12-x86-pie.zip'
|
||||
dest "$torBinaryDir/tor_x86_pie.zip"
|
||||
onlyIfNewer true
|
||||
}
|
||||
|
||||
task verifyTorGeoIp(type: Verify, dependsOn: 'downloadTorGeoIp') {
|
||||
src "$torBinaryDir/geoip.zip"
|
||||
algorithm 'SHA-256'
|
||||
checksum 'fe49d3adb86d3c512373101422a017dbb86c85a570524663f09dd8ce143a24f3'
|
||||
}
|
||||
|
||||
task verifyTorBinaryArm(type: Verify, dependsOn: 'downloadTorBinaryArm') {
|
||||
src "$torBinaryDir/tor_arm.zip"
|
||||
algorithm 'SHA-256'
|
||||
checksum '8ed0b347ffed1d6a4d2fd14495118eb92be83e9cc06e057e15220dc288b31688'
|
||||
}
|
||||
|
||||
task verifyTorBinaryArmPie(type: Verify, dependsOn: 'downloadTorBinaryArmPie') {
|
||||
src "$torBinaryDir/tor_arm_pie.zip"
|
||||
algorithm 'SHA-256'
|
||||
checksum '64403262511c29f462ca5e7c7621bfc3c944898364d1d5ad35a016bb8a034283'
|
||||
}
|
||||
|
||||
task verifyTorBinaryX86(type: Verify, dependsOn: 'downloadTorBinaryX86') {
|
||||
src "$torBinaryDir/tor_x86.zip"
|
||||
algorithm 'SHA-256'
|
||||
checksum '61e014607a2079bcf1646289c67bff6372b1aded6e1d8d83d7791efda9a4d5ab'
|
||||
}
|
||||
|
||||
task verifyTorBinaryX86Pie(type: Verify, dependsOn: 'downloadTorBinaryX86Pie') {
|
||||
src "$torBinaryDir/tor_x86_pie.zip"
|
||||
algorithm 'SHA-256'
|
||||
checksum '18fbc98356697dd0895836ab46d5c9877d1c539193464f7db1e82a65adaaf288'
|
||||
def verifyBinary(name, chksum) {
|
||||
return tasks.create([
|
||||
name : "verifyBinary${name}",
|
||||
type : Verify,
|
||||
dependsOn: downloadBinary(name)]) {
|
||||
src "${torBinaryDir}/${name}.zip"
|
||||
algorithm 'SHA-256'
|
||||
checksum chksum
|
||||
}
|
||||
}
|
||||
|
||||
project.afterEvaluate {
|
||||
preBuild.dependsOn {
|
||||
[
|
||||
'verifyTorGeoIp',
|
||||
'verifyTorBinaryArm',
|
||||
'verifyTorBinaryArmPie',
|
||||
'verifyTorBinaryX86',
|
||||
'verifyTorBinaryX86Pie'
|
||||
]
|
||||
torBinaries.every { key, value ->
|
||||
preBuild.dependsOn.add(verifyBinary(key, value))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
-dontwarn dagger.**
|
||||
-dontnote dagger.**
|
||||
|
||||
-keep class net.i2p.crypto.eddsa.** { *; }
|
||||
|
||||
-dontwarn sun.misc.Unsafe
|
||||
-dontnote com.google.common.**
|
||||
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.READ_LOGS"/>
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK"/>
|
||||
<!-- Since API 23, this is needed to add contacts via Bluetooth -->
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
||||
|
||||
<application
|
||||
android:allowBackup="false"
|
||||
|
||||
@@ -45,7 +45,7 @@ public class AndroidPluginModule {
|
||||
backoffFactory);
|
||||
DuplexPluginFactory lan = new AndroidLanTcpPluginFactory(ioExecutor,
|
||||
backoffFactory, appContext);
|
||||
final Collection<DuplexPluginFactory> duplex =
|
||||
Collection<DuplexPluginFactory> duplex =
|
||||
Arrays.asList(bluetooth, tor, lan);
|
||||
@NotNullByDefault
|
||||
PluginConfig pluginConfig = new PluginConfig() {
|
||||
|
||||
@@ -124,12 +124,7 @@ class DroidtoothPlugin implements DuplexPlugin, EventListener {
|
||||
// with a message queue, so submit it to the AndroidExecutor
|
||||
try {
|
||||
adapter = androidExecutor.runOnBackgroundThread(
|
||||
new Callable<BluetoothAdapter>() {
|
||||
@Override
|
||||
public BluetoothAdapter call() throws Exception {
|
||||
return BluetoothAdapter.getDefaultAdapter();
|
||||
}
|
||||
}).get();
|
||||
BluetoothAdapter::getDefaultAdapter).get();
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
LOG.warning("Interrupted while getting BluetoothAdapter");
|
||||
@@ -162,40 +157,36 @@ class DroidtoothPlugin implements DuplexPlugin, EventListener {
|
||||
}
|
||||
|
||||
private void bind() {
|
||||
ioExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!isRunning()) return;
|
||||
String address = AndroidUtils.getBluetoothAddress(appContext,
|
||||
adapter);
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Local address " + scrubMacAddress(address));
|
||||
if (!StringUtils.isNullOrEmpty(address)) {
|
||||
// Advertise the Bluetooth address to contacts
|
||||
TransportProperties p = new TransportProperties();
|
||||
p.put(PROP_ADDRESS, address);
|
||||
callback.mergeLocalProperties(p);
|
||||
}
|
||||
// Bind a server socket to accept connections from contacts
|
||||
BluetoothServerSocket ss;
|
||||
try {
|
||||
ss = adapter.listenUsingInsecureRfcommWithServiceRecord(
|
||||
"RFCOMM", getUuid());
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, e.toString(), e);
|
||||
return;
|
||||
}
|
||||
if (!isRunning()) {
|
||||
tryToClose(ss);
|
||||
return;
|
||||
}
|
||||
LOG.info("Socket bound");
|
||||
socket = ss;
|
||||
backoff.reset();
|
||||
callback.transportEnabled();
|
||||
acceptContactConnections();
|
||||
ioExecutor.execute(() -> {
|
||||
if (!isRunning()) return;
|
||||
String address = AndroidUtils.getBluetoothAddress(appContext,
|
||||
adapter);
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Local address " + scrubMacAddress(address));
|
||||
if (!StringUtils.isNullOrEmpty(address)) {
|
||||
// Advertise the Bluetooth address to contacts
|
||||
TransportProperties p = new TransportProperties();
|
||||
p.put(PROP_ADDRESS, address);
|
||||
callback.mergeLocalProperties(p);
|
||||
}
|
||||
// Bind a server socket to accept connections from contacts
|
||||
BluetoothServerSocket ss;
|
||||
try {
|
||||
ss = adapter.listenUsingInsecureRfcommWithServiceRecord(
|
||||
"RFCOMM", getUuid());
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
return;
|
||||
}
|
||||
if (!isRunning()) {
|
||||
tryToClose(ss);
|
||||
return;
|
||||
}
|
||||
LOG.info("Socket bound");
|
||||
socket = ss;
|
||||
backoff.reset();
|
||||
callback.transportEnabled();
|
||||
acceptContactConnections();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -294,21 +285,18 @@ class DroidtoothPlugin implements DuplexPlugin, EventListener {
|
||||
Map<ContactId, TransportProperties> remote =
|
||||
callback.getRemoteProperties();
|
||||
for (Entry<ContactId, TransportProperties> e : remote.entrySet()) {
|
||||
final ContactId c = e.getKey();
|
||||
ContactId c = e.getKey();
|
||||
if (connected.contains(c)) continue;
|
||||
final String address = e.getValue().get(PROP_ADDRESS);
|
||||
String address = e.getValue().get(PROP_ADDRESS);
|
||||
if (StringUtils.isNullOrEmpty(address)) continue;
|
||||
final String uuid = e.getValue().get(PROP_UUID);
|
||||
String uuid = e.getValue().get(PROP_UUID);
|
||||
if (StringUtils.isNullOrEmpty(uuid)) continue;
|
||||
ioExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!running) return;
|
||||
BluetoothSocket s = connect(address, uuid);
|
||||
if (s != null) {
|
||||
backoff.reset();
|
||||
callback.outgoingConnectionCreated(c, wrapSocket(s));
|
||||
}
|
||||
ioExecutor.execute(() -> {
|
||||
if (!running) return;
|
||||
BluetoothSocket s = connect(address, uuid);
|
||||
if (s != null) {
|
||||
backoff.reset();
|
||||
callback.outgoingConnectionCreated(c, wrapSocket(s));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -438,21 +426,11 @@ class DroidtoothPlugin implements DuplexPlugin, EventListener {
|
||||
}
|
||||
|
||||
private void enableAdapterAsync() {
|
||||
ioExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
enableAdapter();
|
||||
}
|
||||
});
|
||||
ioExecutor.execute(this::enableAdapter);
|
||||
}
|
||||
|
||||
private void disableAdapterAsync() {
|
||||
ioExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
disableAdapter();
|
||||
}
|
||||
});
|
||||
ioExecutor.execute(this::disableAdapter);
|
||||
}
|
||||
|
||||
private class BluetoothStateReceiver extends BroadcastReceiver {
|
||||
@@ -490,16 +468,13 @@ class DroidtoothPlugin implements DuplexPlugin, EventListener {
|
||||
|
||||
@Override
|
||||
public Callable<KeyAgreementConnection> listen() {
|
||||
return new Callable<KeyAgreementConnection>() {
|
||||
@Override
|
||||
public KeyAgreementConnection call() throws IOException {
|
||||
BluetoothSocket s = ss.accept();
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info(ID.getString() + ": Incoming connection");
|
||||
return new KeyAgreementConnection(
|
||||
new DroidtoothTransportConnection(
|
||||
DroidtoothPlugin.this, s), ID);
|
||||
}
|
||||
return () -> {
|
||||
BluetoothSocket s = ss.accept();
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info(ID.getString() + ": Incoming connection");
|
||||
return new KeyAgreementConnection(
|
||||
new DroidtoothTransportConnection(
|
||||
DroidtoothPlugin.this, s), ID);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -149,7 +149,8 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
cookieFile = new File(torDirectory, ".tor/control_auth_cookie");
|
||||
Object o = appContext.getSystemService(POWER_SERVICE);
|
||||
PowerManager pm = (PowerManager) o;
|
||||
wakeLock = pm.newWakeLock(PARTIAL_WAKE_LOCK, "TorPlugin");
|
||||
// This tag will prevent Huawei's powermanager from killing us.
|
||||
wakeLock = pm.newWakeLock(PARTIAL_WAKE_LOCK, "LocationManagerService");
|
||||
wakeLock.setReferenceCounted(false);
|
||||
}
|
||||
|
||||
@@ -369,57 +370,45 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
}
|
||||
|
||||
private void sendDevReports() {
|
||||
ioExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// TODO: Trigger this with a TransportEnabledEvent
|
||||
File reportDir = AndroidUtils.getReportDir(appContext);
|
||||
reporter.sendReports(reportDir);
|
||||
}
|
||||
ioExecutor.execute(() -> {
|
||||
// TODO: Trigger this with a TransportEnabledEvent
|
||||
File reportDir = AndroidUtils.getReportDir(appContext);
|
||||
reporter.sendReports(reportDir);
|
||||
});
|
||||
}
|
||||
|
||||
private void bind() {
|
||||
ioExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// If there's already a port number stored in config, reuse it
|
||||
String portString = callback.getSettings().get(PREF_TOR_PORT);
|
||||
int port;
|
||||
if (StringUtils.isNullOrEmpty(portString)) port = 0;
|
||||
else port = Integer.parseInt(portString);
|
||||
// Bind a server socket to receive connections from Tor
|
||||
ServerSocket ss = null;
|
||||
try {
|
||||
ss = new ServerSocket();
|
||||
ss.bind(new InetSocketAddress("127.0.0.1", port));
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, e.toString(), e);
|
||||
tryToClose(ss);
|
||||
return;
|
||||
}
|
||||
if (!running) {
|
||||
tryToClose(ss);
|
||||
return;
|
||||
}
|
||||
socket = ss;
|
||||
// Store the port number
|
||||
final String localPort = String.valueOf(ss.getLocalPort());
|
||||
Settings s = new Settings();
|
||||
s.put(PREF_TOR_PORT, localPort);
|
||||
callback.mergeSettings(s);
|
||||
// Create a hidden service if necessary
|
||||
ioExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
publishHiddenService(localPort);
|
||||
}
|
||||
});
|
||||
backoff.reset();
|
||||
// Accept incoming hidden service connections from Tor
|
||||
acceptContactConnections(ss);
|
||||
ioExecutor.execute(() -> {
|
||||
// If there's already a port number stored in config, reuse it
|
||||
String portString = callback.getSettings().get(PREF_TOR_PORT);
|
||||
int port;
|
||||
if (StringUtils.isNullOrEmpty(portString)) port = 0;
|
||||
else port = Integer.parseInt(portString);
|
||||
// Bind a server socket to receive connections from Tor
|
||||
ServerSocket ss = null;
|
||||
try {
|
||||
ss = new ServerSocket();
|
||||
ss.bind(new InetSocketAddress("127.0.0.1", port));
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
tryToClose(ss);
|
||||
return;
|
||||
}
|
||||
if (!running) {
|
||||
tryToClose(ss);
|
||||
return;
|
||||
}
|
||||
socket = ss;
|
||||
// Store the port number
|
||||
String localPort = String.valueOf(ss.getLocalPort());
|
||||
Settings s = new Settings();
|
||||
s.put(PREF_TOR_PORT, localPort);
|
||||
callback.mergeSettings(s);
|
||||
// Create a hidden service if necessary
|
||||
ioExecutor.execute(() -> publishHiddenService(localPort));
|
||||
backoff.reset();
|
||||
// Accept incoming hidden service connections from Tor
|
||||
acceptContactConnections(ss);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -547,17 +536,13 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
}
|
||||
}
|
||||
|
||||
private void connectAndCallBack(final ContactId c,
|
||||
final TransportProperties p) {
|
||||
ioExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!isRunning()) return;
|
||||
DuplexTransportConnection d = createConnection(p);
|
||||
if (d != null) {
|
||||
backoff.reset();
|
||||
callback.outgoingConnectionCreated(c, d);
|
||||
}
|
||||
private void connectAndCallBack(ContactId c, TransportProperties p) {
|
||||
ioExecutor.execute(() -> {
|
||||
if (!isRunning()) return;
|
||||
DuplexTransportConnection d = createConnection(p);
|
||||
if (d != null) {
|
||||
backoff.reset();
|
||||
callback.outgoingConnectionCreated(c, d);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -690,48 +675,43 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
||||
}
|
||||
|
||||
private void updateConnectionStatus() {
|
||||
ioExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!running) return;
|
||||
ioExecutor.execute(() -> {
|
||||
if (!running) return;
|
||||
|
||||
Object o = appContext.getSystemService(CONNECTIVITY_SERVICE);
|
||||
ConnectivityManager cm = (ConnectivityManager) o;
|
||||
NetworkInfo net = cm.getActiveNetworkInfo();
|
||||
boolean online = net != null && net.isConnected();
|
||||
boolean wifi = online && net.getType() == TYPE_WIFI;
|
||||
String country = locationUtils.getCurrentCountry();
|
||||
boolean blocked = TorNetworkMetadata.isTorProbablyBlocked(
|
||||
country);
|
||||
Settings s = callback.getSettings();
|
||||
int network = s.getInt(PREF_TOR_NETWORK,
|
||||
PREF_TOR_NETWORK_ALWAYS);
|
||||
Object o = appContext.getSystemService(CONNECTIVITY_SERVICE);
|
||||
ConnectivityManager cm = (ConnectivityManager) o;
|
||||
NetworkInfo net = cm.getActiveNetworkInfo();
|
||||
boolean online = net != null && net.isConnected();
|
||||
boolean wifi = online && net.getType() == TYPE_WIFI;
|
||||
String country = locationUtils.getCurrentCountry();
|
||||
boolean blocked = TorNetworkMetadata.isTorProbablyBlocked(
|
||||
country);
|
||||
Settings s = callback.getSettings();
|
||||
int network = s.getInt(PREF_TOR_NETWORK, PREF_TOR_NETWORK_ALWAYS);
|
||||
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
LOG.info("Online: " + online + ", wifi: " + wifi);
|
||||
if ("".equals(country)) LOG.info("Country code unknown");
|
||||
else LOG.info("Country code: " + country);
|
||||
}
|
||||
|
||||
try {
|
||||
if (!online) {
|
||||
LOG.info("Disabling network, device is offline");
|
||||
enableNetwork(false);
|
||||
} else if (blocked) {
|
||||
LOG.info("Disabling network, country is blocked");
|
||||
enableNetwork(false);
|
||||
} else if (network == PREF_TOR_NETWORK_NEVER
|
||||
|| (network == PREF_TOR_NETWORK_WIFI && !wifi)) {
|
||||
LOG.info("Disabling network due to data setting");
|
||||
enableNetwork(false);
|
||||
} else {
|
||||
LOG.info("Enabling network");
|
||||
enableNetwork(true);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, e.toString(), e);
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
LOG.info("Online: " + online + ", wifi: " + wifi);
|
||||
if ("".equals(country)) LOG.info("Country code unknown");
|
||||
else LOG.info("Country code: " + country);
|
||||
}
|
||||
|
||||
try {
|
||||
if (!online) {
|
||||
LOG.info("Disabling network, device is offline");
|
||||
enableNetwork(false);
|
||||
} else if (blocked) {
|
||||
LOG.info("Disabling network, country is blocked");
|
||||
enableNetwork(false);
|
||||
} else if (network == PREF_TOR_NETWORK_NEVER
|
||||
|| (network == PREF_TOR_NETWORK_WIFI && !wifi)) {
|
||||
LOG.info("Disabling network due to data setting");
|
||||
enableNetwork(false);
|
||||
} else {
|
||||
LOG.info("Enabling network");
|
||||
enableNetwork(true);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -27,14 +27,11 @@ class AndroidExecutorImpl implements AndroidExecutor {
|
||||
@Inject
|
||||
AndroidExecutorImpl(Application app) {
|
||||
uiHandler = new Handler(app.getApplicationContext().getMainLooper());
|
||||
loop = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Looper.prepare();
|
||||
backgroundHandler = new Handler();
|
||||
startLatch.countDown();
|
||||
Looper.loop();
|
||||
}
|
||||
loop = () -> {
|
||||
Looper.prepare();
|
||||
backgroundHandler = new Handler();
|
||||
startLatch.countDown();
|
||||
Looper.loop();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,30 +1,39 @@
|
||||
apply plugin: 'java'
|
||||
sourceCompatibility = 1.6
|
||||
targetCompatibility = 1.6
|
||||
apply plugin: 'java-library'
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
|
||||
apply plugin: 'witness'
|
||||
|
||||
dependencies {
|
||||
compile "com.google.dagger:dagger:2.0.2"
|
||||
compile 'com.google.dagger:dagger-compiler:2.0.2'
|
||||
compile 'com.google.code.findbugs:jsr305:3.0.2'
|
||||
implementation "com.google.dagger:dagger:$daggerVersion"
|
||||
implementation 'com.google.code.findbugs:jsr305:3.0.2'
|
||||
|
||||
testCompile 'junit:junit:4.12'
|
||||
testCompile "org.jmock:jmock:2.8.2"
|
||||
testCompile "org.jmock:jmock-junit4:2.8.2"
|
||||
testCompile "org.jmock:jmock-legacy:2.8.2"
|
||||
testCompile "org.hamcrest:hamcrest-library:1.3"
|
||||
testCompile "org.hamcrest:hamcrest-core:1.3"
|
||||
testImplementation "junit:junit:$junitVersion"
|
||||
testImplementation "org.jmock:jmock:$jmockVersion"
|
||||
testImplementation "org.jmock:jmock-junit4:$jmockVersion"
|
||||
testImplementation "org.jmock:jmock-legacy:$jmockVersion"
|
||||
testImplementation "org.hamcrest:hamcrest-library:$hamcrestVersion"
|
||||
testImplementation "org.hamcrest:hamcrest-core:$hamcrestVersion"
|
||||
}
|
||||
|
||||
dependencyVerification {
|
||||
verify = [
|
||||
'com.google.dagger:dagger:84c0282ed8be73a29e0475d639da030b55dee72369e58dd35ae7d4fe6243dcf9',
|
||||
'com.google.dagger:dagger-compiler:b74bc9de063dd4c6400b232231f2ef5056145b8fbecbf5382012007dd1c071b3',
|
||||
'com.google.code.findbugs:jsr305:766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7',
|
||||
'javax.inject:javax.inject:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
|
||||
'com.google.dagger:dagger-producers:99ec15e8a0507ba569e7655bc1165ee5e5ca5aa914b3c8f7e2c2458f724edd6b',
|
||||
'com.google.guava:guava:d664fbfc03d2e5ce9cab2a44fb01f1d0bf9dfebeccc1a473b1f9ea31f79f6f99',
|
||||
'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.dagger:dagger:2.0.2:dagger-2.0.2.jar:84c0282ed8be73a29e0475d639da030b55dee72369e58dd35ae7d4fe6243dcf9',
|
||||
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
|
||||
'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:1.9.4:ant-1.9.4.jar:649ae0730251de07b8913f49286d46bba7b92d47c5f332610aa426c4f02161d8',
|
||||
'org.beanshell:bsh:1.3.0:bsh-1.3.0.jar:9b04edc75d19db54f1b4e8b5355e9364384c6cf71eb0a1b9724c159d779879f8',
|
||||
'org.hamcrest:hamcrest-core:1.3:hamcrest-core-1.3.jar:66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9',
|
||||
'org.hamcrest:hamcrest-library:1.3:hamcrest-library-1.3.jar:711d64522f9ec410983bd310934296da134be4254a125080a0416ec178dfad1c',
|
||||
'org.jmock:jmock-junit4:2.8.2:jmock-junit4-2.8.2.jar:f7ee4df4f7bd7b7f1cafad3b99eb74d579f109d5992ff625347352edb55e674c',
|
||||
'org.jmock:jmock-legacy:2.8.2:jmock-legacy-2.8.2.jar:f2b985a5c08a9edb7f37612330c058809da3f6a6d63ce792426ebf8ff0d6d31b',
|
||||
'org.jmock:jmock-testjar:2.8.2:jmock-testjar-2.8.2.jar:8900860f72c474e027cf97fe78dcbf154a1aa7fc62b6845c5fb4e4f3c7bc8760',
|
||||
'org.jmock:jmock:2.8.2:jmock-2.8.2.jar:6c73cb4a2e6dbfb61fd99c9a768539c170ab6568e57846bd60dbf19596b65b16',
|
||||
'org.objenesis:objenesis:2.1:objenesis-2.1.jar:c74330cc6b806c804fd37e74487b4fe5d7c2750c5e15fbc6efa13bdee1bdef80',
|
||||
'org.ow2.asm:asm:5.0.4:asm-5.0.4.jar:896618ed8ae62702521a78bc7be42b7c491a08e6920a15f89a3ecdec31e9a220',
|
||||
]
|
||||
}
|
||||
|
||||
@@ -39,3 +48,8 @@ task jarTest(type: Jar, dependsOn: testClasses) {
|
||||
artifacts {
|
||||
testOutput jarTest
|
||||
}
|
||||
|
||||
// If a Java 6 JRE is available, check we're not using any Java 7 or 8 APIs
|
||||
tasks.withType(JavaCompile) {
|
||||
useJava6StandardLibrary(it)
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ public class BdfMessageContext {
|
||||
}
|
||||
|
||||
public BdfMessageContext(BdfDictionary dictionary) {
|
||||
this(dictionary, Collections.<MessageId>emptyList());
|
||||
this(dictionary, Collections.emptyList());
|
||||
}
|
||||
|
||||
public BdfDictionary getDictionary() {
|
||||
|
||||
@@ -20,6 +20,10 @@ public interface CryptoComponent {
|
||||
|
||||
KeyParser getSignatureKeyParser();
|
||||
|
||||
KeyPair generateEdKeyPair();
|
||||
|
||||
KeyParser getEdKeyParser();
|
||||
|
||||
KeyParser getMessageKeyParser();
|
||||
|
||||
/**
|
||||
@@ -61,7 +65,6 @@ public interface CryptoComponent {
|
||||
* @param ourKeyPair our ephemeral keypair
|
||||
* @param alice true if ourKeyPair belongs to Alice
|
||||
* @return the shared secret
|
||||
* @throws GeneralSecurityException
|
||||
*/
|
||||
SecretKey deriveSharedSecret(byte[] theirPublicKey, KeyPair ourKeyPair,
|
||||
boolean alice) throws GeneralSecurityException;
|
||||
@@ -106,7 +109,6 @@ public interface CryptoComponent {
|
||||
* @param ourKeyPair our ephemeral keypair
|
||||
* @param alice true if ourKeyPair belongs to Alice
|
||||
* @return the shared secret
|
||||
* @throws GeneralSecurityException
|
||||
*/
|
||||
SecretKey deriveMasterSecret(byte[] theirPublicKey, KeyPair ourKeyPair,
|
||||
boolean alice) throws GeneralSecurityException;
|
||||
@@ -130,7 +132,7 @@ public interface CryptoComponent {
|
||||
long streamNumber);
|
||||
|
||||
/**
|
||||
* Signs the given byte[] with the given PrivateKey.
|
||||
* Signs the given byte[] with the given ECDSA private key.
|
||||
*
|
||||
* @param label A label specific to this signature
|
||||
* to ensure that the signature cannot be repurposed
|
||||
@@ -139,8 +141,17 @@ public interface CryptoComponent {
|
||||
throws GeneralSecurityException;
|
||||
|
||||
/**
|
||||
* Verifies that the given signature is valid for the signedData
|
||||
* and the given publicKey.
|
||||
* Signs the given byte[] with the given Ed25519 private key.
|
||||
*
|
||||
* @param label A label specific to this signature
|
||||
* to ensure that the signature cannot be repurposed
|
||||
*/
|
||||
byte[] signEd(String label, byte[] toSign, byte[] privateKey)
|
||||
throws GeneralSecurityException;
|
||||
|
||||
/**
|
||||
* Verifies that the given signature is valid for the signed data
|
||||
* and the given ECDSA public key.
|
||||
*
|
||||
* @param label A label that was specific to this signature
|
||||
* to ensure that the signature cannot be repurposed
|
||||
@@ -149,6 +160,17 @@ public interface CryptoComponent {
|
||||
boolean verify(String label, byte[] signedData, byte[] publicKey,
|
||||
byte[] signature) throws GeneralSecurityException;
|
||||
|
||||
/**
|
||||
* Verifies that the given signature is valid for the signed data
|
||||
* and the given Ed25519 public key.
|
||||
*
|
||||
* @param label A label that was specific to this signature
|
||||
* to ensure that the signature cannot be repurposed
|
||||
* @return true if the signature was valid, false otherwise.
|
||||
*/
|
||||
boolean verifyEd(String label, byte[] signedData, byte[] publicKey,
|
||||
byte[] signature) throws GeneralSecurityException;
|
||||
|
||||
/**
|
||||
* Returns the hash of the given inputs. The inputs are unambiguously
|
||||
* combined by prefixing each input with its length.
|
||||
|
||||
@@ -4,11 +4,14 @@ import org.briarproject.bramble.api.Bytes;
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentSkipListMap;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.NotThreadSafe;
|
||||
|
||||
public class BdfDictionary extends ConcurrentSkipListMap<String, Object> {
|
||||
@NotThreadSafe
|
||||
public class BdfDictionary extends TreeMap<String, Object> {
|
||||
|
||||
public static final Object NULL_VALUE = new Object();
|
||||
|
||||
|
||||
@@ -3,15 +3,17 @@ package org.briarproject.bramble.api.data;
|
||||
import org.briarproject.bramble.api.Bytes;
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.NotThreadSafe;
|
||||
|
||||
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
|
||||
|
||||
public class BdfList extends Vector<Object> {
|
||||
@NotThreadSafe
|
||||
public class BdfList extends ArrayList<Object> {
|
||||
|
||||
/**
|
||||
* Factory method for constructing lists inline.
|
||||
|
||||
@@ -122,8 +122,9 @@ public interface DatabaseComponent {
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Deletes the message with the given ID. The message ID and any other
|
||||
* associated data are not deleted.
|
||||
* Deletes the message with the given ID. Unlike
|
||||
* {@link #removeMessage(Transaction, MessageId)}, the message ID and any
|
||||
* other associated data are not deleted.
|
||||
*/
|
||||
void deleteMessage(Transaction txn, MessageId m) throws DbException;
|
||||
|
||||
@@ -452,6 +453,11 @@ public interface DatabaseComponent {
|
||||
*/
|
||||
void removeLocalAuthor(Transaction txn, AuthorId a) throws DbException;
|
||||
|
||||
/**
|
||||
* Removes a message (and all associated state) from the database.
|
||||
*/
|
||||
void removeMessage(Transaction txn, MessageId m) throws DbException;
|
||||
|
||||
/**
|
||||
* Removes a transport (and all associated state) from the database.
|
||||
*/
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package org.briarproject.bramble.api.db;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import javax.annotation.concurrent.ThreadSafe;
|
||||
import javax.annotation.concurrent.NotThreadSafe;
|
||||
|
||||
@ThreadSafe
|
||||
public class Metadata extends Hashtable<String, byte[]> {
|
||||
@NotThreadSafe
|
||||
public class Metadata extends TreeMap<String, byte[]> {
|
||||
|
||||
/**
|
||||
* Special value to indicate that a key is being removed.
|
||||
|
||||
@@ -45,7 +45,7 @@ public class Transaction {
|
||||
* committed.
|
||||
*/
|
||||
public void attach(Event e) {
|
||||
if (events == null) events = new ArrayList<Event>();
|
||||
if (events == null) events = new ArrayList<>();
|
||||
events.add(e);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ public interface TransportPropertyManager {
|
||||
/**
|
||||
* Returns the local transport properties for all transports.
|
||||
* <br/>
|
||||
* Read-Only
|
||||
* TODO: Transaction can be read-only when code is simplified
|
||||
*/
|
||||
Map<TransportId, TransportProperties> getLocalProperties(Transaction txn)
|
||||
throws DbException;
|
||||
|
||||
@@ -36,4 +36,8 @@ public class ClientId implements Comparable<ClientId> {
|
||||
return id.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ public class MessageContext {
|
||||
}
|
||||
|
||||
public MessageContext(Metadata metadata) {
|
||||
this(metadata, Collections.<MessageId>emptyList());
|
||||
this(metadata, Collections.emptyList());
|
||||
}
|
||||
|
||||
public Metadata getMetadata() {
|
||||
|
||||
@@ -3,8 +3,7 @@ package org.briarproject.bramble.test;
|
||||
import org.jmock.Mockery;
|
||||
import org.junit.After;
|
||||
|
||||
public abstract class BrambleMockTestCase extends
|
||||
BrambleTestCase {
|
||||
public abstract class BrambleMockTestCase extends BrambleTestCase {
|
||||
|
||||
protected final Mockery context = new Mockery();
|
||||
|
||||
|
||||
@@ -8,12 +8,9 @@ public abstract class BrambleTestCase {
|
||||
|
||||
public BrambleTestCase() {
|
||||
// Ensure exceptions thrown on worker threads cause tests to fail
|
||||
UncaughtExceptionHandler fail = new UncaughtExceptionHandler() {
|
||||
@Override
|
||||
public void uncaughtException(Thread thread, Throwable throwable) {
|
||||
throwable.printStackTrace();
|
||||
fail();
|
||||
}
|
||||
UncaughtExceptionHandler fail = (thread, throwable) -> {
|
||||
throwable.printStackTrace();
|
||||
fail();
|
||||
};
|
||||
Thread.setDefaultUncaughtExceptionHandler(fail);
|
||||
}
|
||||
|
||||
@@ -1,28 +1,56 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'net.ltgt.apt' version '0.9'
|
||||
id 'idea'
|
||||
}
|
||||
|
||||
sourceCompatibility = 1.6
|
||||
targetCompatibility = 1.6
|
||||
apply plugin: 'java-library'
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
|
||||
apply plugin: 'net.ltgt.apt'
|
||||
apply plugin: 'idea'
|
||||
apply plugin: 'witness'
|
||||
|
||||
dependencies {
|
||||
compile project(':bramble-api')
|
||||
compile 'com.madgag.spongycastle:core:1.58.0.0'
|
||||
compile 'com.h2database:h2:1.4.192' // This is the last version that supports Java 1.6
|
||||
compile 'org.bitlet:weupnp:0.1.4'
|
||||
implementation project(path: ':bramble-api', configuration: 'default')
|
||||
implementation 'com.madgag.spongycastle:core:1.58.0.0'
|
||||
implementation 'com.h2database:h2:1.4.192' // This is the last version that supports Java 1.6
|
||||
implementation 'org.bitlet:weupnp:0.1.4'
|
||||
implementation 'net.i2p.crypto:eddsa:0.2.0'
|
||||
|
||||
testCompile project(path: ':bramble-api', configuration: 'testOutput')
|
||||
apt "com.google.dagger:dagger-compiler:$daggerVersion"
|
||||
|
||||
testImplementation project(path: ':bramble-api', configuration: 'testOutput')
|
||||
testImplementation "junit:junit:$junitVersion"
|
||||
testImplementation "org.jmock:jmock:$jmockVersion"
|
||||
testImplementation "org.jmock:jmock-junit4:$jmockVersion"
|
||||
testImplementation "org.jmock:jmock-legacy:$jmockVersion"
|
||||
testImplementation "org.hamcrest:hamcrest-library:$hamcrestVersion"
|
||||
testImplementation "org.hamcrest:hamcrest-core:$hamcrestVersion"
|
||||
|
||||
testApt "com.google.dagger:dagger-compiler:$daggerVersion"
|
||||
}
|
||||
|
||||
dependencyVerification {
|
||||
verify = [
|
||||
'com.madgag.spongycastle:core:199617dd5698c5a9312b898c0a4cec7ce9dd8649d07f65d91629f58229d72728',
|
||||
'com.h2database:h2:225b22e9857235c46c93861410b60b8c81c10dc8985f4faf188985ba5445126c',
|
||||
'org.bitlet:weupnp:88df7e6504929d00bdb832863761385c68ab92af945b04f0770b126270a444fb',
|
||||
'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.dagger:dagger-compiler:2.0.2:dagger-compiler-2.0.2.jar:b74bc9de063dd4c6400b232231f2ef5056145b8fbecbf5382012007dd1c071b3',
|
||||
'com.google.dagger:dagger-producers:2.0-beta:dagger-producers-2.0-beta.jar:99ec15e8a0507ba569e7655bc1165ee5e5ca5aa914b3c8f7e2c2458f724edd6b',
|
||||
'com.google.dagger:dagger:2.0.2:dagger-2.0.2.jar:84c0282ed8be73a29e0475d639da030b55dee72369e58dd35ae7d4fe6243dcf9',
|
||||
'com.google.guava:guava:18.0:guava-18.0.jar:d664fbfc03d2e5ce9cab2a44fb01f1d0bf9dfebeccc1a473b1f9ea31f79f6f99',
|
||||
'com.h2database:h2:1.4.192:h2-1.4.192.jar:225b22e9857235c46c93861410b60b8c81c10dc8985f4faf188985ba5445126c',
|
||||
'com.madgag.spongycastle:core:1.58.0.0:core-1.58.0.0.jar:199617dd5698c5a9312b898c0a4cec7ce9dd8649d07f65d91629f58229d72728',
|
||||
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
|
||||
'junit:junit:4.12:junit-4.12.jar:59721f0805e223d84b90677887d9ff567dc534d7c502ca903c0c2b17f05c116a',
|
||||
'net.i2p.crypto:eddsa:0.2.0:eddsa-0.2.0.jar:a7cb1b85c16e2f0730b9204106929a1d9aaae1df728adc7041a8b8b605692140',
|
||||
'org.apache.ant:ant-launcher:1.9.4:ant-launcher-1.9.4.jar:7bccea20b41801ca17bcbc909a78c835d0f443f12d639c77bd6ae3d05861608d',
|
||||
'org.apache.ant:ant:1.9.4:ant-1.9.4.jar:649ae0730251de07b8913f49286d46bba7b92d47c5f332610aa426c4f02161d8',
|
||||
'org.beanshell:bsh:1.3.0:bsh-1.3.0.jar:9b04edc75d19db54f1b4e8b5355e9364384c6cf71eb0a1b9724c159d779879f8',
|
||||
'org.bitlet:weupnp:0.1.4:weupnp-0.1.4.jar:88df7e6504929d00bdb832863761385c68ab92af945b04f0770b126270a444fb',
|
||||
'org.hamcrest:hamcrest-core:1.3:hamcrest-core-1.3.jar:66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9',
|
||||
'org.hamcrest:hamcrest-library:1.3:hamcrest-library-1.3.jar:711d64522f9ec410983bd310934296da134be4254a125080a0416ec178dfad1c',
|
||||
'org.jmock:jmock-junit4:2.8.2:jmock-junit4-2.8.2.jar:f7ee4df4f7bd7b7f1cafad3b99eb74d579f109d5992ff625347352edb55e674c',
|
||||
'org.jmock:jmock-legacy:2.8.2:jmock-legacy-2.8.2.jar:f2b985a5c08a9edb7f37612330c058809da3f6a6d63ce792426ebf8ff0d6d31b',
|
||||
'org.jmock:jmock-testjar:2.8.2:jmock-testjar-2.8.2.jar:8900860f72c474e027cf97fe78dcbf154a1aa7fc62b6845c5fb4e4f3c7bc8760',
|
||||
'org.jmock:jmock:2.8.2:jmock-2.8.2.jar:6c73cb4a2e6dbfb61fd99c9a768539c170ab6568e57846bd60dbf19596b65b16',
|
||||
'org.objenesis:objenesis:2.1:objenesis-2.1.jar:c74330cc6b806c804fd37e74487b4fe5d7c2750c5e15fbc6efa13bdee1bdef80',
|
||||
'org.ow2.asm:asm:5.0.4:asm-5.0.4.jar:896618ed8ae62702521a78bc7be42b7c491a08e6920a15f89a3ecdec31e9a220',
|
||||
]
|
||||
}
|
||||
|
||||
@@ -37,3 +65,8 @@ task jarTest(type: Jar, dependsOn: testClasses) {
|
||||
artifacts {
|
||||
testOutput jarTest
|
||||
}
|
||||
|
||||
// If a Java 6 JRE is available, check we're not using any Java 7 or 8 APIs
|
||||
tasks.withType(JavaCompile) {
|
||||
useJava6StandardLibrary(it)
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ public class PoliteExecutor implements Executor {
|
||||
|
||||
private final Object lock = new Object();
|
||||
@GuardedBy("lock")
|
||||
private final Queue<Runnable> queue = new LinkedList<Runnable>();
|
||||
private final Queue<Runnable> queue = new LinkedList<>();
|
||||
private final Executor delegate;
|
||||
private final int maxConcurrentTasks;
|
||||
private final Logger log;
|
||||
@@ -48,20 +48,17 @@ public class PoliteExecutor implements Executor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(final Runnable r) {
|
||||
final long submitted = System.currentTimeMillis();
|
||||
Runnable wrapped = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (log.isLoggable(LOG_LEVEL)) {
|
||||
long queued = System.currentTimeMillis() - submitted;
|
||||
log.log(LOG_LEVEL, "Queue time " + queued + " ms");
|
||||
}
|
||||
try {
|
||||
r.run();
|
||||
} finally {
|
||||
scheduleNext();
|
||||
}
|
||||
public void execute(Runnable r) {
|
||||
long submitted = System.currentTimeMillis();
|
||||
Runnable wrapped = () -> {
|
||||
if (log.isLoggable(LOG_LEVEL)) {
|
||||
long queued = System.currentTimeMillis() - submitted;
|
||||
log.log(LOG_LEVEL, "Queue time " + queued + " ms");
|
||||
}
|
||||
try {
|
||||
r.run();
|
||||
} finally {
|
||||
scheduleNext();
|
||||
}
|
||||
};
|
||||
synchronized (lock) {
|
||||
|
||||
@@ -28,19 +28,16 @@ public class TimeLoggingExecutor extends ThreadPoolExecutor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(final Runnable r) {
|
||||
public void execute(Runnable r) {
|
||||
if (log.isLoggable(LOG_LEVEL)) {
|
||||
final long submitted = System.currentTimeMillis();
|
||||
super.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
long started = System.currentTimeMillis();
|
||||
long queued = started - submitted;
|
||||
log.log(LOG_LEVEL, "Queue time " + queued + " ms");
|
||||
r.run();
|
||||
long executing = System.currentTimeMillis() - started;
|
||||
log.log(LOG_LEVEL, "Execution time " + executing + " ms");
|
||||
}
|
||||
long submitted = System.currentTimeMillis();
|
||||
super.execute(() -> {
|
||||
long started = System.currentTimeMillis();
|
||||
long queued = started - submitted;
|
||||
log.log(LOG_LEVEL, "Queue time " + queued + " ms");
|
||||
r.run();
|
||||
long executing = System.currentTimeMillis() - started;
|
||||
log.log(LOG_LEVEL, "Execution time " + executing + " ms");
|
||||
});
|
||||
} else {
|
||||
super.execute(r);
|
||||
|
||||
@@ -201,8 +201,7 @@ class ClientHelperImpl implements ClientHelper {
|
||||
public Map<MessageId, BdfDictionary> getMessageMetadataAsDictionary(
|
||||
Transaction txn, GroupId g) throws DbException, FormatException {
|
||||
Map<MessageId, Metadata> raw = db.getMessageMetadata(txn, g);
|
||||
Map<MessageId, BdfDictionary> parsed =
|
||||
new HashMap<MessageId, BdfDictionary>(raw.size());
|
||||
Map<MessageId, BdfDictionary> parsed = new HashMap<>(raw.size());
|
||||
for (Entry<MessageId, Metadata> e : raw.entrySet())
|
||||
parsed.put(e.getKey(), metadataParser.parse(e.getValue()));
|
||||
return parsed;
|
||||
@@ -229,8 +228,7 @@ class ClientHelperImpl implements ClientHelper {
|
||||
FormatException {
|
||||
Metadata metadata = metadataEncoder.encode(query);
|
||||
Map<MessageId, Metadata> raw = db.getMessageMetadata(txn, g, metadata);
|
||||
Map<MessageId, BdfDictionary> parsed =
|
||||
new HashMap<MessageId, BdfDictionary>(raw.size());
|
||||
Map<MessageId, BdfDictionary> parsed = new HashMap<>(raw.size());
|
||||
for (Entry<MessageId, Metadata> e : raw.entrySet())
|
||||
parsed.put(e.getKey(), metadataParser.parse(e.getValue()));
|
||||
return parsed;
|
||||
|
||||
@@ -184,12 +184,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
|
||||
// Close the outgoing stream and expect EOF on the incoming stream
|
||||
w.close();
|
||||
if (!r.eof()) LOG.warning("Unexpected data at end of connection");
|
||||
} catch (GeneralSecurityException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
listener.contactExchangeFailed();
|
||||
tryToClose(conn, true);
|
||||
return;
|
||||
} catch (IOException e) {
|
||||
} catch (GeneralSecurityException | IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
listener.contactExchangeFailed();
|
||||
tryToClose(conn, true);
|
||||
@@ -276,8 +271,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
|
||||
|
||||
private Map<TransportId, TransportProperties> receiveTransportProperties(
|
||||
BdfReader r) throws IOException {
|
||||
Map<TransportId, TransportProperties> remote =
|
||||
new HashMap<TransportId, TransportProperties>();
|
||||
Map<TransportId, TransportProperties> remote = new HashMap<>();
|
||||
r.readListStart();
|
||||
while (!r.hasListEnd()) {
|
||||
r.readListStart();
|
||||
|
||||
@@ -34,8 +34,8 @@ class ContactManagerImpl implements ContactManager {
|
||||
ContactManagerImpl(DatabaseComponent db, KeyManager keyManager) {
|
||||
this.db = db;
|
||||
this.keyManager = keyManager;
|
||||
addHooks = new CopyOnWriteArrayList<AddContactHook>();
|
||||
removeHooks = new CopyOnWriteArrayList<RemoveContactHook>();
|
||||
addHooks = new CopyOnWriteArrayList<>();
|
||||
removeHooks = new CopyOnWriteArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -125,7 +125,7 @@ class ContactManagerImpl implements ContactManager {
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
List<Contact> active = new ArrayList<Contact>(contacts.size());
|
||||
List<Contact> active = new ArrayList<>(contacts.size());
|
||||
for (Contact c : contacts) if (c.isActive()) active.add(c);
|
||||
return active;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package org.briarproject.bramble.crypto;
|
||||
|
||||
import net.i2p.crypto.eddsa.EdDSAPrivateKey;
|
||||
import net.i2p.crypto.eddsa.EdDSAPublicKey;
|
||||
import net.i2p.crypto.eddsa.KeyPairGenerator;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
import org.briarproject.bramble.api.crypto.KeyPair;
|
||||
import org.briarproject.bramble.api.crypto.KeyParser;
|
||||
@@ -56,6 +60,7 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
|
||||
private static final int AGREEMENT_KEY_PAIR_BITS = 256;
|
||||
private static final int SIGNATURE_KEY_PAIR_BITS = 256;
|
||||
private static final int ED_KEY_PAIR_BITS = 256;
|
||||
private static final int STORAGE_IV_BYTES = 24; // 196 bits
|
||||
private static final int PBKDF_SALT_BYTES = 32; // 256 bits
|
||||
private static final int PBKDF_TARGET_MILLIS = 500;
|
||||
@@ -99,6 +104,8 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
private final ECKeyPairGenerator signatureKeyPairGenerator;
|
||||
private final KeyParser agreementKeyParser, signatureKeyParser;
|
||||
private final MessageEncrypter messageEncrypter;
|
||||
private final KeyPairGenerator edKeyPairGenerator;
|
||||
private final KeyParser edKeyParser;
|
||||
|
||||
@Inject
|
||||
CryptoComponentImpl(SecureRandomProvider secureRandomProvider) {
|
||||
@@ -132,6 +139,9 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
signatureKeyParser = new Sec1KeyParser(PARAMETERS,
|
||||
SIGNATURE_KEY_PAIR_BITS);
|
||||
messageEncrypter = new MessageEncrypter(secureRandom);
|
||||
edKeyPairGenerator = new KeyPairGenerator();
|
||||
edKeyPairGenerator.initialize(ED_KEY_PAIR_BITS, secureRandom);
|
||||
edKeyParser = new EdKeyParser();
|
||||
}
|
||||
|
||||
// Based on https://android-developers.googleblog.com/2013/08/some-securerandom-thoughts.html
|
||||
@@ -190,6 +200,21 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
return secret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyPair generateEdKeyPair() {
|
||||
java.security.KeyPair keyPair = edKeyPairGenerator.generateKeyPair();
|
||||
EdDSAPublicKey edPublicKey = (EdDSAPublicKey) keyPair.getPublic();
|
||||
PublicKey publicKey = new EdPublicKey(edPublicKey.getAbyte());
|
||||
EdDSAPrivateKey edPrivateKey = (EdDSAPrivateKey) keyPair.getPrivate();
|
||||
PrivateKey privateKey = new EdPrivateKey(edPrivateKey.getSeed());
|
||||
return new KeyPair(publicKey, privateKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyParser getEdKeyParser() {
|
||||
return edKeyParser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyPair generateAgreementKeyPair() {
|
||||
AsymmetricCipherKeyPair keyPair =
|
||||
@@ -416,19 +441,41 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
@Override
|
||||
public byte[] sign(String label, byte[] toSign, byte[] privateKey)
|
||||
throws GeneralSecurityException {
|
||||
Signature signature = new SignatureImpl(secureRandom);
|
||||
KeyParser keyParser = getSignatureKeyParser();
|
||||
return sign(new SignatureImpl(secureRandom), signatureKeyParser, label,
|
||||
toSign, privateKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] signEd(String label, byte[] toSign, byte[] privateKey)
|
||||
throws GeneralSecurityException {
|
||||
return sign(new EdSignature(), edKeyParser, label, toSign, privateKey);
|
||||
}
|
||||
|
||||
private byte[] sign(Signature sig, KeyParser keyParser, String label,
|
||||
byte[] toSign, byte[] privateKey) throws GeneralSecurityException {
|
||||
PrivateKey key = keyParser.parsePrivateKey(privateKey);
|
||||
signature.initSign(key);
|
||||
updateSignature(signature, label, toSign);
|
||||
return signature.sign();
|
||||
sig.initSign(key);
|
||||
updateSignature(sig, label, toSign);
|
||||
return sig.sign();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verify(String label, byte[] signedData, byte[] publicKey,
|
||||
byte[] signature) throws GeneralSecurityException {
|
||||
Signature sig = new SignatureImpl(secureRandom);
|
||||
KeyParser keyParser = getSignatureKeyParser();
|
||||
return verify(new SignatureImpl(secureRandom), signatureKeyParser,
|
||||
label, signedData, publicKey, signature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verifyEd(String label, byte[] signedData, byte[] publicKey,
|
||||
byte[] signature) throws GeneralSecurityException {
|
||||
return verify(new EdSignature(), edKeyParser, label, signedData,
|
||||
publicKey, signature);
|
||||
}
|
||||
|
||||
private boolean verify(Signature sig, KeyParser keyParser, String label,
|
||||
byte[] signedData, byte[] publicKey, byte[] signature)
|
||||
throws GeneralSecurityException {
|
||||
PublicKey key = keyParser.parsePublicKey(publicKey);
|
||||
sig.initVerify(key);
|
||||
updateSignature(sig, label, signedData);
|
||||
@@ -436,7 +483,7 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
}
|
||||
|
||||
private void updateSignature(Signature signature, String label,
|
||||
byte[] toSign) {
|
||||
byte[] toSign) throws GeneralSecurityException {
|
||||
byte[] labelBytes = StringUtils.toUtf8(label);
|
||||
byte[] length = new byte[INT_32_BYTES];
|
||||
ByteUtils.writeUint32(labelBytes.length, length, 0);
|
||||
@@ -602,8 +649,8 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
|
||||
// Package access for testing
|
||||
int chooseIterationCount(int targetMillis) {
|
||||
List<Long> quickSamples = new ArrayList<Long>(PBKDF_SAMPLES);
|
||||
List<Long> slowSamples = new ArrayList<Long>(PBKDF_SAMPLES);
|
||||
List<Long> quickSamples = new ArrayList<>(PBKDF_SAMPLES);
|
||||
List<Long> slowSamples = new ArrayList<>(PBKDF_SAMPLES);
|
||||
long iterationNanos = 0, initNanos = 0;
|
||||
while (iterationNanos <= 0 || initNanos <= 0) {
|
||||
// Sample the running time with one iteration and two iterations
|
||||
|
||||
@@ -48,7 +48,7 @@ public class CryptoModule {
|
||||
|
||||
public CryptoModule() {
|
||||
// Use an unbounded queue
|
||||
BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>();
|
||||
BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();
|
||||
// Discard tasks that are submitted during shutdown
|
||||
RejectedExecutionHandler policy =
|
||||
new ThreadPoolExecutor.DiscardPolicy();
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package org.briarproject.bramble.crypto;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.KeyParser;
|
||||
import org.briarproject.bramble.api.crypto.PrivateKey;
|
||||
import org.briarproject.bramble.api.crypto.PublicKey;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
@NotNullByDefault
|
||||
class EdKeyParser implements KeyParser {
|
||||
|
||||
@Override
|
||||
public PublicKey parsePublicKey(byte[] encodedKey)
|
||||
throws GeneralSecurityException {
|
||||
if (encodedKey.length != 32) throw new GeneralSecurityException();
|
||||
return new EdPublicKey(encodedKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrivateKey parsePrivateKey(byte[] encodedKey)
|
||||
throws GeneralSecurityException {
|
||||
if (encodedKey.length != 32) throw new GeneralSecurityException();
|
||||
return new EdPrivateKey(encodedKey);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.briarproject.bramble.crypto;
|
||||
|
||||
import org.briarproject.bramble.api.Bytes;
|
||||
import org.briarproject.bramble.api.crypto.PrivateKey;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
@NotNullByDefault
|
||||
class EdPrivateKey extends Bytes implements PrivateKey {
|
||||
|
||||
EdPrivateKey(byte[] bytes) {
|
||||
super(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getEncoded() {
|
||||
return getBytes();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.briarproject.bramble.crypto;
|
||||
|
||||
import org.briarproject.bramble.api.Bytes;
|
||||
import org.briarproject.bramble.api.crypto.PublicKey;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
@NotNullByDefault
|
||||
class EdPublicKey extends Bytes implements PublicKey {
|
||||
|
||||
EdPublicKey(byte[] bytes) {
|
||||
super(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getEncoded() {
|
||||
return getBytes();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package org.briarproject.bramble.crypto;
|
||||
|
||||
import net.i2p.crypto.eddsa.EdDSAPrivateKey;
|
||||
import net.i2p.crypto.eddsa.EdDSAPublicKey;
|
||||
import net.i2p.crypto.eddsa.EdDSASecurityProvider;
|
||||
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveSpec;
|
||||
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable;
|
||||
import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec;
|
||||
import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.PrivateKey;
|
||||
import org.briarproject.bramble.api.crypto.PublicKey;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.Provider;
|
||||
|
||||
import static net.i2p.crypto.eddsa.EdDSAEngine.SIGNATURE_ALGORITHM;
|
||||
|
||||
@NotNullByDefault
|
||||
class EdSignature implements Signature {
|
||||
|
||||
private static final Provider PROVIDER = new EdDSASecurityProvider();
|
||||
|
||||
private static final EdDSANamedCurveSpec CURVE_SPEC =
|
||||
EdDSANamedCurveTable.getByName("Ed25519");
|
||||
|
||||
private final java.security.Signature signature;
|
||||
|
||||
EdSignature() {
|
||||
try {
|
||||
signature = java.security.Signature
|
||||
.getInstance(SIGNATURE_ALGORITHM, PROVIDER);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initSign(PrivateKey k) throws GeneralSecurityException {
|
||||
if (!(k instanceof EdPrivateKey))
|
||||
throw new IllegalArgumentException();
|
||||
EdDSAPrivateKey privateKey = new EdDSAPrivateKey(
|
||||
new EdDSAPrivateKeySpec(k.getEncoded(), CURVE_SPEC));
|
||||
signature.initSign(privateKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initVerify(PublicKey k) throws GeneralSecurityException {
|
||||
if (!(k instanceof EdPublicKey))
|
||||
throw new IllegalArgumentException();
|
||||
EdDSAPublicKey publicKey = new EdDSAPublicKey(
|
||||
new EdDSAPublicKeySpec(k.getEncoded(), CURVE_SPEC));
|
||||
signature.initVerify(publicKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(byte b) throws GeneralSecurityException {
|
||||
signature.update(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(byte[] b) throws GeneralSecurityException {
|
||||
signature.update(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(byte[] b, int off, int len)
|
||||
throws GeneralSecurityException {
|
||||
signature.update(b, off, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] sign() throws GeneralSecurityException {
|
||||
return signature.sign();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verify(byte[] sig) throws GeneralSecurityException {
|
||||
return signature.verify(sig);
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@ class PasswordStrengthEstimatorImpl implements PasswordStrengthEstimator {
|
||||
|
||||
@Override
|
||||
public float estimateStrength(String password) {
|
||||
HashSet<Character> unique = new HashSet<Character>();
|
||||
HashSet<Character> unique = new HashSet<>();
|
||||
int length = password.length();
|
||||
for (int i = 0; i < length; i++) unique.add(password.charAt(i));
|
||||
return Math.min(1, (float) unique.size() / STRONG_UNIQUE_CHARS);
|
||||
|
||||
@@ -22,25 +22,25 @@ interface Signature {
|
||||
/**
|
||||
* @see {@link java.security.Signature#update(byte)}
|
||||
*/
|
||||
void update(byte b);
|
||||
void update(byte b) throws GeneralSecurityException;
|
||||
|
||||
/**
|
||||
* @see {@link java.security.Signature#update(byte[])}
|
||||
*/
|
||||
void update(byte[] b);
|
||||
void update(byte[] b) throws GeneralSecurityException;
|
||||
|
||||
/**
|
||||
* @see {@link java.security.Signature#update(byte[], int, int)}
|
||||
*/
|
||||
void update(byte[] b, int off, int len);
|
||||
void update(byte[] b, int off, int len) throws GeneralSecurityException;
|
||||
|
||||
/**
|
||||
* @see {@link java.security.Signature#sign()}
|
||||
*/
|
||||
byte[] sign();
|
||||
byte[] sign() throws GeneralSecurityException;
|
||||
|
||||
/**
|
||||
* @see {@link java.security.Signature#verify(byte[])}
|
||||
*/
|
||||
boolean verify(byte[] signature);
|
||||
boolean verify(byte[] signature) throws GeneralSecurityException;
|
||||
}
|
||||
|
||||
@@ -103,15 +103,11 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
||||
|
||||
@Override
|
||||
public boolean open() throws DbException {
|
||||
Runnable shutdownHook = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
close();
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
Runnable shutdownHook = () -> {
|
||||
try {
|
||||
close();
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
};
|
||||
boolean reopened = db.open();
|
||||
@@ -141,11 +137,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
||||
}
|
||||
try {
|
||||
return new Transaction(db.startTransaction(), readOnly);
|
||||
} catch (DbException e) {
|
||||
if (readOnly) lock.readLock().unlock();
|
||||
else lock.writeLock().unlock();
|
||||
throw e;
|
||||
} catch (RuntimeException e) {
|
||||
} catch (DbException | RuntimeException e) {
|
||||
if (readOnly) lock.readLock().unlock();
|
||||
else lock.writeLock().unlock();
|
||||
throw e;
|
||||
@@ -331,7 +323,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
||||
if (!db.containsContact(txn, c))
|
||||
throw new NoSuchContactException();
|
||||
Collection<MessageId> ids = db.getMessagesToSend(txn, c, maxLength);
|
||||
List<byte[]> messages = new ArrayList<byte[]>(ids.size());
|
||||
List<byte[]> messages = new ArrayList<>(ids.size());
|
||||
for (MessageId m : ids) {
|
||||
messages.add(db.getRawMessage(txn, m));
|
||||
db.updateExpiryTime(txn, c, m, maxLatency);
|
||||
@@ -381,7 +373,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
||||
throw new NoSuchContactException();
|
||||
Collection<MessageId> ids = db.getRequestedMessagesToSend(txn, c,
|
||||
maxLength);
|
||||
List<byte[]> messages = new ArrayList<byte[]>(ids.size());
|
||||
List<byte[]> messages = new ArrayList<>(ids.size());
|
||||
for (MessageId m : ids) {
|
||||
messages.add(db.getRawMessage(txn, m));
|
||||
db.updateExpiryTime(txn, c, m, maxLatency);
|
||||
@@ -661,7 +653,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
||||
T txn = unbox(transaction);
|
||||
if (!db.containsContact(txn, c))
|
||||
throw new NoSuchContactException();
|
||||
Collection<MessageId> acked = new ArrayList<MessageId>();
|
||||
Collection<MessageId> acked = new ArrayList<>();
|
||||
for (MessageId m : a.getMessageIds()) {
|
||||
if (db.containsVisibleMessage(txn, c, m)) {
|
||||
db.raiseSeenFlag(txn, c, m);
|
||||
@@ -770,6 +762,16 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
||||
transaction.attach(new LocalAuthorRemovedEvent(a));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeMessage(Transaction transaction, MessageId m)
|
||||
throws DbException {
|
||||
if (transaction.isReadOnly()) throw new IllegalArgumentException();
|
||||
T txn = unbox(transaction);
|
||||
if (!db.containsMessage(txn, m))
|
||||
throw new NoSuchMessageException();
|
||||
db.removeMessage(txn, m);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTransport(Transaction transaction, TransportId t)
|
||||
throws DbException {
|
||||
@@ -886,8 +888,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
||||
Map<ContactId, TransportKeys> keys) throws DbException {
|
||||
if (transaction.isReadOnly()) throw new IllegalArgumentException();
|
||||
T txn = unbox(transaction);
|
||||
Map<ContactId, TransportKeys> filtered =
|
||||
new HashMap<ContactId, TransportKeys>();
|
||||
Map<ContactId, TransportKeys> filtered = new HashMap<>();
|
||||
for (Entry<ContactId, TransportKeys> e : keys.entrySet()) {
|
||||
ContactId c = e.getKey();
|
||||
TransportKeys k = e.getValue();
|
||||
|
||||
@@ -32,7 +32,7 @@ public class DatabaseExecutorModule {
|
||||
|
||||
public DatabaseExecutorModule() {
|
||||
// Use an unbounded queue
|
||||
BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>();
|
||||
BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();
|
||||
// Discard tasks that are submitted during shutdown
|
||||
RejectedExecutionHandler policy =
|
||||
new ThreadPoolExecutor.DiscardPolicy();
|
||||
|
||||
@@ -26,7 +26,7 @@ public class DatabaseModule {
|
||||
@Singleton
|
||||
DatabaseComponent provideDatabaseComponent(Database<Connection> db,
|
||||
EventBus eventBus, ShutdownManager shutdown) {
|
||||
return new DatabaseComponentImpl<Connection>(db, Connection.class,
|
||||
eventBus, shutdown);
|
||||
return new DatabaseComponentImpl<>(db, Connection.class, eventBus,
|
||||
shutdown);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,6 +232,30 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
+ " REFERENCES transports (transportId)"
|
||||
+ " ON DELETE CASCADE)";
|
||||
|
||||
private static final String INDEX_CONTACTS_BY_AUTHOR_ID =
|
||||
"CREATE INDEX IF NOT EXISTS contactsByAuthorId"
|
||||
+ " ON contacts (authorId)";
|
||||
|
||||
private static final String INDEX_MESSAGES_BY_GROUP_ID =
|
||||
"CREATE INDEX IF NOT EXISTS messagesByGroupId"
|
||||
+ " ON messages (groupId)";
|
||||
|
||||
private static final String INDEX_OFFERS_BY_CONTACT_ID =
|
||||
"CREATE INDEX IF NOT EXISTS offersByContactId"
|
||||
+ " ON offers (contactId)";
|
||||
|
||||
private static final String INDEX_GROUPS_BY_CLIENT_ID =
|
||||
"CREATE INDEX IF NOT EXISTS groupsByClientId"
|
||||
+ " ON groups (clientId)";
|
||||
|
||||
private static final String INDEX_MESSAGE_METADATA_BY_MESSAGE_ID =
|
||||
"CREATE INDEX IF NOT EXISTS messageMetadataByMessageId"
|
||||
+ " ON messageMetadata (messageId)";
|
||||
|
||||
private static final String INDEX_GROUP_METADATA_BY_GROUP_ID =
|
||||
"CREATE INDEX IF NOT EXISTS groupMetadataByGroupId"
|
||||
+ " ON groupMetadata (groupId)";
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(JdbcDatabase.class.getName());
|
||||
|
||||
@@ -239,8 +263,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
private final String hashType, binaryType, counterType, secretType;
|
||||
private final Clock clock;
|
||||
|
||||
private final LinkedList<Connection> connections =
|
||||
new LinkedList<Connection>(); // Locking: connectionsLock
|
||||
// Locking: connectionsLock
|
||||
private final LinkedList<Connection> connections = new LinkedList<>();
|
||||
|
||||
private int openConnections = 0; // Locking: connectionsLock
|
||||
private boolean closed = false; // Locking: connectionsLock
|
||||
@@ -267,7 +291,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new DbException(e);
|
||||
}
|
||||
// Open the database and create the tables if necessary
|
||||
// Open the database and create the tables and indexes if necessary
|
||||
Connection txn = startTransaction();
|
||||
try {
|
||||
if (reopen) {
|
||||
@@ -276,6 +300,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
createTables(txn);
|
||||
storeSchemaVersion(txn);
|
||||
}
|
||||
createIndexes(txn);
|
||||
commitTransaction(txn);
|
||||
} catch (DbException e) {
|
||||
abortTransaction(txn);
|
||||
@@ -340,6 +365,23 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
}
|
||||
}
|
||||
|
||||
private void createIndexes(Connection txn) throws DbException {
|
||||
Statement s = null;
|
||||
try {
|
||||
s = txn.createStatement();
|
||||
s.executeUpdate(INDEX_CONTACTS_BY_AUTHOR_ID);
|
||||
s.executeUpdate(INDEX_MESSAGES_BY_GROUP_ID);
|
||||
s.executeUpdate(INDEX_OFFERS_BY_CONTACT_ID);
|
||||
s.executeUpdate(INDEX_GROUPS_BY_CLIENT_ID);
|
||||
s.executeUpdate(INDEX_MESSAGE_METADATA_BY_MESSAGE_ID);
|
||||
s.executeUpdate(INDEX_GROUP_METADATA_BY_GROUP_ID);
|
||||
s.close();
|
||||
} catch (SQLException e) {
|
||||
tryToClose(s);
|
||||
throw new DbException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private String insertTypeNames(String s) {
|
||||
s = s.replaceAll("HASH", hashType);
|
||||
s = s.replaceAll("BINARY", binaryType);
|
||||
@@ -993,7 +1035,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
+ " FROM contacts";
|
||||
ps = txn.prepareStatement(sql);
|
||||
rs = ps.executeQuery();
|
||||
List<Contact> contacts = new ArrayList<Contact>();
|
||||
List<Contact> contacts = new ArrayList<>();
|
||||
while (rs.next()) {
|
||||
ContactId contactId = new ContactId(rs.getInt(1));
|
||||
AuthorId authorId = new AuthorId(rs.getBytes(2));
|
||||
@@ -1027,7 +1069,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setBytes(1, local.getBytes());
|
||||
rs = ps.executeQuery();
|
||||
List<ContactId> ids = new ArrayList<ContactId>();
|
||||
List<ContactId> ids = new ArrayList<>();
|
||||
while (rs.next()) ids.add(new ContactId(rs.getInt(1)));
|
||||
rs.close();
|
||||
ps.close();
|
||||
@@ -1052,7 +1094,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setBytes(1, remote.getBytes());
|
||||
rs = ps.executeQuery();
|
||||
List<Contact> contacts = new ArrayList<Contact>();
|
||||
List<Contact> contacts = new ArrayList<>();
|
||||
while (rs.next()) {
|
||||
ContactId c = new ContactId(rs.getInt(1));
|
||||
String name = rs.getString(2);
|
||||
@@ -1108,7 +1150,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setString(1, c.getString());
|
||||
rs = ps.executeQuery();
|
||||
List<Group> groups = new ArrayList<Group>();
|
||||
List<Group> groups = new ArrayList<>();
|
||||
while (rs.next()) {
|
||||
GroupId id = new GroupId(rs.getBytes(1));
|
||||
byte[] descriptor = rs.getBytes(2);
|
||||
@@ -1161,7 +1203,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setBytes(1, g.getBytes());
|
||||
rs = ps.executeQuery();
|
||||
List<ContactId> visible = new ArrayList<ContactId>();
|
||||
List<ContactId> visible = new ArrayList<>();
|
||||
while (rs.next()) visible.add(new ContactId(rs.getInt(1)));
|
||||
rs.close();
|
||||
ps.close();
|
||||
@@ -1213,7 +1255,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
+ " FROM localAuthors";
|
||||
ps = txn.prepareStatement(sql);
|
||||
rs = ps.executeQuery();
|
||||
List<LocalAuthor> authors = new ArrayList<LocalAuthor>();
|
||||
List<LocalAuthor> authors = new ArrayList<>();
|
||||
while (rs.next()) {
|
||||
AuthorId authorId = new AuthorId(rs.getBytes(1));
|
||||
String name = rs.getString(2);
|
||||
@@ -1243,7 +1285,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setBytes(1, g.getBytes());
|
||||
rs = ps.executeQuery();
|
||||
List<MessageId> ids = new ArrayList<MessageId>();
|
||||
List<MessageId> ids = new ArrayList<>();
|
||||
while (rs.next()) ids.add(new MessageId(rs.getBytes(1)));
|
||||
rs.close();
|
||||
ps.close();
|
||||
@@ -1266,7 +1308,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
ps.setInt(1, state.getValue());
|
||||
ps.setBytes(2, g.getBytes());
|
||||
rs = ps.executeQuery();
|
||||
List<MessageId> ids = new ArrayList<MessageId>();
|
||||
List<MessageId> ids = new ArrayList<>();
|
||||
while (rs.next()) ids.add(new MessageId(rs.getBytes(1)));
|
||||
rs.close();
|
||||
ps.close();
|
||||
@@ -1301,7 +1343,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
ps.setString(3, e.getKey());
|
||||
ps.setBytes(4, e.getValue());
|
||||
rs = ps.executeQuery();
|
||||
Set<MessageId> ids = new HashSet<MessageId>();
|
||||
Set<MessageId> ids = new HashSet<>();
|
||||
while (rs.next()) ids.add(new MessageId(rs.getBytes(1)));
|
||||
rs.close();
|
||||
ps.close();
|
||||
@@ -1335,7 +1377,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
ps.setInt(1, DELIVERED.getValue());
|
||||
ps.setBytes(2, g.getBytes());
|
||||
rs = ps.executeQuery();
|
||||
Map<MessageId, Metadata> all = new HashMap<MessageId, Metadata>();
|
||||
Map<MessageId, Metadata> all = new HashMap<>();
|
||||
Metadata metadata = null;
|
||||
MessageId lastMessageId = null;
|
||||
while (rs.next()) {
|
||||
@@ -1364,8 +1406,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
Collection<MessageId> matches = getMessageIds(txn, g, query);
|
||||
if (matches.isEmpty()) return Collections.emptyMap();
|
||||
// Retrieve the metadata for each match
|
||||
Map<MessageId, Metadata> all = new HashMap<MessageId, Metadata>(
|
||||
matches.size());
|
||||
Map<MessageId, Metadata> all = new HashMap<>(matches.size());
|
||||
for (MessageId m : matches) all.put(m, getMessageMetadata(txn, m));
|
||||
return all;
|
||||
}
|
||||
@@ -1463,7 +1504,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
ps.setBytes(1, g.getBytes());
|
||||
ps.setInt(2, c.getInt());
|
||||
rs = ps.executeQuery();
|
||||
List<MessageStatus> statuses = new ArrayList<MessageStatus>();
|
||||
List<MessageStatus> statuses = new ArrayList<>();
|
||||
while (rs.next()) {
|
||||
MessageId messageId = new MessageId(rs.getBytes(1));
|
||||
boolean sent = rs.getBoolean(2);
|
||||
@@ -1522,7 +1563,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setBytes(1, m.getBytes());
|
||||
rs = ps.executeQuery();
|
||||
Map<MessageId, State> dependencies = new HashMap<MessageId, State>();
|
||||
Map<MessageId, State> dependencies = new HashMap<>();
|
||||
while (rs.next()) {
|
||||
MessageId dependency = new MessageId(rs.getBytes(1));
|
||||
State state = State.fromValue(rs.getInt(2));
|
||||
@@ -1560,7 +1601,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setBytes(1, m.getBytes());
|
||||
rs = ps.executeQuery();
|
||||
Map<MessageId, State> dependents = new HashMap<MessageId, State>();
|
||||
Map<MessageId, State> dependents = new HashMap<>();
|
||||
while (rs.next()) {
|
||||
MessageId dependent = new MessageId(rs.getBytes(1));
|
||||
State state = State.fromValue(rs.getInt(2));
|
||||
@@ -1612,7 +1653,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
ps.setInt(1, c.getInt());
|
||||
ps.setInt(2, maxMessages);
|
||||
rs = ps.executeQuery();
|
||||
List<MessageId> ids = new ArrayList<MessageId>();
|
||||
List<MessageId> ids = new ArrayList<>();
|
||||
while (rs.next()) ids.add(new MessageId(rs.getBytes(1)));
|
||||
rs.close();
|
||||
ps.close();
|
||||
@@ -1648,7 +1689,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
ps.setLong(3, now);
|
||||
ps.setInt(4, maxMessages);
|
||||
rs = ps.executeQuery();
|
||||
List<MessageId> ids = new ArrayList<MessageId>();
|
||||
List<MessageId> ids = new ArrayList<>();
|
||||
while (rs.next()) ids.add(new MessageId(rs.getBytes(1)));
|
||||
rs.close();
|
||||
ps.close();
|
||||
@@ -1673,7 +1714,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
ps.setInt(1, c.getInt());
|
||||
ps.setInt(2, maxMessages);
|
||||
rs = ps.executeQuery();
|
||||
List<MessageId> ids = new ArrayList<MessageId>();
|
||||
List<MessageId> ids = new ArrayList<>();
|
||||
while (rs.next()) ids.add(new MessageId(rs.getBytes(1)));
|
||||
rs.close();
|
||||
ps.close();
|
||||
@@ -1708,7 +1749,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
ps.setInt(2, DELIVERED.getValue());
|
||||
ps.setLong(3, now);
|
||||
rs = ps.executeQuery();
|
||||
List<MessageId> ids = new ArrayList<MessageId>();
|
||||
List<MessageId> ids = new ArrayList<>();
|
||||
int total = 0;
|
||||
while (rs.next()) {
|
||||
int length = rs.getInt(1);
|
||||
@@ -1750,7 +1791,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
ps.setInt(1, state.getValue());
|
||||
ps.setString(2, c.getString());
|
||||
rs = ps.executeQuery();
|
||||
List<MessageId> ids = new ArrayList<MessageId>();
|
||||
List<MessageId> ids = new ArrayList<>();
|
||||
while (rs.next()) ids.add(new MessageId(rs.getBytes(1)));
|
||||
rs.close();
|
||||
ps.close();
|
||||
@@ -1780,7 +1821,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setString(1, c.getString());
|
||||
rs = ps.executeQuery();
|
||||
List<MessageId> ids = new ArrayList<MessageId>();
|
||||
List<MessageId> ids = new ArrayList<>();
|
||||
while (rs.next()) ids.add(new MessageId(rs.getBytes(1)));
|
||||
rs.close();
|
||||
ps.close();
|
||||
@@ -1839,7 +1880,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
ps.setInt(2, DELIVERED.getValue());
|
||||
ps.setLong(3, now);
|
||||
rs = ps.executeQuery();
|
||||
List<MessageId> ids = new ArrayList<MessageId>();
|
||||
List<MessageId> ids = new ArrayList<>();
|
||||
int total = 0;
|
||||
while (rs.next()) {
|
||||
int length = rs.getInt(1);
|
||||
@@ -1893,7 +1934,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setString(1, t.getString());
|
||||
rs = ps.executeQuery();
|
||||
List<IncomingKeys> inKeys = new ArrayList<IncomingKeys>();
|
||||
List<IncomingKeys> inKeys = new ArrayList<>();
|
||||
while (rs.next()) {
|
||||
long rotationPeriod = rs.getLong(1);
|
||||
SecretKey tagKey = new SecretKey(rs.getBytes(2));
|
||||
@@ -1913,8 +1954,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setString(1, t.getString());
|
||||
rs = ps.executeQuery();
|
||||
Map<ContactId, TransportKeys> keys =
|
||||
new HashMap<ContactId, TransportKeys>();
|
||||
Map<ContactId, TransportKeys> keys = new HashMap<>();
|
||||
for (int i = 0; rs.next(); i++) {
|
||||
// There should be three times as many incoming keys
|
||||
if (inKeys.size() < (i + 1) * 3) throw new DbStateException();
|
||||
@@ -2032,8 +2072,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
// Determine which keys are being removed
|
||||
List<String> removed = new ArrayList<String>();
|
||||
Map<String, byte[]> retained = new HashMap<String, byte[]>();
|
||||
List<String> removed = new ArrayList<>();
|
||||
Map<String, byte[]> retained = new HashMap<>();
|
||||
for (Entry<String, byte[]> e : meta.entrySet()) {
|
||||
if (e.getValue() == REMOVE) removed.add(e.getKey());
|
||||
else retained.put(e.getKey(), e.getValue());
|
||||
|
||||
@@ -15,7 +15,7 @@ import javax.annotation.concurrent.ThreadSafe;
|
||||
class EventBusImpl implements EventBus {
|
||||
|
||||
private final Collection<EventListener> listeners =
|
||||
new CopyOnWriteArrayList<EventListener>();
|
||||
new CopyOnWriteArrayList<>();
|
||||
|
||||
@Override
|
||||
public void addListener(EventListener l) {
|
||||
|
||||
@@ -50,10 +50,9 @@ class KeyAgreementConnector {
|
||||
private final PluginManager pluginManager;
|
||||
private final CompletionService<KeyAgreementConnection> connect;
|
||||
|
||||
private final List<KeyAgreementListener> listeners =
|
||||
new ArrayList<KeyAgreementListener>();
|
||||
private final List<KeyAgreementListener> listeners = new ArrayList<>();
|
||||
private final List<Future<KeyAgreementConnection>> pending =
|
||||
new ArrayList<Future<KeyAgreementConnection>>();
|
||||
new ArrayList<>();
|
||||
|
||||
private volatile boolean connecting = false;
|
||||
private volatile boolean alice = false;
|
||||
@@ -65,8 +64,7 @@ class KeyAgreementConnector {
|
||||
this.clock = clock;
|
||||
this.crypto = crypto;
|
||||
this.pluginManager = pluginManager;
|
||||
connect = new ExecutorCompletionService<KeyAgreementConnection>(
|
||||
ioExecutor);
|
||||
connect = new ExecutorCompletionService<>(ioExecutor);
|
||||
}
|
||||
|
||||
public Payload listen(KeyPair localKeyPair) {
|
||||
@@ -75,8 +73,7 @@ class KeyAgreementConnector {
|
||||
byte[] commitment = crypto.deriveKeyCommitment(
|
||||
localKeyPair.getPublic().getEncoded());
|
||||
// Start all listeners and collect their descriptors
|
||||
List<TransportDescriptor> descriptors =
|
||||
new ArrayList<TransportDescriptor>();
|
||||
List<TransportDescriptor> descriptors = new ArrayList<>();
|
||||
for (DuplexPlugin plugin : pluginManager.getKeyAgreementPlugins()) {
|
||||
KeyAgreementListener l =
|
||||
plugin.createKeyAgreementListener(commitment);
|
||||
@@ -132,10 +129,7 @@ class KeyAgreementConnector {
|
||||
LOG.info("Interrupted while waiting for connection");
|
||||
Thread.currentThread().interrupt();
|
||||
return null;
|
||||
} catch (ExecutionException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
return null;
|
||||
} catch (IOException e) {
|
||||
} catch (ExecutionException | IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
return null;
|
||||
} finally {
|
||||
|
||||
@@ -51,8 +51,7 @@ class PayloadParserImpl implements PayloadParser {
|
||||
byte[] commitment = payload.getRaw(1);
|
||||
if (commitment.length != COMMIT_LENGTH) throw new FormatException();
|
||||
// Remaining elements: transport descriptors
|
||||
List<TransportDescriptor> recognised =
|
||||
new ArrayList<TransportDescriptor>();
|
||||
List<TransportDescriptor> recognised = new ArrayList<>();
|
||||
for (int i = 2; i < payload.size(); i++) {
|
||||
BdfList descriptor = payload.getList(i);
|
||||
long transportId = descriptor.getLong(0);
|
||||
|
||||
@@ -63,9 +63,9 @@ class LifecycleManagerImpl implements LifecycleManager {
|
||||
this.crypto = crypto;
|
||||
this.authorFactory = authorFactory;
|
||||
this.identityManager = identityManager;
|
||||
services = new CopyOnWriteArrayList<Service>();
|
||||
clients = new CopyOnWriteArrayList<Client>();
|
||||
executors = new CopyOnWriteArrayList<ExecutorService>();
|
||||
services = new CopyOnWriteArrayList<>();
|
||||
clients = new CopyOnWriteArrayList<>();
|
||||
executors = new CopyOnWriteArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -88,7 +88,7 @@ class LifecycleManagerImpl implements LifecycleManager {
|
||||
executors.add(e);
|
||||
}
|
||||
|
||||
private LocalAuthor createLocalAuthor(final String nickname) {
|
||||
private LocalAuthor createLocalAuthor(String nickname) {
|
||||
long now = System.currentTimeMillis();
|
||||
KeyPair keyPair = crypto.generateSignatureKeyPair();
|
||||
byte[] publicKey = keyPair.getPublic().getEncoded();
|
||||
@@ -203,9 +203,7 @@ class LifecycleManagerImpl implements LifecycleManager {
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Closing database took " + duration + " ms");
|
||||
shutdownLatch.countDown();
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (ServiceException e) {
|
||||
} catch (DbException | ServiceException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} finally {
|
||||
startStopSemaphore.release();
|
||||
|
||||
@@ -37,7 +37,7 @@ public class LifecycleModule {
|
||||
|
||||
public LifecycleModule() {
|
||||
// The thread pool is unbounded, so use direct handoff
|
||||
BlockingQueue<Runnable> queue = new SynchronousQueue<Runnable>();
|
||||
BlockingQueue<Runnable> queue = new SynchronousQueue<>();
|
||||
// Discard tasks that are submitted during shutdown
|
||||
RejectedExecutionHandler policy =
|
||||
new ThreadPoolExecutor.DiscardPolicy();
|
||||
|
||||
@@ -21,7 +21,7 @@ class ShutdownManagerImpl implements ShutdownManager {
|
||||
private int nextHandle = 0;
|
||||
|
||||
ShutdownManagerImpl() {
|
||||
hooks = new HashMap<Integer, Thread>();
|
||||
hooks = new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -134,11 +134,7 @@ class ConnectionManagerImpl implements ConnectionManager {
|
||||
try {
|
||||
byte[] tag = readTag(reader);
|
||||
ctx = keyManager.getStreamContext(transportId, tag);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
disposeReader(true, false);
|
||||
return;
|
||||
} catch (DbException e) {
|
||||
} catch (IOException | DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
disposeReader(true, false);
|
||||
return;
|
||||
@@ -249,11 +245,7 @@ class ConnectionManagerImpl implements ConnectionManager {
|
||||
try {
|
||||
byte[] tag = readTag(reader);
|
||||
ctx = keyManager.getStreamContext(transportId, tag);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
disposeReader(true, false);
|
||||
return;
|
||||
} catch (DbException e) {
|
||||
} catch (IOException | DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
disposeReader(true, false);
|
||||
return;
|
||||
@@ -266,12 +258,7 @@ class ConnectionManagerImpl implements ConnectionManager {
|
||||
contactId = ctx.getContactId();
|
||||
connectionRegistry.registerConnection(contactId, transportId, true);
|
||||
// Start the outgoing session on another thread
|
||||
ioExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
runOutgoingSession();
|
||||
}
|
||||
});
|
||||
ioExecutor.execute(this::runOutgoingSession);
|
||||
try {
|
||||
// Create and run the incoming session
|
||||
incomingSession = createIncomingSession(ctx, reader);
|
||||
@@ -368,12 +355,7 @@ class ConnectionManagerImpl implements ConnectionManager {
|
||||
return;
|
||||
}
|
||||
// Start the incoming session on another thread
|
||||
ioExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
runIncomingSession();
|
||||
}
|
||||
});
|
||||
ioExecutor.execute(this::runIncomingSession);
|
||||
try {
|
||||
// Create and run the outgoing session
|
||||
outgoingSession = createDuplexOutgoingSession(ctx, writer);
|
||||
@@ -391,11 +373,7 @@ class ConnectionManagerImpl implements ConnectionManager {
|
||||
try {
|
||||
byte[] tag = readTag(reader);
|
||||
ctx = keyManager.getStreamContext(transportId, tag);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
disposeReader(true, false);
|
||||
return;
|
||||
} catch (DbException e) {
|
||||
} catch (IOException | DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
disposeReader(true, false);
|
||||
return;
|
||||
|
||||
@@ -42,8 +42,8 @@ class ConnectionRegistryImpl implements ConnectionRegistry {
|
||||
@Inject
|
||||
ConnectionRegistryImpl(EventBus eventBus) {
|
||||
this.eventBus = eventBus;
|
||||
connections = new HashMap<TransportId, Map<ContactId, Integer>>();
|
||||
contactCounts = new HashMap<ContactId, Integer>();
|
||||
connections = new HashMap<>();
|
||||
contactCounts = new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -58,7 +58,7 @@ class ConnectionRegistryImpl implements ConnectionRegistry {
|
||||
try {
|
||||
Map<ContactId, Integer> m = connections.get(t);
|
||||
if (m == null) {
|
||||
m = new HashMap<ContactId, Integer>();
|
||||
m = new HashMap<>();
|
||||
connections.put(t, m);
|
||||
}
|
||||
Integer count = m.get(c);
|
||||
@@ -124,7 +124,7 @@ class ConnectionRegistryImpl implements ConnectionRegistry {
|
||||
try {
|
||||
Map<ContactId, Integer> m = connections.get(t);
|
||||
if (m == null) return Collections.emptyList();
|
||||
List<ContactId> ids = new ArrayList<ContactId>(m.keySet());
|
||||
List<ContactId> ids = new ArrayList<>(m.keySet());
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info(ids.size() + " contacts connected");
|
||||
return ids;
|
||||
|
||||
@@ -82,10 +82,10 @@ class PluginManagerImpl implements PluginManager, Service {
|
||||
this.settingsManager = settingsManager;
|
||||
this.transportPropertyManager = transportPropertyManager;
|
||||
this.uiCallback = uiCallback;
|
||||
plugins = new ConcurrentHashMap<TransportId, Plugin>();
|
||||
simplexPlugins = new CopyOnWriteArrayList<SimplexPlugin>();
|
||||
duplexPlugins = new CopyOnWriteArrayList<DuplexPlugin>();
|
||||
startLatches = new ConcurrentHashMap<TransportId, CountDownLatch>();
|
||||
plugins = new ConcurrentHashMap<>();
|
||||
simplexPlugins = new CopyOnWriteArrayList<>();
|
||||
duplexPlugins = new CopyOnWriteArrayList<>();
|
||||
startLatches = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -156,17 +156,17 @@ class PluginManagerImpl implements PluginManager, Service {
|
||||
|
||||
@Override
|
||||
public Collection<SimplexPlugin> getSimplexPlugins() {
|
||||
return new ArrayList<SimplexPlugin>(simplexPlugins);
|
||||
return new ArrayList<>(simplexPlugins);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<DuplexPlugin> getDuplexPlugins() {
|
||||
return new ArrayList<DuplexPlugin>(duplexPlugins);
|
||||
return new ArrayList<>(duplexPlugins);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<DuplexPlugin> getKeyAgreementPlugins() {
|
||||
List<DuplexPlugin> supported = new ArrayList<DuplexPlugin>();
|
||||
List<DuplexPlugin> supported = new ArrayList<>();
|
||||
for (DuplexPlugin d : duplexPlugins)
|
||||
if (d.supportsKeyAgreement()) supported.add(d);
|
||||
return supported;
|
||||
|
||||
@@ -66,7 +66,7 @@ class Poller implements EventListener {
|
||||
this.random = random;
|
||||
this.clock = clock;
|
||||
lock = new ReentrantLock();
|
||||
tasks = new HashMap<TransportId, PollTask>();
|
||||
tasks = new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -111,30 +111,24 @@ class Poller implements EventListener {
|
||||
connectToContact(c, (DuplexPlugin) p);
|
||||
}
|
||||
|
||||
private void connectToContact(final ContactId c, final SimplexPlugin p) {
|
||||
ioExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
TransportId t = p.getId();
|
||||
if (!connectionRegistry.isConnected(c, t)) {
|
||||
TransportConnectionWriter w = p.createWriter(c);
|
||||
if (w != null)
|
||||
connectionManager.manageOutgoingConnection(c, t, w);
|
||||
}
|
||||
private void connectToContact(ContactId c, SimplexPlugin p) {
|
||||
ioExecutor.execute(() -> {
|
||||
TransportId t = p.getId();
|
||||
if (!connectionRegistry.isConnected(c, t)) {
|
||||
TransportConnectionWriter w = p.createWriter(c);
|
||||
if (w != null)
|
||||
connectionManager.manageOutgoingConnection(c, t, w);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void connectToContact(final ContactId c, final DuplexPlugin p) {
|
||||
ioExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
TransportId t = p.getId();
|
||||
if (!connectionRegistry.isConnected(c, t)) {
|
||||
DuplexTransportConnection d = p.createConnection(c);
|
||||
if (d != null)
|
||||
connectionManager.manageOutgoingConnection(c, t, d);
|
||||
}
|
||||
private void connectToContact(ContactId c, DuplexPlugin p) {
|
||||
ioExecutor.execute(() -> {
|
||||
TransportId t = p.getId();
|
||||
if (!connectionRegistry.isConnected(c, t)) {
|
||||
DuplexTransportConnection d = p.createConnection(c);
|
||||
if (d != null)
|
||||
connectionManager.manageOutgoingConnection(c, t, d);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -159,14 +153,10 @@ class Poller implements EventListener {
|
||||
try {
|
||||
PollTask scheduled = tasks.get(t);
|
||||
if (scheduled == null || due < scheduled.due) {
|
||||
final PollTask task = new PollTask(p, due, randomiseNext);
|
||||
PollTask task = new PollTask(p, due, randomiseNext);
|
||||
tasks.put(t, task);
|
||||
scheduler.schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ioExecutor.execute(task);
|
||||
}
|
||||
}, delay, MILLISECONDS);
|
||||
scheduler.schedule(
|
||||
() -> ioExecutor.execute(task), delay, MILLISECONDS);
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
@@ -174,7 +164,7 @@ class Poller implements EventListener {
|
||||
}
|
||||
|
||||
@IoExecutor
|
||||
private void poll(final Plugin p) {
|
||||
private void poll(Plugin p) {
|
||||
TransportId t = p.getId();
|
||||
if (LOG.isLoggable(INFO)) LOG.info("Polling plugin " + t);
|
||||
p.poll(connectionRegistry.getConnectedContacts(t));
|
||||
|
||||
@@ -108,7 +108,7 @@ abstract class FilePlugin implements SimplexPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
protected void createReaderFromFile(final File f) {
|
||||
protected void createReaderFromFile(File f) {
|
||||
if (!running) return;
|
||||
ioExecutor.execute(new ReaderCreator(f));
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ class LanTcpPlugin extends TcpPlugin {
|
||||
TransportProperties p = callback.getLocalProperties();
|
||||
String oldIpPorts = p.get(PROP_IP_PORTS);
|
||||
List<InetSocketAddress> olds = parseSocketAddresses(oldIpPorts);
|
||||
List<InetSocketAddress> locals = new LinkedList<InetSocketAddress>();
|
||||
List<InetSocketAddress> locals = new LinkedList<>();
|
||||
for (InetAddress local : getLocalIpAddresses()) {
|
||||
if (isAcceptableAddress(local)) {
|
||||
// If this is the old address, try to use the same port
|
||||
@@ -82,7 +82,7 @@ class LanTcpPlugin extends TcpPlugin {
|
||||
private List<InetSocketAddress> parseSocketAddresses(String ipPorts) {
|
||||
if (StringUtils.isNullOrEmpty(ipPorts)) return Collections.emptyList();
|
||||
String[] split = ipPorts.split(SEPARATOR);
|
||||
List<InetSocketAddress> addresses = new ArrayList<InetSocketAddress>();
|
||||
List<InetSocketAddress> addresses = new ArrayList<>();
|
||||
for (String ipPort : split) {
|
||||
InetSocketAddress a = parseSocketAddress(ipPort);
|
||||
if (a != null) addresses.add(a);
|
||||
@@ -95,7 +95,7 @@ class LanTcpPlugin extends TcpPlugin {
|
||||
String ipPort = getIpPortString(a);
|
||||
// Get the list of recently used addresses
|
||||
String setting = callback.getSettings().get(PREF_LAN_IP_PORTS);
|
||||
List<String> recent = new ArrayList<String>();
|
||||
List<String> recent = new ArrayList<>();
|
||||
if (!StringUtils.isNullOrEmpty(setting))
|
||||
Collections.addAll(recent, setting.split(SEPARATOR));
|
||||
// Is the address already in the list?
|
||||
@@ -111,7 +111,7 @@ class LanTcpPlugin extends TcpPlugin {
|
||||
recent = recent.subList(0, MAX_ADDRESSES);
|
||||
setting = StringUtils.join(recent, SEPARATOR);
|
||||
// Update the list of addresses shared with contacts
|
||||
List<String> shared = new ArrayList<String>(recent);
|
||||
List<String> shared = new ArrayList<>(recent);
|
||||
Collections.sort(shared);
|
||||
String property = StringUtils.join(shared, SEPARATOR);
|
||||
TransportProperties properties = new TransportProperties();
|
||||
@@ -260,16 +260,12 @@ class LanTcpPlugin extends TcpPlugin {
|
||||
|
||||
@Override
|
||||
public Callable<KeyAgreementConnection> listen() {
|
||||
return new Callable<KeyAgreementConnection>() {
|
||||
@Override
|
||||
public KeyAgreementConnection call() throws IOException {
|
||||
Socket s = ss.accept();
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info(ID.getString() + ": Incoming connection");
|
||||
return new KeyAgreementConnection(
|
||||
new TcpTransportConnection(LanTcpPlugin.this, s),
|
||||
ID);
|
||||
}
|
||||
return () -> {
|
||||
Socket s = ss.accept();
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info(ID.getString() + ": Incoming connection");
|
||||
return new KeyAgreementConnection(
|
||||
new TcpTransportConnection(LanTcpPlugin.this, s), ID);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ class PortMapperImpl implements PortMapper {
|
||||
}
|
||||
|
||||
@Override
|
||||
public MappingResult map(final int port) {
|
||||
public MappingResult map(int port) {
|
||||
if (!started.getAndSet(true)) start();
|
||||
if (gateway == null) return null;
|
||||
InetAddress internal = gateway.getLocalAddress();
|
||||
@@ -50,12 +50,7 @@ class PortMapperImpl implements PortMapper {
|
||||
succeeded = gateway.addPortMapping(port, port,
|
||||
getHostAddress(internal), "TCP", "TCP");
|
||||
if (succeeded) {
|
||||
shutdownManager.addShutdownHook(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
deleteMapping(port);
|
||||
}
|
||||
});
|
||||
shutdownManager.addShutdownHook(() -> deleteMapping(port));
|
||||
}
|
||||
String externalString = gateway.getExternalIPAddress();
|
||||
if (LOG.isLoggable(INFO))
|
||||
@@ -63,9 +58,7 @@ class PortMapperImpl implements PortMapper {
|
||||
"External address " + scrubInetAddress(externalString));
|
||||
if (externalString != null)
|
||||
external = InetAddress.getByName(externalString);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (SAXException e) {
|
||||
} catch (IOException | SAXException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
return new MappingResult(internal, external, port, succeeded);
|
||||
@@ -82,11 +75,7 @@ class PortMapperImpl implements PortMapper {
|
||||
GatewayDiscover d = new GatewayDiscover();
|
||||
try {
|
||||
d.discover();
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (SAXException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (ParserConfigurationException e) {
|
||||
} catch (IOException | SAXException | ParserConfigurationException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
gateway = d.getValidGateway();
|
||||
@@ -97,9 +86,7 @@ class PortMapperImpl implements PortMapper {
|
||||
gateway.deletePortMapping(port, "TCP");
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Deleted mapping for port " + port);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
} catch (SAXException e) {
|
||||
} catch (IOException | SAXException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,41 +110,37 @@ abstract class TcpPlugin implements DuplexPlugin {
|
||||
}
|
||||
|
||||
protected void bind() {
|
||||
ioExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!running) return;
|
||||
ServerSocket ss = null;
|
||||
for (InetSocketAddress addr : getLocalSocketAddresses()) {
|
||||
try {
|
||||
ss = new ServerSocket();
|
||||
ss.bind(addr);
|
||||
break;
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Failed to bind " +
|
||||
scrubSocketAddress(addr));
|
||||
tryToClose(ss);
|
||||
}
|
||||
}
|
||||
if (ss == null || !ss.isBound()) {
|
||||
LOG.info("Could not bind server socket");
|
||||
return;
|
||||
}
|
||||
if (!running) {
|
||||
ioExecutor.execute(() -> {
|
||||
if (!running) return;
|
||||
ServerSocket ss = null;
|
||||
for (InetSocketAddress addr : getLocalSocketAddresses()) {
|
||||
try {
|
||||
ss = new ServerSocket();
|
||||
ss.bind(addr);
|
||||
break;
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Failed to bind " + scrubSocketAddress(addr));
|
||||
tryToClose(ss);
|
||||
return;
|
||||
}
|
||||
socket = ss;
|
||||
backoff.reset();
|
||||
InetSocketAddress local =
|
||||
(InetSocketAddress) ss.getLocalSocketAddress();
|
||||
setLocalSocketAddress(local);
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Listening on " + scrubSocketAddress(local));
|
||||
callback.transportEnabled();
|
||||
acceptContactConnections();
|
||||
}
|
||||
if (ss == null || !ss.isBound()) {
|
||||
LOG.info("Could not bind server socket");
|
||||
return;
|
||||
}
|
||||
if (!running) {
|
||||
tryToClose(ss);
|
||||
return;
|
||||
}
|
||||
socket = ss;
|
||||
backoff.reset();
|
||||
InetSocketAddress local =
|
||||
(InetSocketAddress) ss.getLocalSocketAddress();
|
||||
setLocalSocketAddress(local);
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Listening on " + scrubSocketAddress(local));
|
||||
callback.transportEnabled();
|
||||
acceptContactConnections();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -218,17 +214,13 @@ abstract class TcpPlugin implements DuplexPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
private void connectAndCallBack(final ContactId c,
|
||||
final TransportProperties p) {
|
||||
ioExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!isRunning()) return;
|
||||
DuplexTransportConnection d = createConnection(p);
|
||||
if (d != null) {
|
||||
backoff.reset();
|
||||
callback.outgoingConnectionCreated(c, d);
|
||||
}
|
||||
private void connectAndCallBack(ContactId c, TransportProperties p) {
|
||||
ioExecutor.execute(() -> {
|
||||
if (!isRunning()) return;
|
||||
DuplexTransportConnection d = createConnection(p);
|
||||
if (d != null) {
|
||||
backoff.reset();
|
||||
callback.outgoingConnectionCreated(c, d);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -317,7 +309,7 @@ abstract class TcpPlugin implements DuplexPlugin {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<InetAddress> addrs = new ArrayList<InetAddress>();
|
||||
List<InetAddress> addrs = new ArrayList<>();
|
||||
for (NetworkInterface iface : ifaces)
|
||||
addrs.addAll(Collections.list(iface.getInetAddresses()));
|
||||
return addrs;
|
||||
|
||||
@@ -43,7 +43,7 @@ class WanTcpPlugin extends TcpPlugin {
|
||||
// Use the same address and port as last time if available
|
||||
TransportProperties p = callback.getLocalProperties();
|
||||
InetSocketAddress old = parseSocketAddress(p.get(PROP_IP_PORT));
|
||||
List<InetSocketAddress> addrs = new LinkedList<InetSocketAddress>();
|
||||
List<InetSocketAddress> addrs = new LinkedList<>();
|
||||
for (InetAddress a : getLocalIpAddresses()) {
|
||||
if (isAcceptableAddress(a)) {
|
||||
// If this is the old address, try to use the same port
|
||||
|
||||
@@ -40,9 +40,12 @@ public class PropertiesModule {
|
||||
@Provides
|
||||
@Singleton
|
||||
TransportPropertyManager getTransportPropertyManager(
|
||||
LifecycleManager lifecycleManager, ContactManager contactManager,
|
||||
LifecycleManager lifecycleManager,
|
||||
ValidationManager validationManager, ContactManager contactManager,
|
||||
TransportPropertyManagerImpl transportPropertyManager) {
|
||||
lifecycleManager.registerClient(transportPropertyManager);
|
||||
validationManager.registerIncomingMessageHook(CLIENT_ID,
|
||||
transportPropertyManager);
|
||||
contactManager.registerAddContactHook(transportPropertyManager);
|
||||
contactManager.registerRemoveContactHook(transportPropertyManager);
|
||||
return transportPropertyManager;
|
||||
|
||||
@@ -9,8 +9,10 @@ import org.briarproject.bramble.api.contact.ContactManager.AddContactHook;
|
||||
import org.briarproject.bramble.api.contact.ContactManager.RemoveContactHook;
|
||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.api.data.MetadataParser;
|
||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||
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.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.plugin.TransportId;
|
||||
@@ -19,8 +21,10 @@ import org.briarproject.bramble.api.properties.TransportPropertyManager;
|
||||
import org.briarproject.bramble.api.sync.Client;
|
||||
import org.briarproject.bramble.api.sync.Group;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.bramble.api.sync.InvalidMessageException;
|
||||
import org.briarproject.bramble.api.sync.Message;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.api.sync.ValidationManager.IncomingMessageHook;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
|
||||
import java.util.HashMap;
|
||||
@@ -36,20 +40,22 @@ import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
class TransportPropertyManagerImpl implements TransportPropertyManager,
|
||||
Client, AddContactHook, RemoveContactHook {
|
||||
Client, AddContactHook, RemoveContactHook, IncomingMessageHook {
|
||||
|
||||
private final DatabaseComponent db;
|
||||
private final ClientHelper clientHelper;
|
||||
private final MetadataParser metadataParser;
|
||||
private final ContactGroupFactory contactGroupFactory;
|
||||
private final Clock clock;
|
||||
private final Group localGroup;
|
||||
|
||||
@Inject
|
||||
TransportPropertyManagerImpl(DatabaseComponent db,
|
||||
ClientHelper clientHelper, ContactGroupFactory contactGroupFactory,
|
||||
Clock clock) {
|
||||
ClientHelper clientHelper, MetadataParser metadataParser,
|
||||
ContactGroupFactory contactGroupFactory, Clock clock) {
|
||||
this.db = db;
|
||||
this.clientHelper = clientHelper;
|
||||
this.metadataParser = metadataParser;
|
||||
this.contactGroupFactory = contactGroupFactory;
|
||||
this.clock = clock;
|
||||
localGroup = contactGroupFactory.createLocalGroup(CLIENT_ID);
|
||||
@@ -84,6 +90,31 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
||||
db.removeGroup(txn, getContactGroup(c));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean incomingMessage(Transaction txn, Message m, Metadata meta)
|
||||
throws DbException, InvalidMessageException {
|
||||
try {
|
||||
// Find the latest update for this transport, if any
|
||||
BdfDictionary d = metadataParser.parse(meta);
|
||||
TransportId t = new TransportId(d.getString("transportId"));
|
||||
LatestUpdate latest = findLatest(txn, m.getGroupId(), t, false);
|
||||
if (latest != null) {
|
||||
if (d.getLong("version") > latest.version) {
|
||||
// This update is newer - delete the previous update
|
||||
db.deleteMessage(txn, latest.messageId);
|
||||
db.deleteMessageMetadata(txn, latest.messageId);
|
||||
} else {
|
||||
// We've already received a newer update - delete this one
|
||||
db.deleteMessage(txn, m.getId());
|
||||
db.deleteMessageMetadata(txn, m.getId());
|
||||
}
|
||||
}
|
||||
} catch (FormatException e) {
|
||||
throw new InvalidMessageException(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRemoteProperties(Transaction txn, ContactId c,
|
||||
Map<TransportId, TransportProperties> props) throws DbException {
|
||||
@@ -112,11 +143,9 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
||||
public Map<TransportId, TransportProperties> getLocalProperties(
|
||||
Transaction txn) throws DbException {
|
||||
try {
|
||||
Map<TransportId, TransportProperties> local =
|
||||
new HashMap<TransportId, TransportProperties>();
|
||||
Map<TransportId, TransportProperties> local = new HashMap<>();
|
||||
// Find the latest local update for each transport
|
||||
Map<TransportId, LatestUpdate> latest = findLatest(txn,
|
||||
localGroup.getId(), true);
|
||||
Map<TransportId, LatestUpdate> latest = findLatestLocal(txn);
|
||||
// Retrieve and parse the latest local properties
|
||||
for (Entry<TransportId, LatestUpdate> e : latest.entrySet()) {
|
||||
BdfList message = clientHelper.getMessageAsList(txn,
|
||||
@@ -160,8 +189,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
||||
@Override
|
||||
public Map<ContactId, TransportProperties> getRemoteProperties(
|
||||
TransportId t) throws DbException {
|
||||
Map<ContactId, TransportProperties> remote =
|
||||
new HashMap<ContactId, TransportProperties>();
|
||||
Map<ContactId, TransportProperties> remote = new HashMap<>();
|
||||
Transaction txn = db.startTransaction(true);
|
||||
try {
|
||||
for (Contact c : db.getContacts(txn))
|
||||
@@ -234,6 +262,9 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
||||
long version = latest == null ? 1 : latest.version + 1;
|
||||
storeMessage(txn, localGroup.getId(), t, merged, version,
|
||||
true, false);
|
||||
// Delete the previous update, if any
|
||||
if (latest != null)
|
||||
db.removeMessage(txn, latest.messageId);
|
||||
// Store the merged properties in each contact's group
|
||||
for (Contact c : db.getContacts(txn)) {
|
||||
Group g = getContactGroup(c);
|
||||
@@ -241,6 +272,9 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
||||
version = latest == null ? 1 : latest.version + 1;
|
||||
storeMessage(txn, g.getId(), t, merged, version,
|
||||
true, true);
|
||||
// Delete the previous update, if any
|
||||
if (latest != null)
|
||||
db.removeMessage(txn, latest.messageId);
|
||||
}
|
||||
}
|
||||
db.commitTransaction(txn);
|
||||
@@ -278,21 +312,16 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
||||
return BdfList.of(t.getString(), version, p);
|
||||
}
|
||||
|
||||
private Map<TransportId, LatestUpdate> findLatest(Transaction txn,
|
||||
GroupId g, boolean local) throws DbException, FormatException {
|
||||
Map<TransportId, LatestUpdate> latestUpdates =
|
||||
new HashMap<TransportId, LatestUpdate>();
|
||||
Map<MessageId, BdfDictionary> metadata =
|
||||
clientHelper.getMessageMetadataAsDictionary(txn, g);
|
||||
private Map<TransportId, LatestUpdate> findLatestLocal(Transaction txn)
|
||||
throws DbException, FormatException {
|
||||
Map<TransportId, LatestUpdate> latestUpdates = new HashMap<>();
|
||||
Map<MessageId, BdfDictionary> metadata = clientHelper
|
||||
.getMessageMetadataAsDictionary(txn, localGroup.getId());
|
||||
for (Entry<MessageId, BdfDictionary> e : metadata.entrySet()) {
|
||||
BdfDictionary meta = e.getValue();
|
||||
if (meta.getBoolean("local") == local) {
|
||||
TransportId t = new TransportId(meta.getString("transportId"));
|
||||
long version = meta.getLong("version");
|
||||
LatestUpdate latest = latestUpdates.get(t);
|
||||
if (latest == null || version > latest.version)
|
||||
latestUpdates.put(t, new LatestUpdate(e.getKey(), version));
|
||||
}
|
||||
TransportId t = new TransportId(meta.getString("transportId"));
|
||||
long version = meta.getLong("version");
|
||||
latestUpdates.put(t, new LatestUpdate(e.getKey(), version));
|
||||
}
|
||||
return latestUpdates;
|
||||
}
|
||||
@@ -300,19 +329,16 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
||||
@Nullable
|
||||
private LatestUpdate findLatest(Transaction txn, GroupId g, TransportId t,
|
||||
boolean local) throws DbException, FormatException {
|
||||
LatestUpdate latest = null;
|
||||
Map<MessageId, BdfDictionary> metadata =
|
||||
clientHelper.getMessageMetadataAsDictionary(txn, g);
|
||||
for (Entry<MessageId, BdfDictionary> e : metadata.entrySet()) {
|
||||
BdfDictionary meta = e.getValue();
|
||||
if (meta.getString("transportId").equals(t.getString())
|
||||
&& meta.getBoolean("local") == local) {
|
||||
long version = meta.getLong("version");
|
||||
if (latest == null || version > latest.version)
|
||||
latest = new LatestUpdate(e.getKey(), version);
|
||||
return new LatestUpdate(e.getKey(), meta.getLong("version"));
|
||||
}
|
||||
}
|
||||
return latest;
|
||||
return null;
|
||||
}
|
||||
|
||||
private TransportProperties parseProperties(BdfList message)
|
||||
|
||||
@@ -41,7 +41,7 @@ class Receiver implements ReadHandler {
|
||||
Receiver(Clock clock, Sender sender) {
|
||||
this.sender = sender;
|
||||
this.clock = clock;
|
||||
dataFrames = new TreeSet<Data>(new SequenceNumberComparator());
|
||||
dataFrames = new TreeSet<>(new SequenceNumberComparator());
|
||||
}
|
||||
|
||||
Data read() throws IOException, InterruptedException {
|
||||
|
||||
@@ -42,48 +42,44 @@ class ReliabilityLayerImpl implements ReliabilityLayer, WriteHandler {
|
||||
this.executor = executor;
|
||||
this.clock = clock;
|
||||
this.writeHandler = writeHandler;
|
||||
writes = new LinkedBlockingQueue<byte[]>();
|
||||
writes = new LinkedBlockingQueue<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
SlipEncoder encoder = new SlipEncoder(this);
|
||||
final Sender sender = new Sender(clock, encoder);
|
||||
Sender sender = new Sender(clock, encoder);
|
||||
receiver = new Receiver(clock, sender);
|
||||
decoder = new SlipDecoder(receiver, Data.MAX_LENGTH);
|
||||
inputStream = new ReceiverInputStream(receiver);
|
||||
outputStream = new SenderOutputStream(sender);
|
||||
running = true;
|
||||
executor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
long now = clock.currentTimeMillis();
|
||||
long next = now + TICK_INTERVAL;
|
||||
try {
|
||||
while (running) {
|
||||
byte[] b = null;
|
||||
while (now < next && b == null) {
|
||||
b = writes.poll(next - now, MILLISECONDS);
|
||||
if (!running) return;
|
||||
now = clock.currentTimeMillis();
|
||||
}
|
||||
if (b == null) {
|
||||
sender.tick();
|
||||
while (next <= now) next += TICK_INTERVAL;
|
||||
} else {
|
||||
if (b.length == 0) return; // Poison pill
|
||||
writeHandler.handleWrite(b);
|
||||
}
|
||||
executor.execute(() -> {
|
||||
long now = clock.currentTimeMillis();
|
||||
long next = now + TICK_INTERVAL;
|
||||
try {
|
||||
while (running) {
|
||||
byte[] b = null;
|
||||
while (now < next && b == null) {
|
||||
b = writes.poll(next - now, MILLISECONDS);
|
||||
if (!running) return;
|
||||
now = clock.currentTimeMillis();
|
||||
}
|
||||
if (b == null) {
|
||||
sender.tick();
|
||||
while (next <= now) next += TICK_INTERVAL;
|
||||
} else {
|
||||
if (b.length == 0) return; // Poison pill
|
||||
writeHandler.handleWrite(b);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
LOG.warning("Interrupted while waiting to write");
|
||||
Thread.currentThread().interrupt();
|
||||
running = false;
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, e.toString(), e);
|
||||
running = false;
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
LOG.warning("Interrupted while waiting to write");
|
||||
Thread.currentThread().interrupt();
|
||||
running = false;
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
running = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ class Sender {
|
||||
Sender(Clock clock, WriteHandler writeHandler) {
|
||||
this.clock = clock;
|
||||
this.writeHandler = writeHandler;
|
||||
outstanding = new LinkedList<Outstanding>();
|
||||
outstanding = new LinkedList<>();
|
||||
}
|
||||
|
||||
void sendAck(long sequenceNumber, int windowSize) throws IOException {
|
||||
@@ -136,7 +136,7 @@ class Sender {
|
||||
if (now - o.lastTransmitted > rto) {
|
||||
it.remove();
|
||||
if (retransmit == null)
|
||||
retransmit = new ArrayList<Outstanding>();
|
||||
retransmit = new ArrayList<>();
|
||||
retransmit.add(o);
|
||||
// Update the retransmission timeout
|
||||
rto <<= 1;
|
||||
|
||||
@@ -54,12 +54,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(DuplexOutgoingSession.class.getName());
|
||||
|
||||
private static final ThrowingRunnable<IOException> CLOSE =
|
||||
new ThrowingRunnable<IOException>() {
|
||||
@Override
|
||||
public void run() {
|
||||
}
|
||||
};
|
||||
private static final ThrowingRunnable<IOException> CLOSE = () -> {};
|
||||
|
||||
private final DatabaseComponent db;
|
||||
private final Executor dbExecutor;
|
||||
@@ -83,7 +78,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
|
||||
this.maxLatency = maxLatency;
|
||||
this.maxIdleTime = maxIdleTime;
|
||||
this.recordWriter = recordWriter;
|
||||
writerTasks = new LinkedBlockingQueue<ThrowingRunnable<IOException>>();
|
||||
writerTasks = new LinkedBlockingQueue<>();
|
||||
}
|
||||
|
||||
@IoExecutor
|
||||
|
||||
@@ -116,7 +116,7 @@ class RecordReaderImpl implements RecordReader {
|
||||
private List<MessageId> readMessageIds() throws IOException {
|
||||
if (payloadLength == 0) throw new FormatException();
|
||||
if (payloadLength % UniqueId.LENGTH != 0) throw new FormatException();
|
||||
List<MessageId> ids = new ArrayList<MessageId>();
|
||||
List<MessageId> ids = new ArrayList<>();
|
||||
for (int off = 0; off < payloadLength; off += UniqueId.LENGTH) {
|
||||
byte[] id = new byte[UniqueId.LENGTH];
|
||||
System.arraycopy(payload, off, id, 0, UniqueId.LENGTH);
|
||||
|
||||
@@ -43,12 +43,7 @@ class SimplexOutgoingSession implements SyncSession, EventListener {
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(SimplexOutgoingSession.class.getName());
|
||||
|
||||
private static final ThrowingRunnable<IOException> CLOSE =
|
||||
new ThrowingRunnable<IOException>() {
|
||||
@Override
|
||||
public void run() {
|
||||
}
|
||||
};
|
||||
private static final ThrowingRunnable<IOException> CLOSE = () -> {};
|
||||
|
||||
private final DatabaseComponent db;
|
||||
private final Executor dbExecutor;
|
||||
@@ -71,7 +66,7 @@ class SimplexOutgoingSession implements SyncSession, EventListener {
|
||||
this.maxLatency = maxLatency;
|
||||
this.recordWriter = recordWriter;
|
||||
outstandingQueries = new AtomicInteger(2); // One per type of record
|
||||
writerTasks = new LinkedBlockingQueue<ThrowingRunnable<IOException>>();
|
||||
writerTasks = new LinkedBlockingQueue<>();
|
||||
}
|
||||
|
||||
@IoExecutor
|
||||
|
||||
@@ -64,8 +64,8 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
||||
this.dbExecutor = dbExecutor;
|
||||
this.validationExecutor = validationExecutor;
|
||||
this.messageFactory = messageFactory;
|
||||
validators = new ConcurrentHashMap<ClientId, MessageValidator>();
|
||||
hooks = new ConcurrentHashMap<ClientId, IncomingMessageHook>();
|
||||
validators = new ConcurrentHashMap<>();
|
||||
hooks = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -93,19 +93,14 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
||||
hooks.put(c, hook);
|
||||
}
|
||||
|
||||
private void validateOutstandingMessagesAsync(final ClientId c) {
|
||||
dbExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
validateOutstandingMessages(c);
|
||||
}
|
||||
});
|
||||
private void validateOutstandingMessagesAsync(ClientId c) {
|
||||
dbExecutor.execute(() -> validateOutstandingMessages(c));
|
||||
}
|
||||
|
||||
@DatabaseExecutor
|
||||
private void validateOutstandingMessages(ClientId c) {
|
||||
try {
|
||||
Queue<MessageId> unvalidated = new LinkedList<MessageId>();
|
||||
Queue<MessageId> unvalidated = new LinkedList<>();
|
||||
Transaction txn = db.startTransaction(true);
|
||||
try {
|
||||
unvalidated.addAll(db.getMessagesToValidate(txn, c));
|
||||
@@ -119,14 +114,9 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
||||
}
|
||||
}
|
||||
|
||||
private void validateNextMessageAsync(final Queue<MessageId> unvalidated) {
|
||||
private void validateNextMessageAsync(Queue<MessageId> unvalidated) {
|
||||
if (unvalidated.isEmpty()) return;
|
||||
dbExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
validateNextMessage(unvalidated);
|
||||
}
|
||||
});
|
||||
dbExecutor.execute(() -> validateNextMessage(unvalidated));
|
||||
}
|
||||
|
||||
@DatabaseExecutor
|
||||
@@ -158,19 +148,14 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
||||
}
|
||||
}
|
||||
|
||||
private void deliverOutstandingMessagesAsync(final ClientId c) {
|
||||
dbExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
deliverOutstandingMessages(c);
|
||||
}
|
||||
});
|
||||
private void deliverOutstandingMessagesAsync(ClientId c) {
|
||||
dbExecutor.execute(() -> deliverOutstandingMessages(c));
|
||||
}
|
||||
|
||||
@DatabaseExecutor
|
||||
private void deliverOutstandingMessages(ClientId c) {
|
||||
try {
|
||||
Queue<MessageId> pending = new LinkedList<MessageId>();
|
||||
Queue<MessageId> pending = new LinkedList<>();
|
||||
Transaction txn = db.startTransaction(true);
|
||||
try {
|
||||
pending.addAll(db.getPendingMessages(txn, c));
|
||||
@@ -184,15 +169,9 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
||||
}
|
||||
}
|
||||
|
||||
private void deliverNextPendingMessageAsync(
|
||||
final Queue<MessageId> pending) {
|
||||
private void deliverNextPendingMessageAsync(Queue<MessageId> pending) {
|
||||
if (pending.isEmpty()) return;
|
||||
dbExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
deliverNextPendingMessage(pending);
|
||||
}
|
||||
});
|
||||
dbExecutor.execute(() -> deliverNextPendingMessage(pending));
|
||||
}
|
||||
|
||||
@DatabaseExecutor
|
||||
@@ -229,8 +208,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
||||
pending.addAll(getPendingDependents(txn, id));
|
||||
if (result.share) {
|
||||
db.setMessageShared(txn, id);
|
||||
toShare = new LinkedList<MessageId>(
|
||||
states.keySet());
|
||||
toShare = new LinkedList<>(states.keySet());
|
||||
}
|
||||
} else {
|
||||
invalidate = getDependentsToInvalidate(txn, id);
|
||||
@@ -255,13 +233,8 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
||||
}
|
||||
}
|
||||
|
||||
private void validateMessageAsync(final Message m, final Group g) {
|
||||
validationExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
validateMessage(m, g);
|
||||
}
|
||||
});
|
||||
private void validateMessageAsync(Message m, Group g) {
|
||||
validationExecutor.execute(() -> validateMessage(m, g));
|
||||
}
|
||||
|
||||
@ValidationExecutor
|
||||
@@ -277,21 +250,16 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
||||
} catch (InvalidMessageException e) {
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.log(INFO, e.toString(), e);
|
||||
Queue<MessageId> invalidate = new LinkedList<MessageId>();
|
||||
Queue<MessageId> invalidate = new LinkedList<>();
|
||||
invalidate.add(m.getId());
|
||||
invalidateNextMessageAsync(invalidate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void storeMessageContextAsync(final Message m, final ClientId c,
|
||||
final MessageContext result) {
|
||||
dbExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
storeMessageContext(m, c, result);
|
||||
}
|
||||
});
|
||||
private void storeMessageContextAsync(Message m, ClientId c,
|
||||
MessageContext result) {
|
||||
dbExecutor.execute(() -> storeMessageContext(m, c, result));
|
||||
}
|
||||
|
||||
@DatabaseExecutor
|
||||
@@ -331,8 +299,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
||||
pending = getPendingDependents(txn, id);
|
||||
if (result.share) {
|
||||
db.setMessageShared(txn, id);
|
||||
toShare =
|
||||
new LinkedList<MessageId>(dependencies);
|
||||
toShare = new LinkedList<>(dependencies);
|
||||
}
|
||||
} else {
|
||||
invalidate = getDependentsToInvalidate(txn, id);
|
||||
@@ -378,7 +345,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
||||
@DatabaseExecutor
|
||||
private Queue<MessageId> getPendingDependents(Transaction txn, MessageId m)
|
||||
throws DbException {
|
||||
Queue<MessageId> pending = new LinkedList<MessageId>();
|
||||
Queue<MessageId> pending = new LinkedList<>();
|
||||
Map<MessageId, State> states = db.getMessageDependents(txn, m);
|
||||
for (Entry<MessageId, State> e : states.entrySet()) {
|
||||
if (e.getValue() == PENDING) pending.add(e.getKey());
|
||||
@@ -386,19 +353,14 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
||||
return pending;
|
||||
}
|
||||
|
||||
private void shareOutstandingMessagesAsync(final ClientId c) {
|
||||
dbExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
shareOutstandingMessages(c);
|
||||
}
|
||||
});
|
||||
private void shareOutstandingMessagesAsync(ClientId c) {
|
||||
dbExecutor.execute(() -> shareOutstandingMessages(c));
|
||||
}
|
||||
|
||||
@DatabaseExecutor
|
||||
private void shareOutstandingMessages(ClientId c) {
|
||||
try {
|
||||
Queue<MessageId> toShare = new LinkedList<MessageId>();
|
||||
Queue<MessageId> toShare = new LinkedList<>();
|
||||
Transaction txn = db.startTransaction(true);
|
||||
try {
|
||||
toShare.addAll(db.getMessagesToShare(txn, c));
|
||||
@@ -418,14 +380,9 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
||||
* This method should only be called for messages that have all their
|
||||
* dependencies delivered and have been delivered themselves.
|
||||
*/
|
||||
private void shareNextMessageAsync(final Queue<MessageId> toShare) {
|
||||
private void shareNextMessageAsync(Queue<MessageId> toShare) {
|
||||
if (toShare.isEmpty()) return;
|
||||
dbExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
shareNextMessage(toShare);
|
||||
}
|
||||
});
|
||||
dbExecutor.execute(() -> shareNextMessage(toShare));
|
||||
}
|
||||
|
||||
@DatabaseExecutor
|
||||
@@ -452,14 +409,9 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
||||
}
|
||||
}
|
||||
|
||||
private void invalidateNextMessageAsync(final Queue<MessageId> invalidate) {
|
||||
private void invalidateNextMessageAsync(Queue<MessageId> invalidate) {
|
||||
if (invalidate.isEmpty()) return;
|
||||
dbExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
invalidateNextMessage(invalidate);
|
||||
}
|
||||
});
|
||||
dbExecutor.execute(() -> invalidateNextMessage(invalidate));
|
||||
}
|
||||
|
||||
@DatabaseExecutor
|
||||
@@ -496,7 +448,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
||||
@DatabaseExecutor
|
||||
private Queue<MessageId> getDependentsToInvalidate(Transaction txn,
|
||||
MessageId m) throws DbException {
|
||||
Queue<MessageId> invalidate = new LinkedList<MessageId>();
|
||||
Queue<MessageId> invalidate = new LinkedList<>();
|
||||
Map<MessageId, State> states = db.getMessageDependents(txn, m);
|
||||
for (Entry<MessageId, State> e : states.entrySet()) {
|
||||
if (e.getValue() != INVALID) invalidate.add(e.getKey());
|
||||
@@ -514,17 +466,12 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
||||
}
|
||||
}
|
||||
|
||||
private void loadGroupAndValidateAsync(final Message m) {
|
||||
dbExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
loadGroupAndValidate(m);
|
||||
}
|
||||
});
|
||||
private void loadGroupAndValidateAsync(Message m) {
|
||||
dbExecutor.execute(() -> loadGroupAndValidate(m));
|
||||
}
|
||||
|
||||
@DatabaseExecutor
|
||||
private void loadGroupAndValidate(final Message m) {
|
||||
private void loadGroupAndValidate(Message m) {
|
||||
try {
|
||||
Group g;
|
||||
Transaction txn = db.startTransaction(true);
|
||||
|
||||
@@ -58,15 +58,14 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
|
||||
this.pluginConfig = pluginConfig;
|
||||
this.transportKeyManagerFactory = transportKeyManagerFactory;
|
||||
// Use a ConcurrentHashMap as a thread-safe set
|
||||
activeContacts = new ConcurrentHashMap<ContactId, Boolean>();
|
||||
managers = new ConcurrentHashMap<TransportId, TransportKeyManager>();
|
||||
activeContacts = new ConcurrentHashMap<>();
|
||||
managers = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startService() throws ServiceException {
|
||||
if (used.getAndSet(true)) throw new IllegalStateException();
|
||||
Map<TransportId, Integer> transports =
|
||||
new HashMap<TransportId, Integer>();
|
||||
Map<TransportId, Integer> transports = new HashMap<>();
|
||||
for (SimplexPluginFactory f : pluginConfig.getSimplexFactories())
|
||||
transports.put(f.getId(), f.getMaxLatency());
|
||||
for (DuplexPluginFactory f : pluginConfig.getDuplexFactories())
|
||||
@@ -156,14 +155,10 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
|
||||
}
|
||||
}
|
||||
|
||||
private void removeContact(final ContactId c) {
|
||||
private void removeContact(ContactId c) {
|
||||
activeContacts.remove(c);
|
||||
dbExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (TransportKeyManager m : managers.values())
|
||||
m.removeContact(c);
|
||||
}
|
||||
dbExecutor.execute(() -> {
|
||||
for (TransportKeyManager m : managers.values()) m.removeContact(c);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ class ReorderingWindow {
|
||||
}
|
||||
|
||||
List<Long> getUnseen() {
|
||||
List<Long> unseen = new ArrayList<Long>(seen.length);
|
||||
List<Long> unseen = new ArrayList<>(seen.length);
|
||||
for (int i = 0; i < seen.length; i++)
|
||||
if (!seen[i]) unseen.add(base + i);
|
||||
return unseen;
|
||||
@@ -69,8 +69,8 @@ class ReorderingWindow {
|
||||
return new Change(added, removed);
|
||||
}
|
||||
// Record the elements that will be added and removed
|
||||
List<Long> added = new ArrayList<Long>(slide);
|
||||
List<Long> removed = new ArrayList<Long>(slide);
|
||||
List<Long> added = new ArrayList<>(slide);
|
||||
List<Long> removed = new ArrayList<>(slide);
|
||||
for (int i = 0; i < slide; i++) {
|
||||
if (!seen[i]) removed.add(base + i);
|
||||
added.add(base + seen.length + i);
|
||||
|
||||
@@ -65,9 +65,9 @@ class TransportKeyManagerImpl implements TransportKeyManager {
|
||||
this.transportId = transportId;
|
||||
rotationPeriodLength = maxLatency + MAX_CLOCK_DIFFERENCE;
|
||||
lock = new ReentrantLock();
|
||||
inContexts = new HashMap<Bytes, TagContext>();
|
||||
outContexts = new HashMap<ContactId, MutableOutgoingKeys>();
|
||||
keys = new HashMap<ContactId, MutableTransportKeys>();
|
||||
inContexts = new HashMap<>();
|
||||
outContexts = new HashMap<>();
|
||||
keys = new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -134,32 +134,22 @@ class TransportKeyManagerImpl implements TransportKeyManager {
|
||||
}
|
||||
|
||||
private void scheduleKeyRotation(long now) {
|
||||
Runnable task = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
rotateKeys();
|
||||
}
|
||||
};
|
||||
long delay = rotationPeriodLength - now % rotationPeriodLength;
|
||||
scheduler.schedule(task, delay, MILLISECONDS);
|
||||
scheduler.schedule((Runnable) this::rotateKeys, delay, MILLISECONDS);
|
||||
}
|
||||
|
||||
private void rotateKeys() {
|
||||
dbExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
dbExecutor.execute(() -> {
|
||||
try {
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
rotateKeys(txn);
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, e.toString(), e);
|
||||
rotateKeys(txn);
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -272,8 +262,7 @@ class TransportKeyManagerImpl implements TransportKeyManager {
|
||||
lock.lock();
|
||||
try {
|
||||
// Rotate the keys to the current rotation period
|
||||
Map<ContactId, TransportKeys> snapshot =
|
||||
new HashMap<ContactId, TransportKeys>();
|
||||
Map<ContactId, TransportKeys> snapshot = new HashMap<>();
|
||||
for (Entry<ContactId, MutableTransportKeys> e : keys.entrySet())
|
||||
snapshot.put(e.getKey(), e.getValue().snapshot());
|
||||
RotationResult rotationResult = rotateKeys(snapshot, now);
|
||||
@@ -311,8 +300,8 @@ class TransportKeyManagerImpl implements TransportKeyManager {
|
||||
private final Map<ContactId, TransportKeys> current, rotated;
|
||||
|
||||
private RotationResult() {
|
||||
current = new HashMap<ContactId, TransportKeys>();
|
||||
rotated = new HashMap<ContactId, TransportKeys>();
|
||||
current = new HashMap<>();
|
||||
rotated = new HashMap<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,16 +24,13 @@ public class PoliteExecutorTest extends BrambleTestCase {
|
||||
Executor delegate = Executors.newSingleThreadExecutor();
|
||||
// Allow all the tasks to be delegated straight away
|
||||
PoliteExecutor polite = new PoliteExecutor(TAG, delegate, TASKS * 2);
|
||||
final List<Integer> list = new Vector<Integer>();
|
||||
final CountDownLatch latch = new CountDownLatch(TASKS);
|
||||
List<Integer> list = new Vector<>();
|
||||
CountDownLatch latch = new CountDownLatch(TASKS);
|
||||
for (int i = 0; i < TASKS; i++) {
|
||||
final int result = i;
|
||||
polite.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
list.add(result);
|
||||
latch.countDown();
|
||||
}
|
||||
int result = i;
|
||||
polite.execute(() -> {
|
||||
list.add(result);
|
||||
latch.countDown();
|
||||
});
|
||||
}
|
||||
// Wait for all the tasks to finish
|
||||
@@ -49,16 +46,13 @@ public class PoliteExecutorTest extends BrambleTestCase {
|
||||
Executor delegate = Executors.newSingleThreadExecutor();
|
||||
// Allow two tasks to be delegated at a time
|
||||
PoliteExecutor polite = new PoliteExecutor(TAG, delegate, 2);
|
||||
final List<Integer> list = new Vector<Integer>();
|
||||
final CountDownLatch latch = new CountDownLatch(TASKS);
|
||||
List<Integer> list = new Vector<>();
|
||||
CountDownLatch latch = new CountDownLatch(TASKS);
|
||||
for (int i = 0; i < TASKS; i++) {
|
||||
final int result = i;
|
||||
polite.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
list.add(result);
|
||||
latch.countDown();
|
||||
}
|
||||
int result = i;
|
||||
polite.execute(() -> {
|
||||
list.add(result);
|
||||
latch.countDown();
|
||||
});
|
||||
}
|
||||
// Wait for all the tasks to finish
|
||||
@@ -73,23 +67,20 @@ public class PoliteExecutorTest extends BrambleTestCase {
|
||||
Executor delegate = Executors.newCachedThreadPool();
|
||||
// Allow all the tasks to be delegated straight away
|
||||
PoliteExecutor polite = new PoliteExecutor(TAG, delegate, TASKS * 2);
|
||||
final List<Integer> list = new Vector<Integer>();
|
||||
final CountDownLatch[] latches = new CountDownLatch[TASKS];
|
||||
List<Integer> list = new Vector<>();
|
||||
CountDownLatch[] latches = new CountDownLatch[TASKS];
|
||||
for (int i = 0; i < TASKS; i++) latches[i] = new CountDownLatch(1);
|
||||
for (int i = 0; i < TASKS; i++) {
|
||||
final int result = i;
|
||||
polite.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
// Each task waits for the next task, if any, to finish
|
||||
if (result < TASKS - 1) latches[result + 1].await();
|
||||
list.add(result);
|
||||
} catch (InterruptedException e) {
|
||||
fail();
|
||||
}
|
||||
latches[result].countDown();
|
||||
int result = i;
|
||||
polite.execute(() -> {
|
||||
try {
|
||||
// Each task waits for the next task, if any, to finish
|
||||
if (result < TASKS - 1) latches[result + 1].await();
|
||||
list.add(result);
|
||||
} catch (InterruptedException e) {
|
||||
fail();
|
||||
}
|
||||
latches[result].countDown();
|
||||
});
|
||||
}
|
||||
// Wait for all the tasks to finish
|
||||
@@ -104,22 +95,19 @@ public class PoliteExecutorTest extends BrambleTestCase {
|
||||
Executor delegate = Executors.newCachedThreadPool();
|
||||
// Allow one task to be delegated at a time
|
||||
PoliteExecutor polite = new PoliteExecutor(TAG, delegate, 1);
|
||||
final List<Integer> list = new Vector<Integer>();
|
||||
final CountDownLatch latch = new CountDownLatch(TASKS);
|
||||
List<Integer> list = new Vector<>();
|
||||
CountDownLatch latch = new CountDownLatch(TASKS);
|
||||
for (int i = 0; i < TASKS; i++) {
|
||||
final int result = i;
|
||||
polite.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
// Each task runs faster than the previous task
|
||||
Thread.sleep(TASKS - result);
|
||||
list.add(result);
|
||||
} catch (InterruptedException e) {
|
||||
fail();
|
||||
}
|
||||
latch.countDown();
|
||||
int result = i;
|
||||
polite.execute(() -> {
|
||||
try {
|
||||
// Each task runs faster than the previous task
|
||||
Thread.sleep(TASKS - result);
|
||||
list.add(result);
|
||||
} catch (InterruptedException e) {
|
||||
fail();
|
||||
}
|
||||
latch.countDown();
|
||||
});
|
||||
}
|
||||
// Wait for all the tasks to finish
|
||||
|
||||
@@ -83,9 +83,9 @@ public class BdfMessageValidatorTest extends ValidatorTestCase {
|
||||
|
||||
@Test(expected = InvalidMessageException.class)
|
||||
public void testRejectsTooShortMessage() throws Exception {
|
||||
final byte[] invalidRaw = new byte[MESSAGE_HEADER_LENGTH];
|
||||
byte[] invalidRaw = new byte[MESSAGE_HEADER_LENGTH];
|
||||
// Use a mock message so the length of the raw message can be invalid
|
||||
final Message invalidMessage = context.mock(Message.class);
|
||||
Message invalidMessage = context.mock(Message.class);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(invalidMessage).getTimestamp();
|
||||
@@ -101,8 +101,8 @@ public class BdfMessageValidatorTest extends ValidatorTestCase {
|
||||
|
||||
@Test
|
||||
public void testAcceptsMinLengthMessage() throws Exception {
|
||||
final byte[] shortRaw = new byte[MESSAGE_HEADER_LENGTH + 1];
|
||||
final Message shortMessage =
|
||||
byte[] shortRaw = new byte[MESSAGE_HEADER_LENGTH + 1];
|
||||
Message shortMessage =
|
||||
new Message(messageId, groupId, timestamp, shortRaw);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
|
||||
@@ -76,8 +76,8 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testAddLocalMessage() throws Exception {
|
||||
final boolean shared = true;
|
||||
final Transaction txn = new Transaction(null, false);
|
||||
boolean shared = true;
|
||||
Transaction txn = new Transaction(null, false);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(false);
|
||||
@@ -95,7 +95,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testCreateMessage() throws Exception {
|
||||
final byte[] bytes = expectToByteArray(list);
|
||||
byte[] bytes = expectToByteArray(list);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(messageFactory).createMessage(groupId, timestamp, bytes);
|
||||
@@ -107,7 +107,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testGetMessageAsList() throws Exception {
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
Transaction txn = new Transaction(null, true);
|
||||
|
||||
expectToList(true);
|
||||
context.checking(new Expectations() {{
|
||||
@@ -125,7 +125,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testGetGroupMetadataAsDictionary() throws Exception {
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
Transaction txn = new Transaction(null, true);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(true);
|
||||
@@ -145,7 +145,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testGetMessageMetadataAsDictionary() throws Exception {
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
Transaction txn = new Transaction(null, true);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(true);
|
||||
@@ -165,10 +165,9 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testGetMessageMetadataAsDictionaryMap() throws Exception {
|
||||
final Map<MessageId, BdfDictionary> map =
|
||||
new HashMap<MessageId, BdfDictionary>();
|
||||
Map<MessageId, BdfDictionary> map = new HashMap<>();
|
||||
map.put(messageId, dictionary);
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
Transaction txn = new Transaction(null, true);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(true);
|
||||
@@ -188,14 +187,13 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testGetMessageMetadataAsDictionaryQuery() throws Exception {
|
||||
final Map<MessageId, BdfDictionary> map =
|
||||
new HashMap<MessageId, BdfDictionary>();
|
||||
Map<MessageId, BdfDictionary> map = new HashMap<>();
|
||||
map.put(messageId, dictionary);
|
||||
final BdfDictionary query =
|
||||
BdfDictionary query =
|
||||
BdfDictionary.of(new BdfEntry("query", "me"));
|
||||
final Metadata queryMetadata = new Metadata();
|
||||
Metadata queryMetadata = new Metadata();
|
||||
queryMetadata.put("query", getRandomBytes(42));
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
Transaction txn = new Transaction(null, true);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(true);
|
||||
@@ -217,7 +215,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testMergeGroupMetadata() throws Exception {
|
||||
final Transaction txn = new Transaction(null, false);
|
||||
Transaction txn = new Transaction(null, false);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(false);
|
||||
@@ -235,7 +233,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testMergeMessageMetadata() throws Exception {
|
||||
final Transaction txn = new Transaction(null, false);
|
||||
Transaction txn = new Transaction(null, false);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(false);
|
||||
@@ -282,10 +280,10 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testSign() throws Exception {
|
||||
final byte[] privateKey = getRandomBytes(42);
|
||||
final byte[] signed = getRandomBytes(42);
|
||||
byte[] privateKey = getRandomBytes(42);
|
||||
byte[] signed = getRandomBytes(42);
|
||||
|
||||
final byte[] bytes = expectToByteArray(list);
|
||||
byte[] bytes = expectToByteArray(list);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(cryptoComponent).sign(label, bytes, privateKey);
|
||||
will(returnValue(signed));
|
||||
@@ -297,8 +295,8 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testVerifySignature() throws Exception {
|
||||
final byte[] publicKey = getRandomBytes(42);
|
||||
final byte[] bytes = expectToByteArray(list);
|
||||
byte[] publicKey = getRandomBytes(42);
|
||||
byte[] bytes = expectToByteArray(list);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(cryptoComponent).verify(label, bytes, publicKey, rawMessage);
|
||||
@@ -311,8 +309,8 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testVerifyWrongSignature() throws Exception {
|
||||
final byte[] publicKey = getRandomBytes(42);
|
||||
final byte[] bytes = expectToByteArray(list);
|
||||
byte[] publicKey = getRandomBytes(42);
|
||||
byte[] bytes = expectToByteArray(list);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(cryptoComponent).verify(label, bytes, publicKey, rawMessage);
|
||||
@@ -329,8 +327,8 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] expectToByteArray(final BdfList list) throws Exception {
|
||||
final BdfWriter bdfWriter = context.mock(BdfWriter.class);
|
||||
private byte[] expectToByteArray(BdfList list) throws Exception {
|
||||
BdfWriter bdfWriter = context.mock(BdfWriter.class);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(bdfWriterFactory)
|
||||
@@ -341,8 +339,8 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
private void expectToList(final boolean eof) throws Exception {
|
||||
final BdfReader bdfReader = context.mock(BdfReader.class);
|
||||
private void expectToList(boolean eof) throws Exception {
|
||||
BdfReader bdfReader = context.mock(BdfReader.class);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(bdfReaderFactory)
|
||||
|
||||
@@ -46,10 +46,10 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
||||
|
||||
@Test
|
||||
public void testAddContact() throws Exception {
|
||||
final SecretKey master = getSecretKey();
|
||||
final long timestamp = 42;
|
||||
final boolean alice = true;
|
||||
final Transaction txn = new Transaction(null, false);
|
||||
SecretKey master = getSecretKey();
|
||||
long timestamp = 42;
|
||||
boolean alice = true;
|
||||
Transaction txn = new Transaction(null, false);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(false);
|
||||
@@ -64,14 +64,13 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
assertEquals(contactId, contactManager
|
||||
.addContact(remote, local, master, timestamp, alice, verified,
|
||||
active));
|
||||
assertEquals(contactId, contactManager.addContact(remote, local,
|
||||
master, timestamp, alice, verified, active));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetContact() throws Exception {
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
Transaction txn = new Transaction(null, true);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
@@ -86,8 +85,8 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
||||
|
||||
@Test
|
||||
public void testGetContactByAuthor() throws Exception {
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
final Collection<Contact> contacts = Collections.singleton(contact);
|
||||
Transaction txn = new Transaction(null, true);
|
||||
Collection<Contact> contacts = Collections.singleton(contact);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
@@ -102,7 +101,7 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
||||
|
||||
@Test(expected = NoSuchContactException.class)
|
||||
public void testGetContactByUnknownAuthor() throws Exception {
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
Transaction txn = new Transaction(null, true);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
@@ -116,8 +115,8 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
||||
|
||||
@Test(expected = NoSuchContactException.class)
|
||||
public void testGetContactByUnknownLocalAuthor() throws Exception {
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
final Collection<Contact> contacts = Collections.singleton(contact);
|
||||
Transaction txn = new Transaction(null, true);
|
||||
Collection<Contact> contacts = Collections.singleton(contact);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
@@ -132,10 +131,9 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
||||
@Test
|
||||
public void testActiveContacts() throws Exception {
|
||||
Collection<Contact> activeContacts = Collections.singletonList(contact);
|
||||
final Collection<Contact> contacts =
|
||||
new ArrayList<Contact>(activeContacts);
|
||||
Collection<Contact> contacts = new ArrayList<>(activeContacts);
|
||||
contacts.add(new Contact(new ContactId(3), remote, local, true, false));
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
Transaction txn = new Transaction(null, true);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
@@ -150,7 +148,7 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
||||
|
||||
@Test
|
||||
public void testRemoveContact() throws Exception {
|
||||
final Transaction txn = new Transaction(null, false);
|
||||
Transaction txn = new Transaction(null, false);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn));
|
||||
@@ -166,7 +164,7 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
||||
|
||||
@Test
|
||||
public void testSetContactActive() throws Exception {
|
||||
final Transaction txn = new Transaction(null, false);
|
||||
Transaction txn = new Transaction(null, false);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).setContactActive(txn, contactId, active);
|
||||
}});
|
||||
@@ -176,7 +174,7 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
||||
|
||||
@Test
|
||||
public void testContactExists() throws Exception {
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
Transaction txn = new Transaction(null, true);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.briarproject.bramble.crypto;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.KeyPair;
|
||||
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
public class EcdsaSignatureTest extends SignatureTest {
|
||||
|
||||
@Override
|
||||
protected KeyPair generateKeyPair() {
|
||||
return crypto.generateSignatureKeyPair();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected byte[] sign(String label, byte[] toSign, byte[] privateKey)
|
||||
throws GeneralSecurityException {
|
||||
return crypto.sign(label, toSign, privateKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean verify(String label, byte[] signedData, byte[] publicKey,
|
||||
byte[] signature) throws GeneralSecurityException {
|
||||
return crypto.verify(label, signedData, publicKey, signature);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.briarproject.bramble.crypto;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.KeyPair;
|
||||
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
public class EdSignatureTest extends SignatureTest {
|
||||
|
||||
@Override
|
||||
protected KeyPair generateKeyPair() {
|
||||
return crypto.generateEdKeyPair();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected byte[] sign(String label, byte[] toSign, byte[] privateKey)
|
||||
throws GeneralSecurityException {
|
||||
return crypto.signEd(label, toSign, privateKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean verify(String label, byte[] signedData, byte[] publicKey,
|
||||
byte[] signature) throws GeneralSecurityException {
|
||||
return crypto.verifyEd(label, signedData, publicKey, signature);
|
||||
}
|
||||
}
|
||||
@@ -69,7 +69,7 @@ public class EllipticCurvePerformanceTest {
|
||||
ECPublicKeyParameters public2 =
|
||||
(ECPublicKeyParameters) keyPair2.getPublic();
|
||||
// Time some ECDH key agreements
|
||||
List<Long> samples = new ArrayList<Long>();
|
||||
List<Long> samples = new ArrayList<>();
|
||||
for (int i = 0; i < SAMPLES; i++) {
|
||||
ECDHCBasicAgreement agreement = new ECDHCBasicAgreement();
|
||||
long start = System.nanoTime();
|
||||
@@ -79,7 +79,7 @@ public class EllipticCurvePerformanceTest {
|
||||
}
|
||||
long agreementMedian = median(samples);
|
||||
// Time some signatures
|
||||
List<byte[]> signatures = new ArrayList<byte[]>();
|
||||
List<byte[]> signatures = new ArrayList<>();
|
||||
samples.clear();
|
||||
for (int i = 0; i < SAMPLES; i++) {
|
||||
Digest digest = new Blake2sDigest();
|
||||
|
||||
@@ -145,7 +145,7 @@ public class KeyDerivationTest extends BrambleTestCase {
|
||||
}
|
||||
|
||||
private void assertAllDifferent(TransportKeys... transportKeys) {
|
||||
List<SecretKey> secretKeys = new ArrayList<SecretKey>();
|
||||
List<SecretKey> secretKeys = new ArrayList<>();
|
||||
for (TransportKeys k : transportKeys) {
|
||||
secretKeys.add(k.getPreviousIncomingKeys().getTagKey());
|
||||
secretKeys.add(k.getPreviousIncomingKeys().getHeaderKey());
|
||||
@@ -160,7 +160,7 @@ public class KeyDerivationTest extends BrambleTestCase {
|
||||
}
|
||||
|
||||
private void assertAllDifferent(List<SecretKey> keys) {
|
||||
Set<Bytes> set = new HashSet<Bytes>();
|
||||
Set<Bytes> set = new HashSet<>();
|
||||
for (SecretKey k : keys) assertTrue(set.add(new Bytes(k.getBytes())));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,23 +8,32 @@ import org.briarproject.bramble.test.TestUtils;
|
||||
import org.briarproject.bramble.util.StringUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class SignatureTest extends BrambleTestCase {
|
||||
public abstract class SignatureTest extends BrambleTestCase {
|
||||
|
||||
private final CryptoComponent crypto;
|
||||
protected final CryptoComponent crypto;
|
||||
|
||||
private final byte[] publicKey, privateKey;
|
||||
private final String label = StringUtils.getRandomString(42);
|
||||
private final byte[] inputBytes = TestUtils.getRandomBytes(123);
|
||||
|
||||
public SignatureTest() {
|
||||
protected abstract KeyPair generateKeyPair();
|
||||
|
||||
protected abstract byte[] sign(String label, byte[] toSign,
|
||||
byte[] privateKey) throws GeneralSecurityException;
|
||||
|
||||
protected abstract boolean verify(String label, byte[] signedData,
|
||||
byte[] publicKey, byte[] signature) throws GeneralSecurityException;
|
||||
|
||||
SignatureTest() {
|
||||
crypto = new CryptoComponentImpl(new TestSecureRandomProvider());
|
||||
KeyPair k = crypto.generateSignatureKeyPair();
|
||||
KeyPair k = generateKeyPair();
|
||||
publicKey = k.getPublic().getEncoded();
|
||||
privateKey = k.getPrivate().getEncoded();
|
||||
}
|
||||
@@ -33,19 +42,19 @@ public class SignatureTest extends BrambleTestCase {
|
||||
public void testIdenticalKeysAndInputsProduceIdenticalSignatures()
|
||||
throws Exception {
|
||||
// Calculate the Signature twice - the results should be identical
|
||||
byte[] sig1 = crypto.sign(label, inputBytes, privateKey);
|
||||
byte[] sig2 = crypto.sign(label, inputBytes, privateKey);
|
||||
byte[] sig1 = sign(label, inputBytes, privateKey);
|
||||
byte[] sig2 = sign(label, inputBytes, privateKey);
|
||||
assertArrayEquals(sig1, sig2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDifferentKeysProduceDifferentSignatures() throws Exception {
|
||||
// Generate second private key
|
||||
KeyPair k2 = crypto.generateSignatureKeyPair();
|
||||
KeyPair k2 = generateKeyPair();
|
||||
byte[] privateKey2 = k2.getPrivate().getEncoded();
|
||||
// Calculate the signature with each key
|
||||
byte[] sig1 = crypto.sign(label, inputBytes, privateKey);
|
||||
byte[] sig2 = crypto.sign(label, inputBytes, privateKey2);
|
||||
byte[] sig1 = sign(label, inputBytes, privateKey);
|
||||
byte[] sig2 = sign(label, inputBytes, privateKey2);
|
||||
assertFalse(Arrays.equals(sig1, sig2));
|
||||
}
|
||||
|
||||
@@ -56,8 +65,8 @@ public class SignatureTest extends BrambleTestCase {
|
||||
byte[] inputBytes2 = TestUtils.getRandomBytes(123);
|
||||
// Calculate the signature with different inputs
|
||||
// the results should be different
|
||||
byte[] sig1 = crypto.sign(label, inputBytes, privateKey);
|
||||
byte[] sig2 = crypto.sign(label, inputBytes2, privateKey);
|
||||
byte[] sig1 = sign(label, inputBytes, privateKey);
|
||||
byte[] sig2 = sign(label, inputBytes2, privateKey);
|
||||
assertFalse(Arrays.equals(sig1, sig2));
|
||||
}
|
||||
|
||||
@@ -68,25 +77,25 @@ public class SignatureTest extends BrambleTestCase {
|
||||
String label2 = StringUtils.getRandomString(42);
|
||||
// Calculate the signature with different inputs
|
||||
// the results should be different
|
||||
byte[] sig1 = crypto.sign(label, inputBytes, privateKey);
|
||||
byte[] sig2 = crypto.sign(label2, inputBytes, privateKey);
|
||||
byte[] sig1 = sign(label, inputBytes, privateKey);
|
||||
byte[] sig2 = sign(label2, inputBytes, privateKey);
|
||||
assertFalse(Arrays.equals(sig1, sig2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSignatureVerification() throws Exception {
|
||||
byte[] sig = crypto.sign(label, inputBytes, privateKey);
|
||||
assertTrue(crypto.verify(label, inputBytes, publicKey, sig));
|
||||
byte[] sig = sign(label, inputBytes, privateKey);
|
||||
assertTrue(verify(label, inputBytes, publicKey, sig));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDifferentKeyFailsVerification() throws Exception {
|
||||
// Generate second private key
|
||||
KeyPair k2 = crypto.generateSignatureKeyPair();
|
||||
KeyPair k2 = generateKeyPair();
|
||||
byte[] privateKey2 = k2.getPrivate().getEncoded();
|
||||
// calculate the signature with different key, should fail to verify
|
||||
byte[] sig = crypto.sign(label, inputBytes, privateKey2);
|
||||
assertFalse(crypto.verify(label, inputBytes, publicKey, sig));
|
||||
byte[] sig = sign(label, inputBytes, privateKey2);
|
||||
assertFalse(verify(label, inputBytes, publicKey, sig));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -94,8 +103,8 @@ public class SignatureTest extends BrambleTestCase {
|
||||
// Generate a second input
|
||||
byte[] inputBytes2 = TestUtils.getRandomBytes(123);
|
||||
// calculate the signature with different input, should fail to verify
|
||||
byte[] sig = crypto.sign(label, inputBytes, privateKey);
|
||||
assertFalse(crypto.verify(label, inputBytes2, publicKey, sig));
|
||||
byte[] sig = sign(label, inputBytes, privateKey);
|
||||
assertFalse(verify(label, inputBytes2, publicKey, sig));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -103,8 +112,8 @@ public class SignatureTest extends BrambleTestCase {
|
||||
// Generate a second label
|
||||
String label2 = StringUtils.getRandomString(42);
|
||||
// calculate the signature with different label, should fail to verify
|
||||
byte[] sig = crypto.sign(label, inputBytes, privateKey);
|
||||
assertFalse(crypto.verify(label2, inputBytes, publicKey, sig));
|
||||
byte[] sig = sign(label, inputBytes, privateKey);
|
||||
assertFalse(verify(label2, inputBytes, publicKey, sig));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ public class TagEncodingTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testKeyAffectsTag() throws Exception {
|
||||
Set<Bytes> set = new HashSet<Bytes>();
|
||||
Set<Bytes> set = new HashSet<>();
|
||||
for (int i = 0; i < 100; i++) {
|
||||
byte[] tag = new byte[TAG_LENGTH];
|
||||
SecretKey tagKey = TestUtils.getSecretKey();
|
||||
@@ -39,7 +39,7 @@ public class TagEncodingTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testProtocolVersionAffectsTag() throws Exception {
|
||||
Set<Bytes> set = new HashSet<Bytes>();
|
||||
Set<Bytes> set = new HashSet<>();
|
||||
for (int i = 0; i < 100; i++) {
|
||||
byte[] tag = new byte[TAG_LENGTH];
|
||||
crypto.encodeTag(tag, tagKey, PROTOCOL_VERSION + i, streamNumber);
|
||||
@@ -49,7 +49,7 @@ public class TagEncodingTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testStreamNumberAffectsTag() throws Exception {
|
||||
Set<Bytes> set = new HashSet<Bytes>();
|
||||
Set<Bytes> set = new HashSet<>();
|
||||
for (int i = 0; i < 100; i++) {
|
||||
byte[] tag = new byte[TAG_LENGTH];
|
||||
crypto.encodeTag(tag, tagKey, PROTOCOL_VERSION, streamNumber + i);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package org.briarproject.bramble.data;
|
||||
|
||||
import org.briarproject.bramble.test.BrambleTestCase;
|
||||
import org.briarproject.bramble.test.TestUtils;
|
||||
import org.briarproject.bramble.util.StringUtils;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -155,7 +154,7 @@ public class BdfWriterImplTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testWriteList() throws IOException {
|
||||
List<Object> l = new ArrayList<Object>();
|
||||
List<Object> l = new ArrayList<>();
|
||||
for (int i = 0; i < 3; i++) l.add(i);
|
||||
w.writeList(l);
|
||||
// LIST tag, elements as integers, END tag
|
||||
@@ -164,7 +163,7 @@ public class BdfWriterImplTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testListCanContainNull() throws IOException {
|
||||
List<Object> l = new ArrayList<Object>();
|
||||
List<Object> l = new ArrayList<>();
|
||||
l.add(1);
|
||||
l.add(null);
|
||||
l.add(NULL_VALUE);
|
||||
@@ -177,7 +176,7 @@ public class BdfWriterImplTest extends BrambleTestCase {
|
||||
@Test
|
||||
public void testWriteDictionary() throws IOException {
|
||||
// Use LinkedHashMap to get predictable iteration order
|
||||
Map<String, Object> m = new LinkedHashMap<String, Object>();
|
||||
Map<String, Object> m = new LinkedHashMap<>();
|
||||
for (int i = 0; i < 4; i++) m.put(String.valueOf(i), i);
|
||||
w.writeDictionary(m);
|
||||
// DICTIONARY tag, keys as strings and values as integers, END tag
|
||||
@@ -216,12 +215,12 @@ public class BdfWriterImplTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testWriteNestedDictionariesAndLists() throws IOException {
|
||||
Map<String, Object> inner = new LinkedHashMap<String, Object>();
|
||||
Map<String, Object> inner = new LinkedHashMap<>();
|
||||
inner.put("bar", new byte[0]);
|
||||
List<Object> list = new ArrayList<Object>();
|
||||
List<Object> list = new ArrayList<>();
|
||||
list.add(1);
|
||||
list.add(inner);
|
||||
Map<String, Object> outer = new LinkedHashMap<String, Object>();
|
||||
Map<String, Object> outer = new LinkedHashMap<>();
|
||||
outer.put("foo", list);
|
||||
w.writeDictionary(outer);
|
||||
// DICTIONARY tag, "foo" as string, LIST tag, 1 as integer,
|
||||
|
||||
@@ -99,7 +99,7 @@ public class MetadataEncoderParserIntegrationTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testList() throws FormatException {
|
||||
List<Long> l = new ArrayList<Long>(4);
|
||||
List<Long> l = new ArrayList<>(4);
|
||||
l.add(42L);
|
||||
l.add(1337L);
|
||||
l.add(Long.MIN_VALUE);
|
||||
@@ -114,7 +114,7 @@ public class MetadataEncoderParserIntegrationTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testDictionary() throws FormatException {
|
||||
Map<String, Boolean> m = new HashMap<String, Boolean>();
|
||||
Map<String, Boolean> m = new HashMap<>();
|
||||
m.put("1", true);
|
||||
m.put("2", false);
|
||||
|
||||
@@ -130,19 +130,19 @@ public class MetadataEncoderParserIntegrationTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testComplexDictionary() throws FormatException {
|
||||
Map<String, List> m = new HashMap<String, List>();
|
||||
List<String> one = new ArrayList<String>(3);
|
||||
Map<String, List> m = new HashMap<>();
|
||||
List<String> one = new ArrayList<>(3);
|
||||
one.add("\uFDD0");
|
||||
one.add("\uFDD1");
|
||||
one.add("\uFDD2");
|
||||
m.put("One", one);
|
||||
List<String> two = new ArrayList<String>(2);
|
||||
List<String> two = new ArrayList<>(2);
|
||||
two.add("\u0080");
|
||||
two.add("\uD800\uDC00");
|
||||
m.put("Two", two);
|
||||
d.put("test", m);
|
||||
|
||||
Map<String, Boolean> m2 = new HashMap<String, Boolean>();
|
||||
Map<String, Boolean> m2 = new HashMap<>();
|
||||
m2.put("should be true", true);
|
||||
d.put("another test", m2);
|
||||
|
||||
|
||||
@@ -323,7 +323,7 @@ public class BasicH2Test extends BrambleTestCase {
|
||||
|
||||
private List<String> getNames() throws SQLException {
|
||||
String sql = "SELECT name FROM foo ORDER BY uniqueId";
|
||||
List<String> names = new ArrayList<String>();
|
||||
List<String> names = new ArrayList<>();
|
||||
try {
|
||||
PreparedStatement ps = connection.prepareStatement(sql);
|
||||
ResultSet rs = ps.executeQuery();
|
||||
|
||||
@@ -120,18 +120,18 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
|
||||
|
||||
private DatabaseComponent createDatabaseComponent(Database<Object> database,
|
||||
EventBus eventBus, ShutdownManager shutdown) {
|
||||
return new DatabaseComponentImpl<Object>(database, Object.class,
|
||||
eventBus, shutdown);
|
||||
return new DatabaseComponentImpl<>(database, Object.class, eventBus,
|
||||
shutdown);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testSimpleCalls() throws Exception {
|
||||
final int shutdownHandle = 12345;
|
||||
int shutdownHandle = 12345;
|
||||
Mockery context = new Mockery();
|
||||
final Database<Object> database = context.mock(Database.class);
|
||||
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
final EventBus eventBus = context.mock(EventBus.class);
|
||||
Database<Object> database = context.mock(Database.class);
|
||||
ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
EventBus eventBus = context.mock(EventBus.class);
|
||||
context.checking(new Expectations() {{
|
||||
// open()
|
||||
oneOf(database).open();
|
||||
@@ -230,9 +230,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
|
||||
throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
@SuppressWarnings("unchecked")
|
||||
final Database<Object> database = context.mock(Database.class);
|
||||
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
final EventBus eventBus = context.mock(EventBus.class);
|
||||
Database<Object> database = context.mock(Database.class);
|
||||
ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
EventBus eventBus = context.mock(EventBus.class);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(database).startTransaction();
|
||||
will(returnValue(txn));
|
||||
@@ -260,9 +260,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
|
||||
public void testAddLocalMessage() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
@SuppressWarnings("unchecked")
|
||||
final Database<Object> database = context.mock(Database.class);
|
||||
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
final EventBus eventBus = context.mock(EventBus.class);
|
||||
Database<Object> database = context.mock(Database.class);
|
||||
ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
EventBus eventBus = context.mock(EventBus.class);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(database).startTransaction();
|
||||
will(returnValue(txn));
|
||||
@@ -303,9 +303,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
|
||||
throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
@SuppressWarnings("unchecked")
|
||||
final Database<Object> database = context.mock(Database.class);
|
||||
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
final EventBus eventBus = context.mock(EventBus.class);
|
||||
Database<Object> database = context.mock(Database.class);
|
||||
ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
EventBus eventBus = context.mock(EventBus.class);
|
||||
context.checking(new Expectations() {{
|
||||
// Check whether the contact is in the DB (which it's not)
|
||||
exactly(18).of(database).startTransaction();
|
||||
@@ -509,9 +509,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
|
||||
throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
@SuppressWarnings("unchecked")
|
||||
final Database<Object> database = context.mock(Database.class);
|
||||
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
final EventBus eventBus = context.mock(EventBus.class);
|
||||
Database<Object> database = context.mock(Database.class);
|
||||
ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
EventBus eventBus = context.mock(EventBus.class);
|
||||
context.checking(new Expectations() {{
|
||||
// Check whether the pseudonym is in the DB (which it's not)
|
||||
exactly(3).of(database).startTransaction();
|
||||
@@ -561,9 +561,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
|
||||
throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
@SuppressWarnings("unchecked")
|
||||
final Database<Object> database = context.mock(Database.class);
|
||||
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
final EventBus eventBus = context.mock(EventBus.class);
|
||||
Database<Object> database = context.mock(Database.class);
|
||||
ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
EventBus eventBus = context.mock(EventBus.class);
|
||||
context.checking(new Expectations() {{
|
||||
// Check whether the group is in the DB (which it's not)
|
||||
exactly(8).of(database).startTransaction();
|
||||
@@ -666,9 +666,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
|
||||
throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
@SuppressWarnings("unchecked")
|
||||
final Database<Object> database = context.mock(Database.class);
|
||||
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
final EventBus eventBus = context.mock(EventBus.class);
|
||||
Database<Object> database = context.mock(Database.class);
|
||||
ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
EventBus eventBus = context.mock(EventBus.class);
|
||||
context.checking(new Expectations() {{
|
||||
// Check whether the message is in the DB (which it's not)
|
||||
exactly(11).of(database).startTransaction();
|
||||
@@ -801,9 +801,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
|
||||
throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
@SuppressWarnings("unchecked")
|
||||
final Database<Object> database = context.mock(Database.class);
|
||||
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
final EventBus eventBus = context.mock(EventBus.class);
|
||||
Database<Object> database = context.mock(Database.class);
|
||||
ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
EventBus eventBus = context.mock(EventBus.class);
|
||||
context.checking(new Expectations() {{
|
||||
// startTransaction()
|
||||
oneOf(database).startTransaction();
|
||||
@@ -896,13 +896,13 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testGenerateAck() throws Exception {
|
||||
final Collection<MessageId> messagesToAck = Arrays.asList(messageId,
|
||||
Collection<MessageId> messagesToAck = Arrays.asList(messageId,
|
||||
messageId1);
|
||||
Mockery context = new Mockery();
|
||||
@SuppressWarnings("unchecked")
|
||||
final Database<Object> database = context.mock(Database.class);
|
||||
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
final EventBus eventBus = context.mock(EventBus.class);
|
||||
Database<Object> database = context.mock(Database.class);
|
||||
ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
EventBus eventBus = context.mock(EventBus.class);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(database).startTransaction();
|
||||
will(returnValue(txn));
|
||||
@@ -931,14 +931,14 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testGenerateBatch() throws Exception {
|
||||
final byte[] raw1 = new byte[size];
|
||||
final Collection<MessageId> ids = Arrays.asList(messageId, messageId1);
|
||||
final Collection<byte[]> messages = Arrays.asList(raw, raw1);
|
||||
byte[] raw1 = new byte[size];
|
||||
Collection<MessageId> ids = Arrays.asList(messageId, messageId1);
|
||||
Collection<byte[]> messages = Arrays.asList(raw, raw1);
|
||||
Mockery context = new Mockery();
|
||||
@SuppressWarnings("unchecked")
|
||||
final Database<Object> database = context.mock(Database.class);
|
||||
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
final EventBus eventBus = context.mock(EventBus.class);
|
||||
Database<Object> database = context.mock(Database.class);
|
||||
ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
EventBus eventBus = context.mock(EventBus.class);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(database).startTransaction();
|
||||
will(returnValue(txn));
|
||||
@@ -975,13 +975,13 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testGenerateOffer() throws Exception {
|
||||
final MessageId messageId1 = new MessageId(TestUtils.getRandomId());
|
||||
final Collection<MessageId> ids = Arrays.asList(messageId, messageId1);
|
||||
MessageId messageId1 = new MessageId(TestUtils.getRandomId());
|
||||
Collection<MessageId> ids = Arrays.asList(messageId, messageId1);
|
||||
Mockery context = new Mockery();
|
||||
@SuppressWarnings("unchecked")
|
||||
final Database<Object> database = context.mock(Database.class);
|
||||
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
final EventBus eventBus = context.mock(EventBus.class);
|
||||
Database<Object> database = context.mock(Database.class);
|
||||
ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
EventBus eventBus = context.mock(EventBus.class);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(database).startTransaction();
|
||||
will(returnValue(txn));
|
||||
@@ -1013,13 +1013,13 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testGenerateRequest() throws Exception {
|
||||
final MessageId messageId1 = new MessageId(TestUtils.getRandomId());
|
||||
final Collection<MessageId> ids = Arrays.asList(messageId, messageId1);
|
||||
MessageId messageId1 = new MessageId(TestUtils.getRandomId());
|
||||
Collection<MessageId> ids = Arrays.asList(messageId, messageId1);
|
||||
Mockery context = new Mockery();
|
||||
@SuppressWarnings("unchecked")
|
||||
final Database<Object> database = context.mock(Database.class);
|
||||
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
final EventBus eventBus = context.mock(EventBus.class);
|
||||
Database<Object> database = context.mock(Database.class);
|
||||
ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
EventBus eventBus = context.mock(EventBus.class);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(database).startTransaction();
|
||||
will(returnValue(txn));
|
||||
@@ -1048,14 +1048,14 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testGenerateRequestedBatch() throws Exception {
|
||||
final byte[] raw1 = new byte[size];
|
||||
final Collection<MessageId> ids = Arrays.asList(messageId, messageId1);
|
||||
final Collection<byte[]> messages = Arrays.asList(raw, raw1);
|
||||
byte[] raw1 = new byte[size];
|
||||
Collection<MessageId> ids = Arrays.asList(messageId, messageId1);
|
||||
Collection<byte[]> messages = Arrays.asList(raw, raw1);
|
||||
Mockery context = new Mockery();
|
||||
@SuppressWarnings("unchecked")
|
||||
final Database<Object> database = context.mock(Database.class);
|
||||
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
final EventBus eventBus = context.mock(EventBus.class);
|
||||
Database<Object> database = context.mock(Database.class);
|
||||
ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
EventBus eventBus = context.mock(EventBus.class);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(database).startTransaction();
|
||||
will(returnValue(txn));
|
||||
@@ -1095,9 +1095,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
|
||||
public void testReceiveAck() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
@SuppressWarnings("unchecked")
|
||||
final Database<Object> database = context.mock(Database.class);
|
||||
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
final EventBus eventBus = context.mock(EventBus.class);
|
||||
Database<Object> database = context.mock(Database.class);
|
||||
ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
EventBus eventBus = context.mock(EventBus.class);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(database).startTransaction();
|
||||
will(returnValue(txn));
|
||||
@@ -1128,9 +1128,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
|
||||
public void testReceiveMessage() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
@SuppressWarnings("unchecked")
|
||||
final Database<Object> database = context.mock(Database.class);
|
||||
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
final EventBus eventBus = context.mock(EventBus.class);
|
||||
Database<Object> database = context.mock(Database.class);
|
||||
ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
EventBus eventBus = context.mock(EventBus.class);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(database).startTransaction();
|
||||
will(returnValue(txn));
|
||||
@@ -1183,9 +1183,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
|
||||
public void testReceiveDuplicateMessage() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
@SuppressWarnings("unchecked")
|
||||
final Database<Object> database = context.mock(Database.class);
|
||||
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
final EventBus eventBus = context.mock(EventBus.class);
|
||||
Database<Object> database = context.mock(Database.class);
|
||||
ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
EventBus eventBus = context.mock(EventBus.class);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(database).startTransaction();
|
||||
will(returnValue(txn));
|
||||
@@ -1220,9 +1220,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
|
||||
public void testReceiveMessageWithoutVisibleGroup() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
@SuppressWarnings("unchecked")
|
||||
final Database<Object> database = context.mock(Database.class);
|
||||
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
final EventBus eventBus = context.mock(EventBus.class);
|
||||
Database<Object> database = context.mock(Database.class);
|
||||
ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
EventBus eventBus = context.mock(EventBus.class);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(database).startTransaction();
|
||||
will(returnValue(txn));
|
||||
@@ -1248,14 +1248,14 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testReceiveOffer() throws Exception {
|
||||
final MessageId messageId1 = new MessageId(TestUtils.getRandomId());
|
||||
final MessageId messageId2 = new MessageId(TestUtils.getRandomId());
|
||||
final MessageId messageId3 = new MessageId(TestUtils.getRandomId());
|
||||
MessageId messageId1 = new MessageId(TestUtils.getRandomId());
|
||||
MessageId messageId2 = new MessageId(TestUtils.getRandomId());
|
||||
MessageId messageId3 = new MessageId(TestUtils.getRandomId());
|
||||
Mockery context = new Mockery();
|
||||
@SuppressWarnings("unchecked")
|
||||
final Database<Object> database = context.mock(Database.class);
|
||||
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
final EventBus eventBus = context.mock(EventBus.class);
|
||||
Database<Object> database = context.mock(Database.class);
|
||||
ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
EventBus eventBus = context.mock(EventBus.class);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(database).startTransaction();
|
||||
will(returnValue(txn));
|
||||
@@ -1304,9 +1304,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
|
||||
public void testReceiveRequest() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
@SuppressWarnings("unchecked")
|
||||
final Database<Object> database = context.mock(Database.class);
|
||||
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
final EventBus eventBus = context.mock(EventBus.class);
|
||||
Database<Object> database = context.mock(Database.class);
|
||||
ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
EventBus eventBus = context.mock(EventBus.class);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(database).startTransaction();
|
||||
will(returnValue(txn));
|
||||
@@ -1338,9 +1338,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
|
||||
public void testChangingVisibilityCallsListeners() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
@SuppressWarnings("unchecked")
|
||||
final Database<Object> database = context.mock(Database.class);
|
||||
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
final EventBus eventBus = context.mock(EventBus.class);
|
||||
Database<Object> database = context.mock(Database.class);
|
||||
ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
EventBus eventBus = context.mock(EventBus.class);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(database).startTransaction();
|
||||
will(returnValue(txn));
|
||||
@@ -1379,9 +1379,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
|
||||
throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
@SuppressWarnings("unchecked")
|
||||
final Database<Object> database = context.mock(Database.class);
|
||||
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
final EventBus eventBus = context.mock(EventBus.class);
|
||||
Database<Object> database = context.mock(Database.class);
|
||||
ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
EventBus eventBus = context.mock(EventBus.class);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(database).startTransaction();
|
||||
will(returnValue(txn));
|
||||
@@ -1409,14 +1409,14 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testTransportKeys() throws Exception {
|
||||
final TransportKeys transportKeys = createTransportKeys();
|
||||
final Map<ContactId, TransportKeys> keys = Collections.singletonMap(
|
||||
TransportKeys transportKeys = createTransportKeys();
|
||||
Map<ContactId, TransportKeys> keys = Collections.singletonMap(
|
||||
contactId, transportKeys);
|
||||
Mockery context = new Mockery();
|
||||
@SuppressWarnings("unchecked")
|
||||
final Database<Object> database = context.mock(Database.class);
|
||||
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
final EventBus eventBus = context.mock(EventBus.class);
|
||||
Database<Object> database = context.mock(Database.class);
|
||||
ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
EventBus eventBus = context.mock(EventBus.class);
|
||||
context.checking(new Expectations() {{
|
||||
// startTransaction()
|
||||
oneOf(database).startTransaction();
|
||||
@@ -1472,19 +1472,19 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testMergeSettings() throws Exception {
|
||||
final Settings before = new Settings();
|
||||
Settings before = new Settings();
|
||||
before.put("foo", "bar");
|
||||
before.put("baz", "bam");
|
||||
final Settings update = new Settings();
|
||||
Settings update = new Settings();
|
||||
update.put("baz", "qux");
|
||||
final Settings merged = new Settings();
|
||||
Settings merged = new Settings();
|
||||
merged.put("foo", "bar");
|
||||
merged.put("baz", "qux");
|
||||
Mockery context = new Mockery();
|
||||
@SuppressWarnings("unchecked")
|
||||
final Database<Object> database = context.mock(Database.class);
|
||||
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
final EventBus eventBus = context.mock(EventBus.class);
|
||||
Database<Object> database = context.mock(Database.class);
|
||||
ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
EventBus eventBus = context.mock(EventBus.class);
|
||||
context.checking(new Expectations() {{
|
||||
// startTransaction()
|
||||
oneOf(database).startTransaction();
|
||||
@@ -1547,9 +1547,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
|
||||
throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
@SuppressWarnings("unchecked")
|
||||
final Database<Object> database = context.mock(Database.class);
|
||||
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
final EventBus eventBus = context.mock(EventBus.class);
|
||||
Database<Object> database = context.mock(Database.class);
|
||||
ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
EventBus eventBus = context.mock(EventBus.class);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(database).startTransaction();
|
||||
@@ -1572,9 +1572,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
|
||||
public void testCannotAddLocalIdentityAsContact() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
@SuppressWarnings("unchecked")
|
||||
final Database<Object> database = context.mock(Database.class);
|
||||
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
final EventBus eventBus = context.mock(EventBus.class);
|
||||
Database<Object> database = context.mock(Database.class);
|
||||
ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
EventBus eventBus = context.mock(EventBus.class);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(database).startTransaction();
|
||||
@@ -1607,9 +1607,9 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
|
||||
public void testCannotAddDuplicateContact() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
@SuppressWarnings("unchecked")
|
||||
final Database<Object> database = context.mock(Database.class);
|
||||
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
final EventBus eventBus = context.mock(EventBus.class);
|
||||
Database<Object> database = context.mock(Database.class);
|
||||
ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
EventBus eventBus = context.mock(EventBus.class);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(database).startTransaction();
|
||||
@@ -1643,12 +1643,12 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testMessageDependencies() throws Exception {
|
||||
final int shutdownHandle = 12345;
|
||||
int shutdownHandle = 12345;
|
||||
Mockery context = new Mockery();
|
||||
final Database<Object> database = context.mock(Database.class);
|
||||
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
final EventBus eventBus = context.mock(EventBus.class);
|
||||
final MessageId messageId2 = new MessageId(TestUtils.getRandomId());
|
||||
Database<Object> database = context.mock(Database.class);
|
||||
ShutdownManager shutdown = context.mock(ShutdownManager.class);
|
||||
EventBus eventBus = context.mock(EventBus.class);
|
||||
MessageId messageId2 = new MessageId(TestUtils.getRandomId());
|
||||
context.checking(new Expectations() {{
|
||||
// open()
|
||||
oneOf(database).open();
|
||||
@@ -1703,7 +1703,7 @@ public class DatabaseComponentImplTest extends BrambleTestCase {
|
||||
Transaction transaction = db.startTransaction(false);
|
||||
try {
|
||||
db.addLocalMessage(transaction, message, metadata, true);
|
||||
Collection<MessageId> dependencies = new ArrayList<MessageId>(2);
|
||||
Collection<MessageId> dependencies = new ArrayList<>(2);
|
||||
dependencies.add(messageId1);
|
||||
dependencies.add(messageId2);
|
||||
db.addMessageDependencies(transaction, message, dependencies);
|
||||
|
||||
@@ -464,28 +464,25 @@ public class H2DatabaseTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testCloseWaitsForCommit() throws Exception {
|
||||
final CountDownLatch closing = new CountDownLatch(1);
|
||||
final CountDownLatch closed = new CountDownLatch(1);
|
||||
final AtomicBoolean transactionFinished = new AtomicBoolean(false);
|
||||
final AtomicBoolean error = new AtomicBoolean(false);
|
||||
final Database<Connection> db = open(false);
|
||||
CountDownLatch closing = new CountDownLatch(1);
|
||||
CountDownLatch closed = new CountDownLatch(1);
|
||||
AtomicBoolean transactionFinished = new AtomicBoolean(false);
|
||||
AtomicBoolean error = new AtomicBoolean(false);
|
||||
Database<Connection> db = open(false);
|
||||
|
||||
// Start a transaction
|
||||
Connection txn = db.startTransaction();
|
||||
// In another thread, close the database
|
||||
Thread close = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
closing.countDown();
|
||||
db.close();
|
||||
if (!transactionFinished.get()) error.set(true);
|
||||
closed.countDown();
|
||||
} catch (Exception e) {
|
||||
error.set(true);
|
||||
}
|
||||
Thread close = new Thread(() -> {
|
||||
try {
|
||||
closing.countDown();
|
||||
db.close();
|
||||
if (!transactionFinished.get()) error.set(true);
|
||||
closed.countDown();
|
||||
} catch (Exception e) {
|
||||
error.set(true);
|
||||
}
|
||||
};
|
||||
});
|
||||
close.start();
|
||||
closing.await();
|
||||
// Do whatever the transaction needs to do
|
||||
@@ -501,28 +498,25 @@ public class H2DatabaseTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testCloseWaitsForAbort() throws Exception {
|
||||
final CountDownLatch closing = new CountDownLatch(1);
|
||||
final CountDownLatch closed = new CountDownLatch(1);
|
||||
final AtomicBoolean transactionFinished = new AtomicBoolean(false);
|
||||
final AtomicBoolean error = new AtomicBoolean(false);
|
||||
final Database<Connection> db = open(false);
|
||||
CountDownLatch closing = new CountDownLatch(1);
|
||||
CountDownLatch closed = new CountDownLatch(1);
|
||||
AtomicBoolean transactionFinished = new AtomicBoolean(false);
|
||||
AtomicBoolean error = new AtomicBoolean(false);
|
||||
Database<Connection> db = open(false);
|
||||
|
||||
// Start a transaction
|
||||
Connection txn = db.startTransaction();
|
||||
// In another thread, close the database
|
||||
Thread close = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
closing.countDown();
|
||||
db.close();
|
||||
if (!transactionFinished.get()) error.set(true);
|
||||
closed.countDown();
|
||||
} catch (Exception e) {
|
||||
error.set(true);
|
||||
}
|
||||
Thread close = new Thread(() -> {
|
||||
try {
|
||||
closing.countDown();
|
||||
db.close();
|
||||
if (!transactionFinished.get()) error.set(true);
|
||||
closed.countDown();
|
||||
} catch (Exception e) {
|
||||
error.set(true);
|
||||
}
|
||||
};
|
||||
});
|
||||
close.start();
|
||||
closing.await();
|
||||
// Do whatever the transaction needs to do
|
||||
@@ -870,7 +864,7 @@ public class H2DatabaseTest extends BrambleTestCase {
|
||||
assertEquals(0, db.countOfferedMessages(txn, contactId));
|
||||
|
||||
// Add some offered messages and count them
|
||||
List<MessageId> ids = new ArrayList<MessageId>();
|
||||
List<MessageId> ids = new ArrayList<>();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
MessageId m = new MessageId(TestUtils.getRandomId());
|
||||
db.addOfferedMessage(txn, contactId, m);
|
||||
|
||||
@@ -17,56 +17,50 @@ public class LockFairnessTest extends BrambleTestCase {
|
||||
@Test
|
||||
public void testReadersCanShareTheLock() throws Exception {
|
||||
// Use a fair lock
|
||||
final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
|
||||
final CountDownLatch firstReaderHasLock = new CountDownLatch(1);
|
||||
final CountDownLatch firstReaderHasFinished = new CountDownLatch(1);
|
||||
final CountDownLatch secondReaderHasLock = new CountDownLatch(1);
|
||||
final CountDownLatch secondReaderHasFinished = new CountDownLatch(1);
|
||||
ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
|
||||
CountDownLatch firstReaderHasLock = new CountDownLatch(1);
|
||||
CountDownLatch firstReaderHasFinished = new CountDownLatch(1);
|
||||
CountDownLatch secondReaderHasLock = new CountDownLatch(1);
|
||||
CountDownLatch secondReaderHasFinished = new CountDownLatch(1);
|
||||
// First reader
|
||||
Thread first = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
Thread first = new Thread(() -> {
|
||||
try {
|
||||
// Acquire the lock
|
||||
lock.readLock().lock();
|
||||
try {
|
||||
// Acquire the lock
|
||||
lock.readLock().lock();
|
||||
try {
|
||||
// Allow the second reader to acquire the lock
|
||||
firstReaderHasLock.countDown();
|
||||
// Wait for the second reader to acquire the lock
|
||||
assertTrue(secondReaderHasLock.await(10, SECONDS));
|
||||
} finally {
|
||||
// Release the lock
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
fail();
|
||||
// Allow the second reader to acquire the lock
|
||||
firstReaderHasLock.countDown();
|
||||
// Wait for the second reader to acquire the lock
|
||||
assertTrue(secondReaderHasLock.await(10, SECONDS));
|
||||
} finally {
|
||||
// Release the lock
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
firstReaderHasFinished.countDown();
|
||||
} catch (InterruptedException e) {
|
||||
fail();
|
||||
}
|
||||
};
|
||||
firstReaderHasFinished.countDown();
|
||||
});
|
||||
first.start();
|
||||
// Second reader
|
||||
Thread second = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
Thread second = new Thread(() -> {
|
||||
try {
|
||||
// Wait for the first reader to acquire the lock
|
||||
assertTrue(firstReaderHasLock.await(10, SECONDS));
|
||||
// Acquire the lock
|
||||
lock.readLock().lock();
|
||||
try {
|
||||
// Wait for the first reader to acquire the lock
|
||||
assertTrue(firstReaderHasLock.await(10, SECONDS));
|
||||
// Acquire the lock
|
||||
lock.readLock().lock();
|
||||
try {
|
||||
// Allow the first reader to release the lock
|
||||
secondReaderHasLock.countDown();
|
||||
} finally {
|
||||
// Release the lock
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
fail();
|
||||
// Allow the first reader to release the lock
|
||||
secondReaderHasLock.countDown();
|
||||
} finally {
|
||||
// Release the lock
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
secondReaderHasFinished.countDown();
|
||||
} catch (InterruptedException e) {
|
||||
fail();
|
||||
}
|
||||
};
|
||||
secondReaderHasFinished.countDown();
|
||||
});
|
||||
second.start();
|
||||
// Wait for both readers to finish
|
||||
assertTrue(firstReaderHasFinished.await(10, SECONDS));
|
||||
@@ -76,86 +70,77 @@ public class LockFairnessTest extends BrambleTestCase {
|
||||
@Test
|
||||
public void testWritersDoNotStarve() throws Exception {
|
||||
// Use a fair lock
|
||||
final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
|
||||
final CountDownLatch firstReaderHasLock = new CountDownLatch(1);
|
||||
final CountDownLatch firstReaderHasFinished = new CountDownLatch(1);
|
||||
final CountDownLatch secondReaderHasFinished = new CountDownLatch(1);
|
||||
final CountDownLatch writerHasFinished = new CountDownLatch(1);
|
||||
final AtomicBoolean secondReaderHasHeldLock = new AtomicBoolean(false);
|
||||
final AtomicBoolean writerHasHeldLock = new AtomicBoolean(false);
|
||||
ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
|
||||
CountDownLatch firstReaderHasLock = new CountDownLatch(1);
|
||||
CountDownLatch firstReaderHasFinished = new CountDownLatch(1);
|
||||
CountDownLatch secondReaderHasFinished = new CountDownLatch(1);
|
||||
CountDownLatch writerHasFinished = new CountDownLatch(1);
|
||||
AtomicBoolean secondReaderHasHeldLock = new AtomicBoolean(false);
|
||||
AtomicBoolean writerHasHeldLock = new AtomicBoolean(false);
|
||||
// First reader
|
||||
Thread first = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
Thread first = new Thread(() -> {
|
||||
try {
|
||||
// Acquire the lock
|
||||
lock.readLock().lock();
|
||||
try {
|
||||
// Acquire the lock
|
||||
lock.readLock().lock();
|
||||
try {
|
||||
// Allow the other threads to acquire the lock
|
||||
firstReaderHasLock.countDown();
|
||||
// Wait for both other threads to wait for the lock
|
||||
while (lock.getQueueLength() < 2) Thread.sleep(10);
|
||||
// No other thread should have acquired the lock
|
||||
assertFalse(secondReaderHasHeldLock.get());
|
||||
assertFalse(writerHasHeldLock.get());
|
||||
} finally {
|
||||
// Release the lock
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
fail();
|
||||
// Allow the other threads to acquire the lock
|
||||
firstReaderHasLock.countDown();
|
||||
// Wait for both other threads to wait for the lock
|
||||
while (lock.getQueueLength() < 2) Thread.sleep(10);
|
||||
// No other thread should have acquired the lock
|
||||
assertFalse(secondReaderHasHeldLock.get());
|
||||
assertFalse(writerHasHeldLock.get());
|
||||
} finally {
|
||||
// Release the lock
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
firstReaderHasFinished.countDown();
|
||||
} catch (InterruptedException e) {
|
||||
fail();
|
||||
}
|
||||
};
|
||||
firstReaderHasFinished.countDown();
|
||||
});
|
||||
first.start();
|
||||
// Writer
|
||||
Thread writer = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
Thread writer = new Thread(() -> {
|
||||
try {
|
||||
// Wait for the first reader to acquire the lock
|
||||
assertTrue(firstReaderHasLock.await(10, SECONDS));
|
||||
// Acquire the lock
|
||||
lock.writeLock().lock();
|
||||
try {
|
||||
// Wait for the first reader to acquire the lock
|
||||
assertTrue(firstReaderHasLock.await(10, SECONDS));
|
||||
// Acquire the lock
|
||||
lock.writeLock().lock();
|
||||
try {
|
||||
writerHasHeldLock.set(true);
|
||||
// The second reader should not overtake the writer
|
||||
assertFalse(secondReaderHasHeldLock.get());
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
fail();
|
||||
writerHasHeldLock.set(true);
|
||||
// The second reader should not overtake the writer
|
||||
assertFalse(secondReaderHasHeldLock.get());
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
writerHasFinished.countDown();
|
||||
} catch (InterruptedException e) {
|
||||
fail();
|
||||
}
|
||||
};
|
||||
writerHasFinished.countDown();
|
||||
});
|
||||
writer.start();
|
||||
// Second reader
|
||||
Thread second = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
Thread second = new Thread(() -> {
|
||||
try {
|
||||
// Wait for the first reader to acquire the lock
|
||||
assertTrue(firstReaderHasLock.await(10, SECONDS));
|
||||
// Wait for the writer to wait for the lock
|
||||
while (lock.getQueueLength() < 1) Thread.sleep(10);
|
||||
// Acquire the lock
|
||||
lock.readLock().lock();
|
||||
try {
|
||||
// Wait for the first reader to acquire the lock
|
||||
assertTrue(firstReaderHasLock.await(10, SECONDS));
|
||||
// Wait for the writer to wait for the lock
|
||||
while (lock.getQueueLength() < 1) Thread.sleep(10);
|
||||
// Acquire the lock
|
||||
lock.readLock().lock();
|
||||
try {
|
||||
secondReaderHasHeldLock.set(true);
|
||||
// The second reader should not overtake the writer
|
||||
assertTrue(writerHasHeldLock.get());
|
||||
} finally {
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
fail();
|
||||
secondReaderHasHeldLock.set(true);
|
||||
// The second reader should not overtake the writer
|
||||
assertTrue(writerHasHeldLock.get());
|
||||
} finally {
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
secondReaderHasFinished.countDown();
|
||||
} catch (InterruptedException e) {
|
||||
fail();
|
||||
}
|
||||
};
|
||||
secondReaderHasFinished.countDown();
|
||||
});
|
||||
second.start();
|
||||
// Wait for all the threads to finish
|
||||
assertTrue(firstReaderHasFinished.await(10, SECONDS));
|
||||
|
||||
@@ -80,8 +80,8 @@ public class IdentityManagerImplTest extends BrambleMockTestCase {
|
||||
|
||||
@Test
|
||||
public void testGetAuthorStatus() throws DbException {
|
||||
final AuthorId authorId = new AuthorId(TestUtils.getRandomId());
|
||||
final Collection<Contact> contacts = new ArrayList<Contact>();
|
||||
AuthorId authorId = new AuthorId(TestUtils.getRandomId());
|
||||
Collection<Contact> contacts = new ArrayList<>();
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(true);
|
||||
@@ -125,8 +125,8 @@ public class IdentityManagerImplTest extends BrambleMockTestCase {
|
||||
identityManager.getAuthorStatus(localAuthor.getId()));
|
||||
}
|
||||
|
||||
private void checkAuthorStatusContext(final AuthorId authorId,
|
||||
final Collection<Contact> contacts) throws DbException {
|
||||
private void checkAuthorStatusContext(AuthorId authorId,
|
||||
Collection<Contact> contacts) throws DbException {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
|
||||
@@ -65,11 +65,11 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
@Test
|
||||
public void testAliceProtocol() throws Exception {
|
||||
// set up
|
||||
final Payload theirPayload = new Payload(BOB_COMMIT, null);
|
||||
final Payload ourPayload = new Payload(ALICE_COMMIT, null);
|
||||
final KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
|
||||
final SecretKey sharedSecret = TestUtils.getSecretKey();
|
||||
final SecretKey masterSecret = TestUtils.getSecretKey();
|
||||
Payload theirPayload = new Payload(BOB_COMMIT, null);
|
||||
Payload ourPayload = new Payload(ALICE_COMMIT, null);
|
||||
KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
|
||||
SecretKey sharedSecret = TestUtils.getSecretKey();
|
||||
SecretKey masterSecret = TestUtils.getSecretKey();
|
||||
|
||||
KeyAgreementProtocol protocol =
|
||||
new KeyAgreementProtocol(callbacks, crypto, payloadEncoder,
|
||||
@@ -129,11 +129,11 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
@Test
|
||||
public void testBobProtocol() throws Exception {
|
||||
// set up
|
||||
final Payload theirPayload = new Payload(ALICE_COMMIT, null);
|
||||
final Payload ourPayload = new Payload(BOB_COMMIT, null);
|
||||
final KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
|
||||
final SecretKey sharedSecret = TestUtils.getSecretKey();
|
||||
final SecretKey masterSecret = TestUtils.getSecretKey();
|
||||
Payload theirPayload = new Payload(ALICE_COMMIT, null);
|
||||
Payload ourPayload = new Payload(BOB_COMMIT, null);
|
||||
KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
|
||||
SecretKey sharedSecret = TestUtils.getSecretKey();
|
||||
SecretKey masterSecret = TestUtils.getSecretKey();
|
||||
|
||||
KeyAgreementProtocol protocol =
|
||||
new KeyAgreementProtocol(callbacks, crypto, payloadEncoder,
|
||||
@@ -192,9 +192,9 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
@Test(expected = AbortException.class)
|
||||
public void testAliceProtocolAbortOnBadKey() throws Exception {
|
||||
// set up
|
||||
final Payload theirPayload = new Payload(BOB_COMMIT, null);
|
||||
final Payload ourPayload = new Payload(ALICE_COMMIT, null);
|
||||
final KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
|
||||
Payload theirPayload = new Payload(BOB_COMMIT, null);
|
||||
Payload ourPayload = new Payload(ALICE_COMMIT, null);
|
||||
KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
|
||||
|
||||
KeyAgreementProtocol protocol =
|
||||
new KeyAgreementProtocol(callbacks, crypto, payloadEncoder,
|
||||
@@ -233,9 +233,9 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
@Test(expected = AbortException.class)
|
||||
public void testBobProtocolAbortOnBadKey() throws Exception {
|
||||
// set up
|
||||
final Payload theirPayload = new Payload(ALICE_COMMIT, null);
|
||||
final Payload ourPayload = new Payload(BOB_COMMIT, null);
|
||||
final KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
|
||||
Payload theirPayload = new Payload(ALICE_COMMIT, null);
|
||||
Payload ourPayload = new Payload(BOB_COMMIT, null);
|
||||
KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
|
||||
|
||||
KeyAgreementProtocol protocol =
|
||||
new KeyAgreementProtocol(callbacks, crypto, payloadEncoder,
|
||||
@@ -270,10 +270,10 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
@Test(expected = AbortException.class)
|
||||
public void testAliceProtocolAbortOnBadConfirm() throws Exception {
|
||||
// set up
|
||||
final Payload theirPayload = new Payload(BOB_COMMIT, null);
|
||||
final Payload ourPayload = new Payload(ALICE_COMMIT, null);
|
||||
final KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
|
||||
final SecretKey sharedSecret = TestUtils.getSecretKey();
|
||||
Payload theirPayload = new Payload(BOB_COMMIT, null);
|
||||
Payload ourPayload = new Payload(ALICE_COMMIT, null);
|
||||
KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
|
||||
SecretKey sharedSecret = TestUtils.getSecretKey();
|
||||
|
||||
KeyAgreementProtocol protocol =
|
||||
new KeyAgreementProtocol(callbacks, crypto, payloadEncoder,
|
||||
@@ -335,10 +335,10 @@ public class KeyAgreementProtocolTest extends BrambleTestCase {
|
||||
@Test(expected = AbortException.class)
|
||||
public void testBobProtocolAbortOnBadConfirm() throws Exception {
|
||||
// set up
|
||||
final Payload theirPayload = new Payload(ALICE_COMMIT, null);
|
||||
final Payload ourPayload = new Payload(BOB_COMMIT, null);
|
||||
final KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
|
||||
final SecretKey sharedSecret = TestUtils.getSecretKey();
|
||||
Payload theirPayload = new Payload(ALICE_COMMIT, null);
|
||||
Payload ourPayload = new Payload(BOB_COMMIT, null);
|
||||
KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
|
||||
SecretKey sharedSecret = TestUtils.getSecretKey();
|
||||
|
||||
KeyAgreementProtocol protocol =
|
||||
new KeyAgreementProtocol(callbacks, crypto, payloadEncoder,
|
||||
|
||||
@@ -15,13 +15,9 @@ public class ShutdownManagerImplTest extends BrambleTestCase {
|
||||
@Test
|
||||
public void testAddAndRemove() {
|
||||
ShutdownManager s = createShutdownManager();
|
||||
Set<Integer> handles = new HashSet<Integer>();
|
||||
Set<Integer> handles = new HashSet<>();
|
||||
for (int i = 0; i < 100; i++) {
|
||||
int handle = s.addShutdownHook(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
}
|
||||
});
|
||||
int handle = s.addShutdownHook(() -> {});
|
||||
// The handles should all be distinct
|
||||
assertTrue(handles.add(handle));
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ConnectionRegistryImplTest extends BrambleTestCase {
|
||||
@Test
|
||||
public void testRegisterAndUnregister() {
|
||||
Mockery context = new Mockery();
|
||||
final EventBus eventBus = context.mock(EventBus.class);
|
||||
EventBus eventBus = context.mock(EventBus.class);
|
||||
context.checking(new Expectations() {{
|
||||
exactly(5).of(eventBus).broadcast(with(any(
|
||||
ConnectionOpenedEvent.class)));
|
||||
|
||||
@@ -30,36 +30,36 @@ public class PluginManagerImplTest extends BrambleTestCase {
|
||||
Mockery context = new Mockery() {{
|
||||
setThreadingPolicy(new Synchroniser());
|
||||
}};
|
||||
final Executor ioExecutor = Executors.newSingleThreadExecutor();
|
||||
final EventBus eventBus = context.mock(EventBus.class);
|
||||
final PluginConfig pluginConfig = context.mock(PluginConfig.class);
|
||||
final ConnectionManager connectionManager =
|
||||
Executor ioExecutor = Executors.newSingleThreadExecutor();
|
||||
EventBus eventBus = context.mock(EventBus.class);
|
||||
PluginConfig pluginConfig = context.mock(PluginConfig.class);
|
||||
ConnectionManager connectionManager =
|
||||
context.mock(ConnectionManager.class);
|
||||
final SettingsManager settingsManager =
|
||||
SettingsManager settingsManager =
|
||||
context.mock(SettingsManager.class);
|
||||
final TransportPropertyManager transportPropertyManager =
|
||||
TransportPropertyManager transportPropertyManager =
|
||||
context.mock(TransportPropertyManager.class);
|
||||
final UiCallback uiCallback = context.mock(UiCallback.class);
|
||||
UiCallback uiCallback = context.mock(UiCallback.class);
|
||||
|
||||
// Two simplex plugin factories: both create plugins, one fails to start
|
||||
final SimplexPluginFactory simplexFactory =
|
||||
SimplexPluginFactory simplexFactory =
|
||||
context.mock(SimplexPluginFactory.class);
|
||||
final SimplexPlugin simplexPlugin = context.mock(SimplexPlugin.class);
|
||||
final TransportId simplexId = new TransportId("simplex");
|
||||
final SimplexPluginFactory simplexFailFactory =
|
||||
SimplexPlugin simplexPlugin = context.mock(SimplexPlugin.class);
|
||||
TransportId simplexId = new TransportId("simplex");
|
||||
SimplexPluginFactory simplexFailFactory =
|
||||
context.mock(SimplexPluginFactory.class, "simplexFailFactory");
|
||||
final SimplexPlugin simplexFailPlugin =
|
||||
SimplexPlugin simplexFailPlugin =
|
||||
context.mock(SimplexPlugin.class, "simplexFailPlugin");
|
||||
final TransportId simplexFailId = new TransportId("simplex1");
|
||||
TransportId simplexFailId = new TransportId("simplex1");
|
||||
|
||||
// Two duplex plugin factories: one creates a plugin, the other fails
|
||||
final DuplexPluginFactory duplexFactory =
|
||||
DuplexPluginFactory duplexFactory =
|
||||
context.mock(DuplexPluginFactory.class);
|
||||
final DuplexPlugin duplexPlugin = context.mock(DuplexPlugin.class);
|
||||
final TransportId duplexId = new TransportId("duplex");
|
||||
final DuplexPluginFactory duplexFailFactory =
|
||||
DuplexPlugin duplexPlugin = context.mock(DuplexPlugin.class);
|
||||
TransportId duplexId = new TransportId("duplex");
|
||||
DuplexPluginFactory duplexFailFactory =
|
||||
context.mock(DuplexPluginFactory.class, "duplexFailFactory");
|
||||
final TransportId duplexFailId = new TransportId("duplex1");
|
||||
TransportId duplexFailId = new TransportId("duplex1");
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
allowing(simplexPlugin).getId();
|
||||
|
||||
@@ -42,35 +42,35 @@ public class PollerTest extends BrambleTestCase {
|
||||
public void testConnectOnContactStatusChanged() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
context.setImposteriser(ClassImposteriser.INSTANCE);
|
||||
final Executor ioExecutor = new ImmediateExecutor();
|
||||
final ScheduledExecutorService scheduler =
|
||||
Executor ioExecutor = new ImmediateExecutor();
|
||||
ScheduledExecutorService scheduler =
|
||||
context.mock(ScheduledExecutorService.class);
|
||||
final ConnectionManager connectionManager =
|
||||
ConnectionManager connectionManager =
|
||||
context.mock(ConnectionManager.class);
|
||||
final ConnectionRegistry connectionRegistry =
|
||||
ConnectionRegistry connectionRegistry =
|
||||
context.mock(ConnectionRegistry.class);
|
||||
final PluginManager pluginManager = context.mock(PluginManager.class);
|
||||
final SecureRandom random = context.mock(SecureRandom.class);
|
||||
final Clock clock = context.mock(Clock.class);
|
||||
PluginManager pluginManager = context.mock(PluginManager.class);
|
||||
SecureRandom random = context.mock(SecureRandom.class);
|
||||
Clock clock = context.mock(Clock.class);
|
||||
|
||||
// Two simplex plugins: one supports polling, the other doesn't
|
||||
final SimplexPlugin simplexPlugin = context.mock(SimplexPlugin.class);
|
||||
final SimplexPlugin simplexPlugin1 =
|
||||
SimplexPlugin simplexPlugin = context.mock(SimplexPlugin.class);
|
||||
SimplexPlugin simplexPlugin1 =
|
||||
context.mock(SimplexPlugin.class, "simplexPlugin1");
|
||||
final TransportId simplexId1 = new TransportId("simplex1");
|
||||
final List<SimplexPlugin> simplexPlugins = Arrays.asList(simplexPlugin,
|
||||
TransportId simplexId1 = new TransportId("simplex1");
|
||||
List<SimplexPlugin> simplexPlugins = Arrays.asList(simplexPlugin,
|
||||
simplexPlugin1);
|
||||
final TransportConnectionWriter simplexWriter =
|
||||
TransportConnectionWriter simplexWriter =
|
||||
context.mock(TransportConnectionWriter.class);
|
||||
|
||||
// Two duplex plugins: one supports polling, the other doesn't
|
||||
final DuplexPlugin duplexPlugin = context.mock(DuplexPlugin.class);
|
||||
final TransportId duplexId = new TransportId("duplex");
|
||||
final DuplexPlugin duplexPlugin1 =
|
||||
DuplexPlugin duplexPlugin = context.mock(DuplexPlugin.class);
|
||||
TransportId duplexId = new TransportId("duplex");
|
||||
DuplexPlugin duplexPlugin1 =
|
||||
context.mock(DuplexPlugin.class, "duplexPlugin1");
|
||||
final List<DuplexPlugin> duplexPlugins = Arrays.asList(duplexPlugin,
|
||||
List<DuplexPlugin> duplexPlugins = Arrays.asList(duplexPlugin,
|
||||
duplexPlugin1);
|
||||
final DuplexTransportConnection duplexConnection =
|
||||
DuplexTransportConnection duplexConnection =
|
||||
context.mock(DuplexTransportConnection.class);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
@@ -129,20 +129,20 @@ public class PollerTest extends BrambleTestCase {
|
||||
throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
context.setImposteriser(ClassImposteriser.INSTANCE);
|
||||
final Executor ioExecutor = new ImmediateExecutor();
|
||||
final ScheduledExecutorService scheduler =
|
||||
Executor ioExecutor = new ImmediateExecutor();
|
||||
ScheduledExecutorService scheduler =
|
||||
context.mock(ScheduledExecutorService.class);
|
||||
final ConnectionManager connectionManager =
|
||||
ConnectionManager connectionManager =
|
||||
context.mock(ConnectionManager.class);
|
||||
final ConnectionRegistry connectionRegistry =
|
||||
ConnectionRegistry connectionRegistry =
|
||||
context.mock(ConnectionRegistry.class);
|
||||
final PluginManager pluginManager = context.mock(PluginManager.class);
|
||||
final SecureRandom random = context.mock(SecureRandom.class);
|
||||
final Clock clock = context.mock(Clock.class);
|
||||
PluginManager pluginManager = context.mock(PluginManager.class);
|
||||
SecureRandom random = context.mock(SecureRandom.class);
|
||||
Clock clock = context.mock(Clock.class);
|
||||
|
||||
final DuplexPlugin plugin = context.mock(DuplexPlugin.class);
|
||||
final TransportId transportId = new TransportId("id");
|
||||
final DuplexTransportConnection duplexConnection =
|
||||
DuplexPlugin plugin = context.mock(DuplexPlugin.class);
|
||||
TransportId transportId = new TransportId("id");
|
||||
DuplexTransportConnection duplexConnection =
|
||||
context.mock(DuplexTransportConnection.class);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
@@ -194,19 +194,19 @@ public class PollerTest extends BrambleTestCase {
|
||||
public void testRescheduleOnConnectionOpened() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
context.setImposteriser(ClassImposteriser.INSTANCE);
|
||||
final Executor ioExecutor = new ImmediateExecutor();
|
||||
final ScheduledExecutorService scheduler =
|
||||
Executor ioExecutor = new ImmediateExecutor();
|
||||
ScheduledExecutorService scheduler =
|
||||
context.mock(ScheduledExecutorService.class);
|
||||
final ConnectionManager connectionManager =
|
||||
ConnectionManager connectionManager =
|
||||
context.mock(ConnectionManager.class);
|
||||
final ConnectionRegistry connectionRegistry =
|
||||
ConnectionRegistry connectionRegistry =
|
||||
context.mock(ConnectionRegistry.class);
|
||||
final PluginManager pluginManager = context.mock(PluginManager.class);
|
||||
final SecureRandom random = context.mock(SecureRandom.class);
|
||||
final Clock clock = context.mock(Clock.class);
|
||||
PluginManager pluginManager = context.mock(PluginManager.class);
|
||||
SecureRandom random = context.mock(SecureRandom.class);
|
||||
Clock clock = context.mock(Clock.class);
|
||||
|
||||
final DuplexPlugin plugin = context.mock(DuplexPlugin.class);
|
||||
final TransportId transportId = new TransportId("id");
|
||||
DuplexPlugin plugin = context.mock(DuplexPlugin.class);
|
||||
TransportId transportId = new TransportId("id");
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
allowing(plugin).getId();
|
||||
@@ -239,19 +239,19 @@ public class PollerTest extends BrambleTestCase {
|
||||
public void testRescheduleDoesNotReplaceEarlierTask() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
context.setImposteriser(ClassImposteriser.INSTANCE);
|
||||
final Executor ioExecutor = new ImmediateExecutor();
|
||||
final ScheduledExecutorService scheduler =
|
||||
Executor ioExecutor = new ImmediateExecutor();
|
||||
ScheduledExecutorService scheduler =
|
||||
context.mock(ScheduledExecutorService.class);
|
||||
final ConnectionManager connectionManager =
|
||||
ConnectionManager connectionManager =
|
||||
context.mock(ConnectionManager.class);
|
||||
final ConnectionRegistry connectionRegistry =
|
||||
ConnectionRegistry connectionRegistry =
|
||||
context.mock(ConnectionRegistry.class);
|
||||
final PluginManager pluginManager = context.mock(PluginManager.class);
|
||||
final SecureRandom random = context.mock(SecureRandom.class);
|
||||
final Clock clock = context.mock(Clock.class);
|
||||
PluginManager pluginManager = context.mock(PluginManager.class);
|
||||
SecureRandom random = context.mock(SecureRandom.class);
|
||||
Clock clock = context.mock(Clock.class);
|
||||
|
||||
final DuplexPlugin plugin = context.mock(DuplexPlugin.class);
|
||||
final TransportId transportId = new TransportId("id");
|
||||
DuplexPlugin plugin = context.mock(DuplexPlugin.class);
|
||||
TransportId transportId = new TransportId("id");
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
allowing(plugin).getId();
|
||||
@@ -299,20 +299,20 @@ public class PollerTest extends BrambleTestCase {
|
||||
public void testPollOnTransportEnabled() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
context.setImposteriser(ClassImposteriser.INSTANCE);
|
||||
final Executor ioExecutor = new ImmediateExecutor();
|
||||
final ScheduledExecutorService scheduler =
|
||||
Executor ioExecutor = new ImmediateExecutor();
|
||||
ScheduledExecutorService scheduler =
|
||||
context.mock(ScheduledExecutorService.class);
|
||||
final ConnectionManager connectionManager =
|
||||
ConnectionManager connectionManager =
|
||||
context.mock(ConnectionManager.class);
|
||||
final ConnectionRegistry connectionRegistry =
|
||||
ConnectionRegistry connectionRegistry =
|
||||
context.mock(ConnectionRegistry.class);
|
||||
final PluginManager pluginManager = context.mock(PluginManager.class);
|
||||
final SecureRandom random = context.mock(SecureRandom.class);
|
||||
final Clock clock = context.mock(Clock.class);
|
||||
PluginManager pluginManager = context.mock(PluginManager.class);
|
||||
SecureRandom random = context.mock(SecureRandom.class);
|
||||
Clock clock = context.mock(Clock.class);
|
||||
|
||||
final Plugin plugin = context.mock(Plugin.class);
|
||||
final TransportId transportId = new TransportId("id");
|
||||
final List<ContactId> connected = Collections.singletonList(contactId);
|
||||
Plugin plugin = context.mock(Plugin.class);
|
||||
TransportId transportId = new TransportId("id");
|
||||
List<ContactId> connected = Collections.singletonList(contactId);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
allowing(plugin).getId();
|
||||
|
||||
@@ -145,22 +145,19 @@ public class LanTcpPluginTest extends BrambleTestCase {
|
||||
assertEquals(2, split.length);
|
||||
String addrString = split[0];
|
||||
// Listen on the same interface as the plugin
|
||||
final ServerSocket ss = new ServerSocket();
|
||||
ServerSocket ss = new ServerSocket();
|
||||
ss.bind(new InetSocketAddress(addrString, 0), 10);
|
||||
int port = ss.getLocalPort();
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
final AtomicBoolean error = new AtomicBoolean(false);
|
||||
new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
ss.accept();
|
||||
latch.countDown();
|
||||
} catch (IOException e) {
|
||||
error.set(true);
|
||||
}
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
AtomicBoolean error = new AtomicBoolean(false);
|
||||
new Thread(() -> {
|
||||
try {
|
||||
ss.accept();
|
||||
latch.countDown();
|
||||
} catch (IOException e) {
|
||||
error.set(true);
|
||||
}
|
||||
}.start();
|
||||
}).start();
|
||||
// Tell the plugin about the port
|
||||
TransportProperties p = new TransportProperties();
|
||||
p.put("ipPorts", addrString + ":" + port);
|
||||
@@ -194,8 +191,7 @@ public class LanTcpPluginTest extends BrambleTestCase {
|
||||
plugin.createKeyAgreementListener(new byte[COMMIT_LENGTH]);
|
||||
assertNotNull(kal);
|
||||
Callable<KeyAgreementConnection> c = kal.listen();
|
||||
FutureTask<KeyAgreementConnection> f =
|
||||
new FutureTask<KeyAgreementConnection>(c);
|
||||
FutureTask<KeyAgreementConnection> f = new FutureTask<>(c);
|
||||
new Thread(f).start();
|
||||
// The plugin should have bound a socket and stored the port number
|
||||
BdfList descriptor = kal.getDescriptor();
|
||||
@@ -240,21 +236,18 @@ public class LanTcpPluginTest extends BrambleTestCase {
|
||||
assertEquals(2, split.length);
|
||||
String addrString = split[0];
|
||||
// Listen on the same interface as the plugin
|
||||
final ServerSocket ss = new ServerSocket();
|
||||
ServerSocket ss = new ServerSocket();
|
||||
ss.bind(new InetSocketAddress(addrString, 0), 10);
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
final AtomicBoolean error = new AtomicBoolean(false);
|
||||
new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
ss.accept();
|
||||
latch.countDown();
|
||||
} catch (IOException e) {
|
||||
error.set(true);
|
||||
}
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
AtomicBoolean error = new AtomicBoolean(false);
|
||||
new Thread(() -> {
|
||||
try {
|
||||
ss.accept();
|
||||
latch.countDown();
|
||||
} catch (IOException e) {
|
||||
error.set(true);
|
||||
}
|
||||
}.start();
|
||||
}).start();
|
||||
// Tell the plugin about the port
|
||||
BdfList descriptor = new BdfList();
|
||||
descriptor.add(TRANSPORT_ID_LAN);
|
||||
@@ -291,7 +284,7 @@ public class LanTcpPluginTest extends BrambleTestCase {
|
||||
private static class Callback implements DuplexPluginCallback {
|
||||
|
||||
private final Map<ContactId, TransportProperties> remote =
|
||||
new Hashtable<ContactId, TransportProperties>();
|
||||
new Hashtable<>();
|
||||
private final CountDownLatch propertiesLatch = new CountDownLatch(1);
|
||||
private final CountDownLatch connectionsLatch = new CountDownLatch(1);
|
||||
private final TransportProperties local = new TransportProperties();
|
||||
|
||||
@@ -0,0 +1,659 @@
|
||||
package org.briarproject.bramble.properties;
|
||||
|
||||
import org.briarproject.bramble.api.client.ClientHelper;
|
||||
import org.briarproject.bramble.api.client.ContactGroupFactory;
|
||||
import org.briarproject.bramble.api.contact.Contact;
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||
import org.briarproject.bramble.api.data.BdfEntry;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.api.data.MetadataParser;
|
||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||
import org.briarproject.bramble.api.db.Metadata;
|
||||
import org.briarproject.bramble.api.db.Transaction;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.AuthorId;
|
||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||
import org.briarproject.bramble.api.plugin.TransportId;
|
||||
import org.briarproject.bramble.api.properties.TransportProperties;
|
||||
import org.briarproject.bramble.api.sync.Group;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.bramble.api.sync.Message;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||
import org.jmock.Expectations;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||
import static org.briarproject.bramble.api.properties.TransportPropertyManager.CLIENT_ID;
|
||||
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_GROUP_DESCRIPTOR_LENGTH;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
||||
|
||||
private final DatabaseComponent db = context.mock(DatabaseComponent.class);
|
||||
private final ClientHelper clientHelper = context.mock(ClientHelper.class);
|
||||
private final MetadataParser metadataParser =
|
||||
context.mock(MetadataParser.class);
|
||||
private final ContactGroupFactory contactGroupFactory =
|
||||
context.mock(ContactGroupFactory.class);
|
||||
private final Clock clock = context.mock(Clock.class);
|
||||
|
||||
private final Group localGroup = getGroup();
|
||||
private final LocalAuthor localAuthor = getLocalAuthor();
|
||||
private final BdfDictionary fooPropertiesDict = BdfDictionary.of(
|
||||
new BdfEntry("fooKey1", "fooValue1"),
|
||||
new BdfEntry("fooKey2", "fooValue2")
|
||||
);
|
||||
private final BdfDictionary barPropertiesDict = BdfDictionary.of(
|
||||
new BdfEntry("barKey1", "barValue1"),
|
||||
new BdfEntry("barKey2", "barValue2")
|
||||
);
|
||||
private final TransportProperties fooProperties, barProperties;
|
||||
|
||||
private int nextContactId = 0;
|
||||
|
||||
public TransportPropertyManagerImplTest() throws Exception {
|
||||
fooProperties = new TransportProperties();
|
||||
for (String key : fooPropertiesDict.keySet())
|
||||
fooProperties.put(key, fooPropertiesDict.getString(key));
|
||||
barProperties = new TransportProperties();
|
||||
for (String key : barPropertiesDict.keySet())
|
||||
barProperties.put(key, barPropertiesDict.getString(key));
|
||||
}
|
||||
|
||||
private TransportPropertyManagerImpl createInstance() {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(contactGroupFactory).createLocalGroup(CLIENT_ID);
|
||||
will(returnValue(localGroup));
|
||||
}});
|
||||
return new TransportPropertyManagerImpl(db, clientHelper,
|
||||
metadataParser, contactGroupFactory, clock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreatesGroupsAtStartup() throws Exception {
|
||||
Transaction txn = new Transaction(null, false);
|
||||
Contact contact1 = getContact(true);
|
||||
Contact contact2 = getContact(true);
|
||||
List<Contact> contacts = Arrays.asList(contact1, contact2);
|
||||
Group contactGroup1 = getGroup(), contactGroup2 = getGroup();
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).addGroup(txn, localGroup);
|
||||
oneOf(db).getContacts(txn);
|
||||
will(returnValue(contacts));
|
||||
// The first contact's group has already been set up
|
||||
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, contact1);
|
||||
will(returnValue(contactGroup1));
|
||||
oneOf(db).containsGroup(txn, contactGroup1.getId());
|
||||
will(returnValue(true));
|
||||
// The second contact's group hasn't been set up
|
||||
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, contact2);
|
||||
will(returnValue(contactGroup2));
|
||||
oneOf(db).containsGroup(txn, contactGroup2.getId());
|
||||
will(returnValue(false));
|
||||
oneOf(db).addGroup(txn, contactGroup2);
|
||||
oneOf(db).setGroupVisibility(txn, contact2.getId(),
|
||||
contactGroup2.getId(), SHARED);
|
||||
}});
|
||||
// Copy the latest local properties into the group
|
||||
expectGetLocalProperties(txn);
|
||||
expectStoreMessage(txn, contactGroup2.getId(), "foo", fooPropertiesDict,
|
||||
1, true, true);
|
||||
expectStoreMessage(txn, contactGroup2.getId(), "bar", barPropertiesDict,
|
||||
1, true, true);
|
||||
|
||||
TransportPropertyManagerImpl t = createInstance();
|
||||
t.createLocalState(txn);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreatesGroupWhenAddingContact() throws Exception {
|
||||
Transaction txn = new Transaction(null, false);
|
||||
Contact contact = getContact(true);
|
||||
Group contactGroup = getGroup();
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
// Create the group and share it with the contact
|
||||
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, contact);
|
||||
will(returnValue(contactGroup));
|
||||
oneOf(db).containsGroup(txn, contactGroup.getId());
|
||||
will(returnValue(false));
|
||||
oneOf(db).addGroup(txn, contactGroup);
|
||||
oneOf(db).setGroupVisibility(txn, contact.getId(),
|
||||
contactGroup.getId(), SHARED);
|
||||
}});
|
||||
// Copy the latest local properties into the group
|
||||
expectGetLocalProperties(txn);
|
||||
expectStoreMessage(txn, contactGroup.getId(), "foo", fooPropertiesDict,
|
||||
1, true, true);
|
||||
expectStoreMessage(txn, contactGroup.getId(), "bar", barPropertiesDict,
|
||||
1, true, true);
|
||||
|
||||
TransportPropertyManagerImpl t = createInstance();
|
||||
t.addingContact(txn, contact);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemovesGroupWhenRemovingContact() throws Exception {
|
||||
Transaction txn = new Transaction(null, false);
|
||||
Contact contact = getContact(true);
|
||||
Group contactGroup = getGroup();
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, contact);
|
||||
will(returnValue(contactGroup));
|
||||
oneOf(db).removeGroup(txn, contactGroup);
|
||||
}});
|
||||
|
||||
TransportPropertyManagerImpl t = createInstance();
|
||||
t.removingContact(txn, contact);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoesNotDeleteAnythingWhenFirstUpdateIsDelivered()
|
||||
throws Exception {
|
||||
Transaction txn = new Transaction(null, false);
|
||||
GroupId contactGroupId = new GroupId(getRandomId());
|
||||
long timestamp = 123456789;
|
||||
Message message = getMessage(contactGroupId, timestamp);
|
||||
Metadata meta = new Metadata();
|
||||
BdfDictionary metaDictionary = BdfDictionary.of(
|
||||
new BdfEntry("transportId", "foo"),
|
||||
new BdfEntry("version", 2),
|
||||
new BdfEntry("local", false)
|
||||
);
|
||||
Map<MessageId, BdfDictionary> messageMetadata =
|
||||
new LinkedHashMap<>();
|
||||
// A remote update for another transport should be ignored
|
||||
MessageId barUpdateId = new MessageId(getRandomId());
|
||||
messageMetadata.put(barUpdateId, BdfDictionary.of(
|
||||
new BdfEntry("transportId", "bar"),
|
||||
new BdfEntry("version", 1),
|
||||
new BdfEntry("local", false)
|
||||
));
|
||||
// A local update for the same transport should be ignored
|
||||
MessageId localUpdateId = new MessageId(getRandomId());
|
||||
messageMetadata.put(localUpdateId, BdfDictionary.of(
|
||||
new BdfEntry("transportId", "foo"),
|
||||
new BdfEntry("version", 1),
|
||||
new BdfEntry("local", true)
|
||||
));
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(metadataParser).parse(meta);
|
||||
will(returnValue(metaDictionary));
|
||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||
contactGroupId);
|
||||
will(returnValue(messageMetadata));
|
||||
}});
|
||||
|
||||
TransportPropertyManagerImpl t = createInstance();
|
||||
assertFalse(t.incomingMessage(txn, message, meta));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeletesOlderUpdatesWhenUpdateIsDelivered()
|
||||
throws Exception {
|
||||
Transaction txn = new Transaction(null, false);
|
||||
GroupId contactGroupId = new GroupId(getRandomId());
|
||||
long timestamp = 123456789;
|
||||
Message message = getMessage(contactGroupId, timestamp);
|
||||
Metadata meta = new Metadata();
|
||||
// Version 4 is being delivered
|
||||
BdfDictionary metaDictionary = BdfDictionary.of(
|
||||
new BdfEntry("transportId", "foo"),
|
||||
new BdfEntry("version", 4),
|
||||
new BdfEntry("local", false)
|
||||
);
|
||||
Map<MessageId, BdfDictionary> messageMetadata =
|
||||
new LinkedHashMap<>();
|
||||
// An older remote update for the same transport should be deleted
|
||||
MessageId fooVersion3 = new MessageId(getRandomId());
|
||||
messageMetadata.put(fooVersion3, BdfDictionary.of(
|
||||
new BdfEntry("transportId", "foo"),
|
||||
new BdfEntry("version", 3),
|
||||
new BdfEntry("local", false)
|
||||
));
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(metadataParser).parse(meta);
|
||||
will(returnValue(metaDictionary));
|
||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||
contactGroupId);
|
||||
will(returnValue(messageMetadata));
|
||||
// The previous update (version 3) should be deleted
|
||||
oneOf(db).deleteMessage(txn, fooVersion3);
|
||||
oneOf(db).deleteMessageMetadata(txn, fooVersion3);
|
||||
}});
|
||||
|
||||
TransportPropertyManagerImpl t = createInstance();
|
||||
assertFalse(t.incomingMessage(txn, message, meta));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeletesObsoleteUpdateWhenDelivered() throws Exception {
|
||||
Transaction txn = new Transaction(null, false);
|
||||
GroupId contactGroupId = new GroupId(getRandomId());
|
||||
long timestamp = 123456789;
|
||||
Message message = getMessage(contactGroupId, timestamp);
|
||||
Metadata meta = new Metadata();
|
||||
// Version 3 is being delivered
|
||||
BdfDictionary metaDictionary = BdfDictionary.of(
|
||||
new BdfEntry("transportId", "foo"),
|
||||
new BdfEntry("version", 3),
|
||||
new BdfEntry("local", false)
|
||||
);
|
||||
Map<MessageId, BdfDictionary> messageMetadata =
|
||||
new LinkedHashMap<>();
|
||||
// A newer remote update for the same transport should not be deleted
|
||||
MessageId fooVersion4 = new MessageId(getRandomId());
|
||||
messageMetadata.put(fooVersion4, BdfDictionary.of(
|
||||
new BdfEntry("transportId", "foo"),
|
||||
new BdfEntry("version", 4),
|
||||
new BdfEntry("local", false)
|
||||
));
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(metadataParser).parse(meta);
|
||||
will(returnValue(metaDictionary));
|
||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||
contactGroupId);
|
||||
will(returnValue(messageMetadata));
|
||||
// The update being delivered (version 3) should be deleted
|
||||
oneOf(db).deleteMessage(txn, message.getId());
|
||||
oneOf(db).deleteMessageMetadata(txn, message.getId());
|
||||
}});
|
||||
|
||||
TransportPropertyManagerImpl t = createInstance();
|
||||
assertFalse(t.incomingMessage(txn, message, meta));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStoresRemotePropertiesWithVersion0() throws Exception {
|
||||
Contact contact = getContact(true);
|
||||
Group contactGroup = getGroup();
|
||||
Transaction txn = new Transaction(null, false);
|
||||
Map<TransportId, TransportProperties> properties =
|
||||
new LinkedHashMap<>();
|
||||
properties.put(new TransportId("foo"), fooProperties);
|
||||
properties.put(new TransportId("bar"), barProperties);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).getContact(txn, contact.getId());
|
||||
will(returnValue(contact));
|
||||
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, contact);
|
||||
will(returnValue(contactGroup));
|
||||
}});
|
||||
expectStoreMessage(txn, contactGroup.getId(), "foo", fooPropertiesDict,
|
||||
0, false, false);
|
||||
expectStoreMessage(txn, contactGroup.getId(), "bar", barPropertiesDict,
|
||||
0, false, false);
|
||||
|
||||
TransportPropertyManagerImpl t = createInstance();
|
||||
t.addRemoteProperties(txn, contact.getId(), properties);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnsLatestLocalProperties() throws Exception {
|
||||
Transaction txn = new Transaction(null, true);
|
||||
|
||||
expectGetLocalProperties(txn);
|
||||
|
||||
TransportPropertyManagerImpl t = createInstance();
|
||||
Map<TransportId, TransportProperties> local = t.getLocalProperties(txn);
|
||||
assertEquals(2, local.size());
|
||||
assertEquals(fooProperties, local.get(new TransportId("foo")));
|
||||
assertEquals(barProperties, local.get(new TransportId("bar")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnsEmptyPropertiesIfNoLocalPropertiesAreFound()
|
||||
throws Exception {
|
||||
Transaction txn = new Transaction(null, true);
|
||||
Map<MessageId, BdfDictionary> messageMetadata =
|
||||
new LinkedHashMap<>();
|
||||
// A local update for another transport should be ignored
|
||||
MessageId barUpdateId = new MessageId(getRandomId());
|
||||
messageMetadata.put(barUpdateId, BdfDictionary.of(
|
||||
new BdfEntry("transportId", "bar"),
|
||||
new BdfEntry("version", 1),
|
||||
new BdfEntry("local", true)
|
||||
));
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||
localGroup.getId());
|
||||
will(returnValue(messageMetadata));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
TransportPropertyManagerImpl t = createInstance();
|
||||
assertEquals(0, t.getLocalProperties(new TransportId("foo")).size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnsLocalProperties() throws Exception {
|
||||
Transaction txn = new Transaction(null, true);
|
||||
Map<MessageId, BdfDictionary> messageMetadata =
|
||||
new LinkedHashMap<>();
|
||||
// A local update for another transport should be ignored
|
||||
MessageId barUpdateId = new MessageId(getRandomId());
|
||||
messageMetadata.put(barUpdateId, BdfDictionary.of(
|
||||
new BdfEntry("transportId", "bar"),
|
||||
new BdfEntry("version", 1),
|
||||
new BdfEntry("local", true)
|
||||
));
|
||||
// A local update for the right transport should be returned
|
||||
MessageId fooUpdateId = new MessageId(getRandomId());
|
||||
messageMetadata.put(fooUpdateId, BdfDictionary.of(
|
||||
new BdfEntry("transportId", "foo"),
|
||||
new BdfEntry("version", 1),
|
||||
new BdfEntry("local", true)
|
||||
));
|
||||
BdfList fooUpdate = BdfList.of("foo", 1, fooPropertiesDict);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||
localGroup.getId());
|
||||
will(returnValue(messageMetadata));
|
||||
oneOf(clientHelper).getMessageAsList(txn, fooUpdateId);
|
||||
will(returnValue(fooUpdate));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
TransportPropertyManagerImpl t = createInstance();
|
||||
assertEquals(fooProperties,
|
||||
t.getLocalProperties(new TransportId("foo")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnsRemotePropertiesOrEmptyProperties()
|
||||
throws Exception {
|
||||
Transaction txn = new Transaction(null, true);
|
||||
Contact contact1 = getContact(false);
|
||||
Contact contact2 = getContact(true);
|
||||
Contact contact3 = getContact(true);
|
||||
List<Contact> contacts =
|
||||
Arrays.asList(contact1, contact2, contact3);
|
||||
Group contactGroup2 = getGroup();
|
||||
Group contactGroup3 = getGroup();
|
||||
Map<MessageId, BdfDictionary> messageMetadata3 =
|
||||
new LinkedHashMap<>();
|
||||
// A remote update for another transport should be ignored
|
||||
MessageId barUpdateId = new MessageId(getRandomId());
|
||||
messageMetadata3.put(barUpdateId, BdfDictionary.of(
|
||||
new BdfEntry("transportId", "bar"),
|
||||
new BdfEntry("version", 1),
|
||||
new BdfEntry("local", false)
|
||||
));
|
||||
// A local update for the right transport should be ignored
|
||||
MessageId localUpdateId = new MessageId(getRandomId());
|
||||
messageMetadata3.put(localUpdateId, BdfDictionary.of(
|
||||
new BdfEntry("transportId", "foo"),
|
||||
new BdfEntry("version", 1),
|
||||
new BdfEntry("local", true)
|
||||
));
|
||||
// A remote update for the right transport should be returned
|
||||
MessageId fooUpdateId = new MessageId(getRandomId());
|
||||
messageMetadata3.put(fooUpdateId, BdfDictionary.of(
|
||||
new BdfEntry("transportId", "foo"),
|
||||
new BdfEntry("version", 1),
|
||||
new BdfEntry("local", false)
|
||||
));
|
||||
BdfList fooUpdate = BdfList.of("foo", 1, fooPropertiesDict);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(db).getContacts(txn);
|
||||
will(returnValue(contacts));
|
||||
// First contact: skipped because not active
|
||||
// Second contact: no updates
|
||||
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, contact2);
|
||||
will(returnValue(contactGroup2));
|
||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||
contactGroup2.getId());
|
||||
will(returnValue(Collections.emptyMap()));
|
||||
// Third contact: returns an update
|
||||
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, contact3);
|
||||
will(returnValue(contactGroup3));
|
||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||
contactGroup3.getId());
|
||||
will(returnValue(messageMetadata3));
|
||||
oneOf(clientHelper).getMessageAsList(txn, fooUpdateId);
|
||||
will(returnValue(fooUpdate));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
TransportPropertyManagerImpl t = createInstance();
|
||||
Map<ContactId, TransportProperties> properties =
|
||||
t.getRemoteProperties(new TransportId("foo"));
|
||||
assertEquals(3, properties.size());
|
||||
assertEquals(0, properties.get(contact1.getId()).size());
|
||||
assertEquals(0, properties.get(contact2.getId()).size());
|
||||
assertEquals(fooProperties, properties.get(contact3.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMergingUnchangedPropertiesDoesNotCreateUpdate()
|
||||
throws Exception {
|
||||
Transaction txn = new Transaction(null, false);
|
||||
MessageId updateId = new MessageId(getRandomId());
|
||||
Map<MessageId, BdfDictionary> messageMetadata =
|
||||
Collections.singletonMap(updateId, BdfDictionary.of(
|
||||
new BdfEntry("transportId", "foo"),
|
||||
new BdfEntry("version", 1),
|
||||
new BdfEntry("local", true)
|
||||
));
|
||||
BdfList update = BdfList.of("foo", 1, fooPropertiesDict);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn));
|
||||
// Merge the new properties with the existing properties
|
||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||
localGroup.getId());
|
||||
will(returnValue(messageMetadata));
|
||||
oneOf(clientHelper).getMessageAsList(txn, updateId);
|
||||
will(returnValue(update));
|
||||
// Properties are unchanged so we're done
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
TransportPropertyManagerImpl t = createInstance();
|
||||
t.mergeLocalProperties(new TransportId("foo"), fooProperties);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMergingNewPropertiesCreatesUpdate() throws Exception {
|
||||
Transaction txn = new Transaction(null, false);
|
||||
Contact contact = getContact(true);
|
||||
Group contactGroup = getGroup();
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn));
|
||||
// There are no existing properties to merge with
|
||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||
localGroup.getId());
|
||||
will(returnValue(Collections.emptyMap()));
|
||||
// Store the new properties in the local group, version 1
|
||||
expectStoreMessage(txn, localGroup.getId(), "foo",
|
||||
fooPropertiesDict, 1, true, false);
|
||||
// Store the new properties in each contact's group, version 1
|
||||
oneOf(db).getContacts(txn);
|
||||
will(returnValue(Collections.singletonList(contact)));
|
||||
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, contact);
|
||||
will(returnValue(contactGroup));
|
||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||
contactGroup.getId());
|
||||
will(returnValue(Collections.emptyMap()));
|
||||
expectStoreMessage(txn, contactGroup.getId(), "foo",
|
||||
fooPropertiesDict, 1, true, true);
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
TransportPropertyManagerImpl t = createInstance();
|
||||
t.mergeLocalProperties(new TransportId("foo"), fooProperties);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMergingUpdatedPropertiesCreatesUpdate() throws Exception {
|
||||
Transaction txn = new Transaction(null, false);
|
||||
Contact contact = getContact(true);
|
||||
Group contactGroup = getGroup();
|
||||
BdfDictionary oldMetadata = BdfDictionary.of(
|
||||
new BdfEntry("transportId", "foo"),
|
||||
new BdfEntry("version", 1),
|
||||
new BdfEntry("local", true)
|
||||
);
|
||||
MessageId localGroupUpdateId = new MessageId(getRandomId());
|
||||
Map<MessageId, BdfDictionary> localGroupMessageMetadata =
|
||||
Collections.singletonMap(localGroupUpdateId, oldMetadata);
|
||||
MessageId contactGroupUpdateId = new MessageId(getRandomId());
|
||||
Map<MessageId, BdfDictionary> contactGroupMessageMetadata =
|
||||
Collections.singletonMap(contactGroupUpdateId, oldMetadata);
|
||||
BdfList oldUpdate = BdfList.of("foo", 1, BdfDictionary.of(
|
||||
new BdfEntry("fooKey1", "oldFooValue1")
|
||||
));
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(false);
|
||||
will(returnValue(txn));
|
||||
// Merge the new properties with the existing properties
|
||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||
localGroup.getId());
|
||||
will(returnValue(localGroupMessageMetadata));
|
||||
oneOf(clientHelper).getMessageAsList(txn, localGroupUpdateId);
|
||||
will(returnValue(oldUpdate));
|
||||
// Store the merged properties in the local group, version 2
|
||||
expectStoreMessage(txn, localGroup.getId(), "foo",
|
||||
fooPropertiesDict, 2, true, false);
|
||||
// Delete the previous update
|
||||
oneOf(db).removeMessage(txn, localGroupUpdateId);
|
||||
// Store the merged properties in each contact's group, version 2
|
||||
oneOf(db).getContacts(txn);
|
||||
will(returnValue(Collections.singletonList(contact)));
|
||||
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, contact);
|
||||
will(returnValue(contactGroup));
|
||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||
contactGroup.getId());
|
||||
will(returnValue(contactGroupMessageMetadata));
|
||||
expectStoreMessage(txn, contactGroup.getId(), "foo",
|
||||
fooPropertiesDict, 2, true, true);
|
||||
// Delete the previous update
|
||||
oneOf(db).removeMessage(txn, contactGroupUpdateId);
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
TransportPropertyManagerImpl t = createInstance();
|
||||
t.mergeLocalProperties(new TransportId("foo"), fooProperties);
|
||||
}
|
||||
|
||||
private Group getGroup() {
|
||||
GroupId g = new GroupId(getRandomId());
|
||||
byte[] descriptor = getRandomBytes(MAX_GROUP_DESCRIPTOR_LENGTH);
|
||||
return new Group(g, CLIENT_ID, descriptor);
|
||||
}
|
||||
|
||||
private LocalAuthor getLocalAuthor() {
|
||||
AuthorId id = new AuthorId(getRandomId());
|
||||
String name = getRandomString(MAX_AUTHOR_NAME_LENGTH);
|
||||
byte[] publicKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
byte[] privateKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
long created = System.currentTimeMillis();
|
||||
return new LocalAuthor(id, name, publicKey, privateKey, created);
|
||||
}
|
||||
|
||||
private Contact getContact(boolean active) {
|
||||
ContactId c = new ContactId(nextContactId++);
|
||||
AuthorId a = new AuthorId(getRandomId());
|
||||
String name = getRandomString(MAX_AUTHOR_NAME_LENGTH);
|
||||
byte[] publicKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
return new Contact(c, new Author(a, name, publicKey),
|
||||
localAuthor.getId(), true, active);
|
||||
}
|
||||
|
||||
private Message getMessage(GroupId g, long timestamp) {
|
||||
MessageId messageId = new MessageId(getRandomId());
|
||||
byte[] raw = getRandomBytes(MAX_MESSAGE_BODY_LENGTH);
|
||||
return new Message(messageId, g, timestamp, raw);
|
||||
}
|
||||
|
||||
private void expectGetLocalProperties(Transaction txn) throws Exception {
|
||||
Map<MessageId, BdfDictionary> messageMetadata = new LinkedHashMap<>();
|
||||
// The latest update for transport "foo" should be returned
|
||||
MessageId fooVersion999 = new MessageId(getRandomId());
|
||||
messageMetadata.put(fooVersion999, BdfDictionary.of(
|
||||
new BdfEntry("transportId", "foo"),
|
||||
new BdfEntry("version", 999)
|
||||
));
|
||||
// The latest update for transport "bar" should be returned
|
||||
MessageId barVersion3 = new MessageId(getRandomId());
|
||||
messageMetadata.put(barVersion3, BdfDictionary.of(
|
||||
new BdfEntry("transportId", "bar"),
|
||||
new BdfEntry("version", 3)
|
||||
));
|
||||
BdfList fooUpdate = BdfList.of("foo", 999, fooPropertiesDict);
|
||||
BdfList barUpdate = BdfList.of("bar", 3, barPropertiesDict);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
// Find the latest local update for each transport
|
||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||
localGroup.getId());
|
||||
will(returnValue(messageMetadata));
|
||||
// Retrieve and parse the latest local properties
|
||||
oneOf(clientHelper).getMessageAsList(txn, fooVersion999);
|
||||
will(returnValue(fooUpdate));
|
||||
oneOf(clientHelper).getMessageAsList(txn, barVersion3);
|
||||
will(returnValue(barUpdate));
|
||||
}});
|
||||
}
|
||||
|
||||
private void expectStoreMessage(Transaction txn, GroupId g,
|
||||
String transportId, BdfDictionary properties, long version,
|
||||
boolean local, boolean shared) throws Exception {
|
||||
long timestamp = 123456789;
|
||||
BdfList body = BdfList.of(transportId, version, properties);
|
||||
Message message = getMessage(g, timestamp);
|
||||
BdfDictionary meta = BdfDictionary.of(
|
||||
new BdfEntry("transportId", transportId),
|
||||
new BdfEntry("version", version),
|
||||
new BdfEntry("local", local)
|
||||
);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(clock).currentTimeMillis();
|
||||
will(returnValue(timestamp));
|
||||
oneOf(clientHelper).createMessage(g, timestamp, body);
|
||||
will(returnValue(message));
|
||||
oneOf(clientHelper).addLocalMessage(txn, message, meta, shared);
|
||||
}});
|
||||
}
|
||||
}
|
||||
@@ -6,10 +6,10 @@ import org.briarproject.bramble.api.db.Transaction;
|
||||
import org.briarproject.bramble.api.event.EventBus;
|
||||
import org.briarproject.bramble.api.sync.Ack;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.api.sync.RecordWriter;
|
||||
import org.briarproject.bramble.test.BrambleTestCase;
|
||||
import org.briarproject.bramble.test.ImmediateExecutor;
|
||||
import org.briarproject.bramble.test.TestUtils;
|
||||
import org.briarproject.bramble.api.sync.RecordWriter;
|
||||
import org.jmock.Expectations;
|
||||
import org.jmock.Mockery;
|
||||
import org.junit.Test;
|
||||
@@ -44,10 +44,10 @@ public class SimplexOutgoingSessionTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testNothingToSend() throws Exception {
|
||||
final SimplexOutgoingSession session = new SimplexOutgoingSession(db,
|
||||
SimplexOutgoingSession session = new SimplexOutgoingSession(db,
|
||||
dbExecutor, eventBus, contactId, maxLatency, recordWriter);
|
||||
final Transaction noAckTxn = new Transaction(null, false);
|
||||
final Transaction noMsgTxn = new Transaction(null, false);
|
||||
Transaction noAckTxn = new Transaction(null, false);
|
||||
Transaction noMsgTxn = new Transaction(null, false);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
// Add listener
|
||||
@@ -80,14 +80,14 @@ public class SimplexOutgoingSessionTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testSomethingToSend() throws Exception {
|
||||
final Ack ack = new Ack(Collections.singletonList(messageId));
|
||||
final byte[] raw = new byte[1234];
|
||||
final SimplexOutgoingSession session = new SimplexOutgoingSession(db,
|
||||
Ack ack = new Ack(Collections.singletonList(messageId));
|
||||
byte[] raw = new byte[1234];
|
||||
SimplexOutgoingSession session = new SimplexOutgoingSession(db,
|
||||
dbExecutor, eventBus, contactId, maxLatency, recordWriter);
|
||||
final Transaction ackTxn = new Transaction(null, false);
|
||||
final Transaction noAckTxn = new Transaction(null, false);
|
||||
final Transaction msgTxn = new Transaction(null, false);
|
||||
final Transaction noMsgTxn = new Transaction(null, false);
|
||||
Transaction ackTxn = new Transaction(null, false);
|
||||
Transaction noAckTxn = new Transaction(null, false);
|
||||
Transaction msgTxn = new Transaction(null, false);
|
||||
Transaction noMsgTxn = new Transaction(null, false);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
// Add listener
|
||||
|
||||
@@ -92,9 +92,9 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
|
||||
@Test
|
||||
public void testStartAndStop() throws Exception {
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
final Transaction txn1 = new Transaction(null, true);
|
||||
final Transaction txn2 = new Transaction(null, true);
|
||||
Transaction txn = new Transaction(null, true);
|
||||
Transaction txn1 = new Transaction(null, true);
|
||||
Transaction txn2 = new Transaction(null, true);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
// validateOutstandingMessages()
|
||||
@@ -126,13 +126,13 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
|
||||
@Test
|
||||
public void testMessagesAreValidatedAtStartup() throws Exception {
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
final Transaction txn1 = new Transaction(null, true);
|
||||
final Transaction txn2 = new Transaction(null, false);
|
||||
final Transaction txn3 = new Transaction(null, true);
|
||||
final Transaction txn4 = new Transaction(null, false);
|
||||
final Transaction txn5 = new Transaction(null, true);
|
||||
final Transaction txn6 = new Transaction(null, true);
|
||||
Transaction txn = new Transaction(null, true);
|
||||
Transaction txn1 = new Transaction(null, true);
|
||||
Transaction txn2 = new Transaction(null, false);
|
||||
Transaction txn3 = new Transaction(null, true);
|
||||
Transaction txn4 = new Transaction(null, false);
|
||||
Transaction txn5 = new Transaction(null, true);
|
||||
Transaction txn6 = new Transaction(null, true);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
// Get messages to validate
|
||||
@@ -217,11 +217,11 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
|
||||
@Test
|
||||
public void testPendingMessagesAreDeliveredAtStartup() throws Exception {
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
final Transaction txn1 = new Transaction(null, true);
|
||||
final Transaction txn2 = new Transaction(null, false);
|
||||
final Transaction txn3 = new Transaction(null, false);
|
||||
final Transaction txn4 = new Transaction(null, true);
|
||||
Transaction txn = new Transaction(null, true);
|
||||
Transaction txn1 = new Transaction(null, true);
|
||||
Transaction txn2 = new Transaction(null, false);
|
||||
Transaction txn3 = new Transaction(null, false);
|
||||
Transaction txn4 = new Transaction(null, true);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
// Get messages to validate
|
||||
@@ -303,11 +303,11 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
|
||||
@Test
|
||||
public void testMessagesAreSharedAtStartup() throws Exception {
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
final Transaction txn1 = new Transaction(null, true);
|
||||
final Transaction txn2 = new Transaction(null, true);
|
||||
final Transaction txn3 = new Transaction(null, false);
|
||||
final Transaction txn4 = new Transaction(null, false);
|
||||
Transaction txn = new Transaction(null, true);
|
||||
Transaction txn1 = new Transaction(null, true);
|
||||
Transaction txn2 = new Transaction(null, true);
|
||||
Transaction txn3 = new Transaction(null, false);
|
||||
Transaction txn4 = new Transaction(null, false);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
// No messages to validate
|
||||
@@ -355,9 +355,9 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
|
||||
@Test
|
||||
public void testIncomingMessagesAreShared() throws Exception {
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
final Transaction txn1 = new Transaction(null, false);
|
||||
final Transaction txn2 = new Transaction(null, false);
|
||||
Transaction txn = new Transaction(null, true);
|
||||
Transaction txn1 = new Transaction(null, false);
|
||||
Transaction txn2 = new Transaction(null, false);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
// Load the group
|
||||
@@ -405,12 +405,12 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
@Test
|
||||
public void testValidationContinuesAfterNoSuchMessageException()
|
||||
throws Exception {
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
final Transaction txn1 = new Transaction(null, true);
|
||||
final Transaction txn2 = new Transaction(null, true);
|
||||
final Transaction txn3 = new Transaction(null, false);
|
||||
final Transaction txn4 = new Transaction(null, true);
|
||||
final Transaction txn5 = new Transaction(null, true);
|
||||
Transaction txn = new Transaction(null, true);
|
||||
Transaction txn1 = new Transaction(null, true);
|
||||
Transaction txn2 = new Transaction(null, true);
|
||||
Transaction txn3 = new Transaction(null, false);
|
||||
Transaction txn4 = new Transaction(null, true);
|
||||
Transaction txn5 = new Transaction(null, true);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
// Get messages to validate
|
||||
@@ -476,12 +476,12 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
@Test
|
||||
public void testValidationContinuesAfterNoSuchGroupException()
|
||||
throws Exception {
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
final Transaction txn1 = new Transaction(null, true);
|
||||
final Transaction txn2 = new Transaction(null, true);
|
||||
final Transaction txn3 = new Transaction(null, false);
|
||||
final Transaction txn4 = new Transaction(null, true);
|
||||
final Transaction txn5 = new Transaction(null, true);
|
||||
Transaction txn = new Transaction(null, true);
|
||||
Transaction txn1 = new Transaction(null, true);
|
||||
Transaction txn2 = new Transaction(null, true);
|
||||
Transaction txn3 = new Transaction(null, false);
|
||||
Transaction txn4 = new Transaction(null, true);
|
||||
Transaction txn5 = new Transaction(null, true);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
// Get messages to validate
|
||||
@@ -551,8 +551,8 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
|
||||
@Test
|
||||
public void testNonLocalMessagesAreValidatedWhenAdded() throws Exception {
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
final Transaction txn1 = new Transaction(null, false);
|
||||
Transaction txn = new Transaction(null, true);
|
||||
Transaction txn1 = new Transaction(null, false);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
// Load the group
|
||||
@@ -591,8 +591,8 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
@Test
|
||||
public void testMessagesWithUndeliveredDependenciesArePending()
|
||||
throws Exception {
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
final Transaction txn1 = new Transaction(null, false);
|
||||
Transaction txn = new Transaction(null, true);
|
||||
Transaction txn1 = new Transaction(null, false);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
// Load the group
|
||||
@@ -624,8 +624,8 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
@Test
|
||||
public void testMessagesWithDeliveredDependenciesGetDelivered()
|
||||
throws Exception {
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
final Transaction txn1 = new Transaction(null, false);
|
||||
Transaction txn = new Transaction(null, true);
|
||||
Transaction txn1 = new Transaction(null, false);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
// Load the group
|
||||
@@ -663,9 +663,9 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
@Test
|
||||
public void testMessagesWithInvalidDependenciesAreInvalid()
|
||||
throws Exception {
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
final Transaction txn1 = new Transaction(null, false);
|
||||
final Transaction txn2 = new Transaction(null, false);
|
||||
Transaction txn = new Transaction(null, true);
|
||||
Transaction txn1 = new Transaction(null, false);
|
||||
Transaction txn2 = new Transaction(null, false);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
// Load the group
|
||||
@@ -716,19 +716,18 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
|
||||
@Test
|
||||
public void testRecursiveInvalidation() throws Exception {
|
||||
final MessageId messageId3 = new MessageId(TestUtils.getRandomId());
|
||||
final MessageId messageId4 = new MessageId(TestUtils.getRandomId());
|
||||
final Map<MessageId, State> twoDependents =
|
||||
new LinkedHashMap<MessageId, State>();
|
||||
MessageId messageId3 = new MessageId(TestUtils.getRandomId());
|
||||
MessageId messageId4 = new MessageId(TestUtils.getRandomId());
|
||||
Map<MessageId, State> twoDependents = new LinkedHashMap<>();
|
||||
twoDependents.put(messageId1, PENDING);
|
||||
twoDependents.put(messageId2, PENDING);
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
final Transaction txn1 = new Transaction(null, false);
|
||||
final Transaction txn2 = new Transaction(null, false);
|
||||
final Transaction txn3 = new Transaction(null, false);
|
||||
final Transaction txn4 = new Transaction(null, false);
|
||||
final Transaction txn5 = new Transaction(null, false);
|
||||
final Transaction txn6 = new Transaction(null, false);
|
||||
Transaction txn = new Transaction(null, true);
|
||||
Transaction txn1 = new Transaction(null, false);
|
||||
Transaction txn2 = new Transaction(null, false);
|
||||
Transaction txn3 = new Transaction(null, false);
|
||||
Transaction txn4 = new Transaction(null, false);
|
||||
Transaction txn5 = new Transaction(null, false);
|
||||
Transaction txn6 = new Transaction(null, false);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
// Load the group
|
||||
@@ -820,27 +819,25 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
|
||||
@Test
|
||||
public void testPendingDependentsGetDelivered() throws Exception {
|
||||
final MessageId messageId3 = new MessageId(TestUtils.getRandomId());
|
||||
final MessageId messageId4 = new MessageId(TestUtils.getRandomId());
|
||||
final Message message3 = new Message(messageId3, groupId, timestamp,
|
||||
MessageId messageId3 = new MessageId(TestUtils.getRandomId());
|
||||
MessageId messageId4 = new MessageId(TestUtils.getRandomId());
|
||||
Message message3 = new Message(messageId3, groupId, timestamp,
|
||||
raw);
|
||||
final Message message4 = new Message(messageId4, groupId, timestamp,
|
||||
Message message4 = new Message(messageId4, groupId, timestamp,
|
||||
raw);
|
||||
final Map<MessageId, State> twoDependents =
|
||||
new LinkedHashMap<MessageId, State>();
|
||||
Map<MessageId, State> twoDependents = new LinkedHashMap<>();
|
||||
twoDependents.put(messageId1, PENDING);
|
||||
twoDependents.put(messageId2, PENDING);
|
||||
final Map<MessageId, State> twoDependencies =
|
||||
new LinkedHashMap<MessageId, State>();
|
||||
Map<MessageId, State> twoDependencies = new LinkedHashMap<>();
|
||||
twoDependencies.put(messageId1, DELIVERED);
|
||||
twoDependencies.put(messageId2, DELIVERED);
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
final Transaction txn1 = new Transaction(null, false);
|
||||
final Transaction txn2 = new Transaction(null, false);
|
||||
final Transaction txn3 = new Transaction(null, false);
|
||||
final Transaction txn4 = new Transaction(null, false);
|
||||
final Transaction txn5 = new Transaction(null, false);
|
||||
final Transaction txn6 = new Transaction(null, false);
|
||||
Transaction txn = new Transaction(null, true);
|
||||
Transaction txn1 = new Transaction(null, false);
|
||||
Transaction txn2 = new Transaction(null, false);
|
||||
Transaction txn3 = new Transaction(null, false);
|
||||
Transaction txn4 = new Transaction(null, false);
|
||||
Transaction txn5 = new Transaction(null, false);
|
||||
Transaction txn6 = new Transaction(null, false);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
// Load the group
|
||||
@@ -979,13 +976,12 @@ public class ValidationManagerImplTest extends BrambleMockTestCase {
|
||||
|
||||
@Test
|
||||
public void testOnlyReadyPendingDependentsGetDelivered() throws Exception {
|
||||
final Map<MessageId, State> twoDependencies =
|
||||
new LinkedHashMap<MessageId, State>();
|
||||
Map<MessageId, State> twoDependencies = new LinkedHashMap<>();
|
||||
twoDependencies.put(messageId, DELIVERED);
|
||||
twoDependencies.put(messageId2, UNKNOWN);
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
final Transaction txn1 = new Transaction(null, false);
|
||||
final Transaction txn2 = new Transaction(null, false);
|
||||
Transaction txn = new Transaction(null, true);
|
||||
Transaction txn1 = new Transaction(null, false);
|
||||
Transaction txn2 = new Transaction(null, false);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
// Load the group
|
||||
|
||||
@@ -38,7 +38,7 @@ public class LinuxSecureRandomSpiTest extends BrambleTestCase {
|
||||
System.err.println("WARNING: Skipping test, can't run on this OS");
|
||||
return;
|
||||
}
|
||||
Set<Bytes> seeds = new HashSet<Bytes>();
|
||||
Set<Bytes> seeds = new HashSet<>();
|
||||
LinuxSecureRandomSpi engine = new LinuxSecureRandomSpi();
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
byte[] seed = engine.engineGenerateSeed(SEED_BYTES);
|
||||
|
||||
@@ -58,21 +58,21 @@ public class KeyManagerImplTest extends BrambleTestCase {
|
||||
|
||||
@Before
|
||||
public void testStartService() throws Exception {
|
||||
final Transaction txn = new Transaction(null, false);
|
||||
Transaction txn = new Transaction(null, false);
|
||||
AuthorId remoteAuthorId = new AuthorId(getRandomId());
|
||||
Author remoteAuthor = new Author(remoteAuthorId, "author",
|
||||
getRandomBytes(42));
|
||||
AuthorId localAuthorId = new AuthorId(getRandomId());
|
||||
final Collection<Contact> contacts = new ArrayList<Contact>();
|
||||
Collection<Contact> contacts = new ArrayList<>();
|
||||
contacts.add(new Contact(contactId, remoteAuthor, localAuthorId, true,
|
||||
true));
|
||||
contacts.add(new Contact(inactiveContactId, remoteAuthor, localAuthorId,
|
||||
true, false));
|
||||
final SimplexPluginFactory pluginFactory =
|
||||
SimplexPluginFactory pluginFactory =
|
||||
context.mock(SimplexPluginFactory.class);
|
||||
final Collection<SimplexPluginFactory> factories = Collections
|
||||
Collection<SimplexPluginFactory> factories = Collections
|
||||
.singletonList(pluginFactory);
|
||||
final int maxLatency = 1337;
|
||||
int maxLatency = 1337;
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(pluginConfig).getSimplexFactories();
|
||||
@@ -100,9 +100,9 @@ public class KeyManagerImplTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testAddContact() throws Exception {
|
||||
final SecretKey secretKey = getSecretKey();
|
||||
final long timestamp = 42L;
|
||||
final boolean alice = true;
|
||||
SecretKey secretKey = getSecretKey();
|
||||
long timestamp = 42L;
|
||||
boolean alice = true;
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(transportKeyManager)
|
||||
|
||||
@@ -14,7 +14,7 @@ public class StreamReaderImplTest extends BrambleTestCase {
|
||||
@Test
|
||||
public void testEmptyFramesAreSkipped() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
final StreamDecrypter decrypter = context.mock(StreamDecrypter.class);
|
||||
StreamDecrypter decrypter = context.mock(StreamDecrypter.class);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(decrypter).readFrame(with(any(byte[].class)));
|
||||
will(returnValue(0)); // Empty frame
|
||||
@@ -37,7 +37,7 @@ public class StreamReaderImplTest extends BrambleTestCase {
|
||||
@Test
|
||||
public void testEmptyFramesAreSkippedWithBuffer() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
final StreamDecrypter decrypter = context.mock(StreamDecrypter.class);
|
||||
StreamDecrypter decrypter = context.mock(StreamDecrypter.class);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(decrypter).readFrame(with(any(byte[].class)));
|
||||
will(returnValue(0)); // Empty frame
|
||||
@@ -63,7 +63,7 @@ public class StreamReaderImplTest extends BrambleTestCase {
|
||||
@Test
|
||||
public void testMultipleReadsPerFrame() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
final StreamDecrypter decrypter = context.mock(StreamDecrypter.class);
|
||||
StreamDecrypter decrypter = context.mock(StreamDecrypter.class);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(decrypter).readFrame(with(any(byte[].class)));
|
||||
will(returnValue(MAX_PAYLOAD_LENGTH)); // Nice long frame
|
||||
@@ -85,7 +85,7 @@ public class StreamReaderImplTest extends BrambleTestCase {
|
||||
@Test
|
||||
public void testMultipleReadsPerFrameWithOffsets() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
final StreamDecrypter decrypter = context.mock(StreamDecrypter.class);
|
||||
StreamDecrypter decrypter = context.mock(StreamDecrypter.class);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(decrypter).readFrame(with(any(byte[].class)));
|
||||
will(returnValue(MAX_PAYLOAD_LENGTH)); // Nice long frame
|
||||
|
||||
@@ -14,7 +14,7 @@ public class StreamWriterImplTest extends BrambleTestCase {
|
||||
@Test
|
||||
public void testCloseWithoutWritingWritesFinalFrame() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
final StreamEncrypter encrypter = context.mock(StreamEncrypter.class);
|
||||
StreamEncrypter encrypter = context.mock(StreamEncrypter.class);
|
||||
context.checking(new Expectations() {{
|
||||
// Write an empty final frame
|
||||
oneOf(encrypter).writeFrame(with(any(byte[].class)), with(0),
|
||||
@@ -31,7 +31,7 @@ public class StreamWriterImplTest extends BrambleTestCase {
|
||||
public void testFlushWithoutBufferedDataWritesFrameAndFlushes()
|
||||
throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
final StreamEncrypter encrypter = context.mock(StreamEncrypter.class);
|
||||
StreamEncrypter encrypter = context.mock(StreamEncrypter.class);
|
||||
StreamWriterImpl w = new StreamWriterImpl(encrypter);
|
||||
context.checking(new Expectations() {{
|
||||
// Write a non-final frame with an empty payload
|
||||
@@ -58,7 +58,7 @@ public class StreamWriterImplTest extends BrambleTestCase {
|
||||
public void testFlushWithBufferedDataWritesFrameAndFlushes()
|
||||
throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
final StreamEncrypter encrypter = context.mock(StreamEncrypter.class);
|
||||
StreamEncrypter encrypter = context.mock(StreamEncrypter.class);
|
||||
StreamWriterImpl w = new StreamWriterImpl(encrypter);
|
||||
context.checking(new Expectations() {{
|
||||
// Write a non-final frame with one payload byte
|
||||
@@ -85,7 +85,7 @@ public class StreamWriterImplTest extends BrambleTestCase {
|
||||
@Test
|
||||
public void testSingleByteWritesWriteFullFrame() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
final StreamEncrypter encrypter = context.mock(StreamEncrypter.class);
|
||||
StreamEncrypter encrypter = context.mock(StreamEncrypter.class);
|
||||
StreamWriterImpl w = new StreamWriterImpl(encrypter);
|
||||
context.checking(new Expectations() {{
|
||||
// Write a full non-final frame
|
||||
@@ -109,7 +109,7 @@ public class StreamWriterImplTest extends BrambleTestCase {
|
||||
@Test
|
||||
public void testMultiByteWritesWriteFullFrames() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
final StreamEncrypter encrypter = context.mock(StreamEncrypter.class);
|
||||
StreamEncrypter encrypter = context.mock(StreamEncrypter.class);
|
||||
StreamWriterImpl w = new StreamWriterImpl(encrypter);
|
||||
context.checking(new Expectations() {{
|
||||
// Write two full non-final frames
|
||||
@@ -140,7 +140,7 @@ public class StreamWriterImplTest extends BrambleTestCase {
|
||||
@Test
|
||||
public void testLargeMultiByteWriteWritesFullFrames() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
final StreamEncrypter encrypter = context.mock(StreamEncrypter.class);
|
||||
StreamEncrypter encrypter = context.mock(StreamEncrypter.class);
|
||||
StreamWriterImpl w = new StreamWriterImpl(encrypter);
|
||||
context.checking(new Expectations() {{
|
||||
// Write two full non-final frames
|
||||
|
||||
@@ -56,21 +56,20 @@ public class TransportKeyManagerImplTest extends BrambleTestCase {
|
||||
@Test
|
||||
public void testKeysAreRotatedAtStartup() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
final DatabaseComponent db = context.mock(DatabaseComponent.class);
|
||||
final CryptoComponent crypto = context.mock(CryptoComponent.class);
|
||||
final Executor dbExecutor = context.mock(Executor.class);
|
||||
final ScheduledExecutorService scheduler =
|
||||
DatabaseComponent db = context.mock(DatabaseComponent.class);
|
||||
CryptoComponent crypto = context.mock(CryptoComponent.class);
|
||||
Executor dbExecutor = context.mock(Executor.class);
|
||||
ScheduledExecutorService scheduler =
|
||||
context.mock(ScheduledExecutorService.class);
|
||||
final Clock clock = context.mock(Clock.class);
|
||||
Clock clock = context.mock(Clock.class);
|
||||
|
||||
final Map<ContactId, TransportKeys> loaded =
|
||||
new LinkedHashMap<ContactId, TransportKeys>();
|
||||
final TransportKeys shouldRotate = createTransportKeys(900, 0);
|
||||
final TransportKeys shouldNotRotate = createTransportKeys(1000, 0);
|
||||
Map<ContactId, TransportKeys> loaded = new LinkedHashMap<>();
|
||||
TransportKeys shouldRotate = createTransportKeys(900, 0);
|
||||
TransportKeys shouldNotRotate = createTransportKeys(1000, 0);
|
||||
loaded.put(contactId, shouldRotate);
|
||||
loaded.put(contactId1, shouldNotRotate);
|
||||
final TransportKeys rotated = createTransportKeys(1000, 0);
|
||||
final Transaction txn = new Transaction(null, false);
|
||||
TransportKeys rotated = createTransportKeys(1000, 0);
|
||||
Transaction txn = new Transaction(null, false);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
// Get the current time (1 ms after start of rotation period 1000)
|
||||
@@ -109,17 +108,17 @@ public class TransportKeyManagerImplTest extends BrambleTestCase {
|
||||
@Test
|
||||
public void testKeysAreRotatedWhenAddingContact() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
final DatabaseComponent db = context.mock(DatabaseComponent.class);
|
||||
final CryptoComponent crypto = context.mock(CryptoComponent.class);
|
||||
final Executor dbExecutor = context.mock(Executor.class);
|
||||
final ScheduledExecutorService scheduler =
|
||||
DatabaseComponent db = context.mock(DatabaseComponent.class);
|
||||
CryptoComponent crypto = context.mock(CryptoComponent.class);
|
||||
Executor dbExecutor = context.mock(Executor.class);
|
||||
ScheduledExecutorService scheduler =
|
||||
context.mock(ScheduledExecutorService.class);
|
||||
final Clock clock = context.mock(Clock.class);
|
||||
Clock clock = context.mock(Clock.class);
|
||||
|
||||
final boolean alice = true;
|
||||
final TransportKeys transportKeys = createTransportKeys(999, 0);
|
||||
final TransportKeys rotated = createTransportKeys(1000, 0);
|
||||
final Transaction txn = new Transaction(null, false);
|
||||
boolean alice = true;
|
||||
TransportKeys transportKeys = createTransportKeys(999, 0);
|
||||
TransportKeys rotated = createTransportKeys(1000, 0);
|
||||
Transaction txn = new Transaction(null, false);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(crypto).deriveTransportKeys(transportId, masterKey, 999,
|
||||
@@ -156,14 +155,14 @@ public class TransportKeyManagerImplTest extends BrambleTestCase {
|
||||
public void testOutgoingStreamContextIsNullIfContactIsNotFound()
|
||||
throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
final DatabaseComponent db = context.mock(DatabaseComponent.class);
|
||||
final CryptoComponent crypto = context.mock(CryptoComponent.class);
|
||||
final Executor dbExecutor = context.mock(Executor.class);
|
||||
final ScheduledExecutorService scheduler =
|
||||
DatabaseComponent db = context.mock(DatabaseComponent.class);
|
||||
CryptoComponent crypto = context.mock(CryptoComponent.class);
|
||||
Executor dbExecutor = context.mock(Executor.class);
|
||||
ScheduledExecutorService scheduler =
|
||||
context.mock(ScheduledExecutorService.class);
|
||||
final Clock clock = context.mock(Clock.class);
|
||||
Clock clock = context.mock(Clock.class);
|
||||
|
||||
final Transaction txn = new Transaction(null, false);
|
||||
Transaction txn = new Transaction(null, false);
|
||||
|
||||
TransportKeyManager
|
||||
transportKeyManager = new TransportKeyManagerImpl(db,
|
||||
@@ -177,18 +176,18 @@ public class TransportKeyManagerImplTest extends BrambleTestCase {
|
||||
public void testOutgoingStreamContextIsNullIfStreamCounterIsExhausted()
|
||||
throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
final DatabaseComponent db = context.mock(DatabaseComponent.class);
|
||||
final CryptoComponent crypto = context.mock(CryptoComponent.class);
|
||||
final Executor dbExecutor = context.mock(Executor.class);
|
||||
final ScheduledExecutorService scheduler =
|
||||
DatabaseComponent db = context.mock(DatabaseComponent.class);
|
||||
CryptoComponent crypto = context.mock(CryptoComponent.class);
|
||||
Executor dbExecutor = context.mock(Executor.class);
|
||||
ScheduledExecutorService scheduler =
|
||||
context.mock(ScheduledExecutorService.class);
|
||||
final Clock clock = context.mock(Clock.class);
|
||||
Clock clock = context.mock(Clock.class);
|
||||
|
||||
final boolean alice = true;
|
||||
boolean alice = true;
|
||||
// The stream counter has been exhausted
|
||||
final TransportKeys transportKeys = createTransportKeys(1000,
|
||||
TransportKeys transportKeys = createTransportKeys(1000,
|
||||
MAX_32_BIT_UNSIGNED + 1);
|
||||
final Transaction txn = new Transaction(null, false);
|
||||
Transaction txn = new Transaction(null, false);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(crypto).deriveTransportKeys(transportId, masterKey, 1000,
|
||||
@@ -225,18 +224,18 @@ public class TransportKeyManagerImplTest extends BrambleTestCase {
|
||||
@Test
|
||||
public void testOutgoingStreamCounterIsIncremented() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
final DatabaseComponent db = context.mock(DatabaseComponent.class);
|
||||
final CryptoComponent crypto = context.mock(CryptoComponent.class);
|
||||
final Executor dbExecutor = context.mock(Executor.class);
|
||||
final ScheduledExecutorService scheduler =
|
||||
DatabaseComponent db = context.mock(DatabaseComponent.class);
|
||||
CryptoComponent crypto = context.mock(CryptoComponent.class);
|
||||
Executor dbExecutor = context.mock(Executor.class);
|
||||
ScheduledExecutorService scheduler =
|
||||
context.mock(ScheduledExecutorService.class);
|
||||
final Clock clock = context.mock(Clock.class);
|
||||
Clock clock = context.mock(Clock.class);
|
||||
|
||||
final boolean alice = true;
|
||||
boolean alice = true;
|
||||
// The stream counter can be used one more time before being exhausted
|
||||
final TransportKeys transportKeys = createTransportKeys(1000,
|
||||
TransportKeys transportKeys = createTransportKeys(1000,
|
||||
MAX_32_BIT_UNSIGNED);
|
||||
final Transaction txn = new Transaction(null, false);
|
||||
Transaction txn = new Transaction(null, false);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(crypto).deriveTransportKeys(transportId, masterKey, 1000,
|
||||
@@ -286,16 +285,16 @@ public class TransportKeyManagerImplTest extends BrambleTestCase {
|
||||
public void testIncomingStreamContextIsNullIfTagIsNotFound()
|
||||
throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
final DatabaseComponent db = context.mock(DatabaseComponent.class);
|
||||
final CryptoComponent crypto = context.mock(CryptoComponent.class);
|
||||
final Executor dbExecutor = context.mock(Executor.class);
|
||||
final ScheduledExecutorService scheduler =
|
||||
DatabaseComponent db = context.mock(DatabaseComponent.class);
|
||||
CryptoComponent crypto = context.mock(CryptoComponent.class);
|
||||
Executor dbExecutor = context.mock(Executor.class);
|
||||
ScheduledExecutorService scheduler =
|
||||
context.mock(ScheduledExecutorService.class);
|
||||
final Clock clock = context.mock(Clock.class);
|
||||
Clock clock = context.mock(Clock.class);
|
||||
|
||||
final boolean alice = true;
|
||||
final TransportKeys transportKeys = createTransportKeys(1000, 0);
|
||||
final Transaction txn = new Transaction(null, false);
|
||||
boolean alice = true;
|
||||
TransportKeys transportKeys = createTransportKeys(1000, 0);
|
||||
Transaction txn = new Transaction(null, false);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(crypto).deriveTransportKeys(transportId, masterKey, 1000,
|
||||
@@ -333,18 +332,18 @@ public class TransportKeyManagerImplTest extends BrambleTestCase {
|
||||
@Test
|
||||
public void testTagIsNotRecognisedTwice() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
final DatabaseComponent db = context.mock(DatabaseComponent.class);
|
||||
final CryptoComponent crypto = context.mock(CryptoComponent.class);
|
||||
final Executor dbExecutor = context.mock(Executor.class);
|
||||
final ScheduledExecutorService scheduler =
|
||||
DatabaseComponent db = context.mock(DatabaseComponent.class);
|
||||
CryptoComponent crypto = context.mock(CryptoComponent.class);
|
||||
Executor dbExecutor = context.mock(Executor.class);
|
||||
ScheduledExecutorService scheduler =
|
||||
context.mock(ScheduledExecutorService.class);
|
||||
final Clock clock = context.mock(Clock.class);
|
||||
Clock clock = context.mock(Clock.class);
|
||||
|
||||
final boolean alice = true;
|
||||
final TransportKeys transportKeys = createTransportKeys(1000, 0);
|
||||
boolean alice = true;
|
||||
TransportKeys transportKeys = createTransportKeys(1000, 0);
|
||||
// Keep a copy of the tags
|
||||
final List<byte[]> tags = new ArrayList<byte[]>();
|
||||
final Transaction txn = new Transaction(null, false);
|
||||
List<byte[]> tags = new ArrayList<>();
|
||||
Transaction txn = new Transaction(null, false);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(crypto).deriveTransportKeys(transportId, masterKey, 1000,
|
||||
@@ -403,19 +402,19 @@ public class TransportKeyManagerImplTest extends BrambleTestCase {
|
||||
@Test
|
||||
public void testKeysAreRotatedToCurrentPeriod() throws Exception {
|
||||
Mockery context = new Mockery();
|
||||
final DatabaseComponent db = context.mock(DatabaseComponent.class);
|
||||
final CryptoComponent crypto = context.mock(CryptoComponent.class);
|
||||
final Executor dbExecutor = context.mock(Executor.class);
|
||||
final ScheduledExecutorService scheduler =
|
||||
DatabaseComponent db = context.mock(DatabaseComponent.class);
|
||||
CryptoComponent crypto = context.mock(CryptoComponent.class);
|
||||
Executor dbExecutor = context.mock(Executor.class);
|
||||
ScheduledExecutorService scheduler =
|
||||
context.mock(ScheduledExecutorService.class);
|
||||
final Clock clock = context.mock(Clock.class);
|
||||
Clock clock = context.mock(Clock.class);
|
||||
|
||||
final TransportKeys transportKeys = createTransportKeys(1000, 0);
|
||||
final Map<ContactId, TransportKeys> loaded =
|
||||
TransportKeys transportKeys = createTransportKeys(1000, 0);
|
||||
Map<ContactId, TransportKeys> loaded =
|
||||
Collections.singletonMap(contactId, transportKeys);
|
||||
final TransportKeys rotated = createTransportKeys(1001, 0);
|
||||
final Transaction txn = new Transaction(null, false);
|
||||
final Transaction txn1 = new Transaction(null, false);
|
||||
TransportKeys rotated = createTransportKeys(1001, 0);
|
||||
Transaction txn = new Transaction(null, false);
|
||||
Transaction txn1 = new Transaction(null, false);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
// Get the current time (the start of rotation period 1000)
|
||||
|
||||
@@ -1,22 +1,56 @@
|
||||
apply plugin: 'java'
|
||||
sourceCompatibility = 1.7
|
||||
targetCompatibility = 1.7
|
||||
apply plugin: 'java-library'
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
|
||||
apply plugin: 'net.ltgt.apt'
|
||||
apply plugin: 'idea'
|
||||
apply plugin: 'witness'
|
||||
|
||||
dependencies {
|
||||
compile project(':bramble-core')
|
||||
compile fileTree(dir: 'libs', include: '*.jar')
|
||||
compile 'net.java.dev.jna:jna:4.4.0'
|
||||
compile 'net.java.dev.jna:jna-platform:4.4.0'
|
||||
implementation project(path: ':bramble-core', configuration: 'default')
|
||||
implementation fileTree(dir: 'libs', include: '*.jar')
|
||||
implementation 'net.java.dev.jna:jna:4.4.0'
|
||||
implementation 'net.java.dev.jna:jna-platform:4.4.0'
|
||||
|
||||
testCompile project(path: ':bramble-core', configuration: 'testOutput')
|
||||
apt "com.google.dagger:dagger-compiler:$daggerVersion"
|
||||
|
||||
testImplementation project(path: ':bramble-api', configuration: 'testOutput')
|
||||
testImplementation project(path: ':bramble-core', configuration: 'testOutput')
|
||||
testImplementation "junit:junit:$junitVersion"
|
||||
testImplementation "org.jmock:jmock:$jmockVersion"
|
||||
testImplementation "org.jmock:jmock-junit4:$jmockVersion"
|
||||
testImplementation "org.jmock:jmock-legacy:$jmockVersion"
|
||||
testImplementation "org.hamcrest:hamcrest-library:$hamcrestVersion"
|
||||
testImplementation "org.hamcrest:hamcrest-core:$hamcrestVersion"
|
||||
}
|
||||
|
||||
dependencyVerification {
|
||||
verify = [
|
||||
'net.java.dev.jna:jna:c4dadeeecaa90c8847902082aee5eb107fcf59c5d0e63a17fcaf273c0e2d2bd1',
|
||||
'net.java.dev.jna:jna-platform:e9dda9e884fc107eb6367710540789a12dfa8ad28be9326b22ca6e352e325499',
|
||||
'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.dagger:dagger-compiler:2.0.2:dagger-compiler-2.0.2.jar:b74bc9de063dd4c6400b232231f2ef5056145b8fbecbf5382012007dd1c071b3',
|
||||
'com.google.dagger:dagger-producers:2.0-beta:dagger-producers-2.0-beta.jar:99ec15e8a0507ba569e7655bc1165ee5e5ca5aa914b3c8f7e2c2458f724edd6b',
|
||||
'com.google.dagger:dagger:2.0.2:dagger-2.0.2.jar:84c0282ed8be73a29e0475d639da030b55dee72369e58dd35ae7d4fe6243dcf9',
|
||||
'com.google.guava:guava:18.0:guava-18.0.jar:d664fbfc03d2e5ce9cab2a44fb01f1d0bf9dfebeccc1a473b1f9ea31f79f6f99',
|
||||
'com.h2database:h2:1.4.192:h2-1.4.192.jar:225b22e9857235c46c93861410b60b8c81c10dc8985f4faf188985ba5445126c',
|
||||
'com.madgag.spongycastle:core:1.58.0.0:core-1.58.0.0.jar:199617dd5698c5a9312b898c0a4cec7ce9dd8649d07f65d91629f58229d72728',
|
||||
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
|
||||
'junit:junit:4.12:junit-4.12.jar:59721f0805e223d84b90677887d9ff567dc534d7c502ca903c0c2b17f05c116a',
|
||||
'net.i2p.crypto:eddsa:0.2.0:eddsa-0.2.0.jar:a7cb1b85c16e2f0730b9204106929a1d9aaae1df728adc7041a8b8b605692140',
|
||||
'net.java.dev.jna:jna-platform:4.4.0:jna-platform-4.4.0.jar:e9dda9e884fc107eb6367710540789a12dfa8ad28be9326b22ca6e352e325499',
|
||||
'net.java.dev.jna:jna:4.4.0:jna-4.4.0.jar:c4dadeeecaa90c8847902082aee5eb107fcf59c5d0e63a17fcaf273c0e2d2bd1',
|
||||
'org.apache.ant:ant-launcher:1.9.4:ant-launcher-1.9.4.jar:7bccea20b41801ca17bcbc909a78c835d0f443f12d639c77bd6ae3d05861608d',
|
||||
'org.apache.ant:ant:1.9.4:ant-1.9.4.jar:649ae0730251de07b8913f49286d46bba7b92d47c5f332610aa426c4f02161d8',
|
||||
'org.beanshell:bsh:1.3.0:bsh-1.3.0.jar:9b04edc75d19db54f1b4e8b5355e9364384c6cf71eb0a1b9724c159d779879f8',
|
||||
'org.bitlet:weupnp:0.1.4:weupnp-0.1.4.jar:88df7e6504929d00bdb832863761385c68ab92af945b04f0770b126270a444fb',
|
||||
'org.hamcrest:hamcrest-core:1.3:hamcrest-core-1.3.jar:66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9',
|
||||
'org.hamcrest:hamcrest-library:1.3:hamcrest-library-1.3.jar:711d64522f9ec410983bd310934296da134be4254a125080a0416ec178dfad1c',
|
||||
'org.jmock:jmock-junit4:2.8.2:jmock-junit4-2.8.2.jar:f7ee4df4f7bd7b7f1cafad3b99eb74d579f109d5992ff625347352edb55e674c',
|
||||
'org.jmock:jmock-legacy:2.8.2:jmock-legacy-2.8.2.jar:f2b985a5c08a9edb7f37612330c058809da3f6a6d63ce792426ebf8ff0d6d31b',
|
||||
'org.jmock:jmock-testjar:2.8.2:jmock-testjar-2.8.2.jar:8900860f72c474e027cf97fe78dcbf154a1aa7fc62b6845c5fb4e4f3c7bc8760',
|
||||
'org.jmock:jmock:2.8.2:jmock-2.8.2.jar:6c73cb4a2e6dbfb61fd99c9a768539c170ab6568e57846bd60dbf19596b65b16',
|
||||
'org.objenesis:objenesis:2.1:objenesis-2.1.jar:c74330cc6b806c804fd37e74487b4fe5d7c2750c5e15fbc6efa13bdee1bdef80',
|
||||
'org.ow2.asm:asm:5.0.4:asm-5.0.4.jar:896618ed8ae62702521a78bc7be42b7c491a08e6920a15f89a3ecdec31e9a220',
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -110,20 +110,16 @@ class WindowsShutdownManagerImpl extends ShutdownManagerImpl {
|
||||
public void run() {
|
||||
try {
|
||||
// Load user32.dll
|
||||
final User32 user32 = (User32) Native.loadLibrary("user32",
|
||||
User32 user32 = (User32) Native.loadLibrary("user32",
|
||||
User32.class, options);
|
||||
// Create a callback to handle the WM_QUERYENDSESSION message
|
||||
WindowProc proc = new WindowProc() {
|
||||
@Override
|
||||
public LRESULT callback(HWND hwnd, int msg, WPARAM wp,
|
||||
LPARAM lp) {
|
||||
if (msg == WM_QUERYENDSESSION) {
|
||||
// It's safe to delay returning from this message
|
||||
runShutdownHooks();
|
||||
}
|
||||
// Pass the message to the default window procedure
|
||||
return user32.DefWindowProc(hwnd, msg, wp, lp);
|
||||
WindowProc proc = (hwnd, msg, wp, lp) -> {
|
||||
if (msg == WM_QUERYENDSESSION) {
|
||||
// It's safe to delay returning from this message
|
||||
runShutdownHooks();
|
||||
}
|
||||
// Pass the message to the default window procedure
|
||||
return user32.DefWindowProc(hwnd, msg, wp, lp);
|
||||
};
|
||||
// Create a native window
|
||||
HWND hwnd = user32.CreateWindowEx(0, "STATIC", "", WS_MINIMIZE,
|
||||
|
||||
@@ -41,9 +41,9 @@ public class DesktopPluginModule extends PluginModule {
|
||||
backoffFactory, shutdownManager);
|
||||
SimplexPluginFactory removable =
|
||||
new RemovableDrivePluginFactory(ioExecutor);
|
||||
final Collection<SimplexPluginFactory> simplex =
|
||||
Collection<SimplexPluginFactory> simplex =
|
||||
Collections.singletonList(removable);
|
||||
final Collection<DuplexPluginFactory> duplex =
|
||||
Collection<DuplexPluginFactory> duplex =
|
||||
Arrays.asList(bluetooth, modem, lan, wan);
|
||||
@NotNullByDefault
|
||||
PluginConfig pluginConfig = new PluginConfig() {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user