mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-17 05:09:53 +01:00
Keep last sent clientSupports on record, sending update only if changed
This commit is contained in:
@@ -10,6 +10,7 @@ import org.briarproject.bramble.api.db.DbException;
|
|||||||
import org.briarproject.bramble.api.db.Transaction;
|
import org.briarproject.bramble.api.db.Transaction;
|
||||||
import org.briarproject.bramble.api.identity.Author;
|
import org.briarproject.bramble.api.identity.Author;
|
||||||
import org.briarproject.bramble.api.mailbox.MailboxUpdate;
|
import org.briarproject.bramble.api.mailbox.MailboxUpdate;
|
||||||
|
import org.briarproject.bramble.api.mailbox.MailboxVersion;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.TransportId;
|
import org.briarproject.bramble.api.plugin.TransportId;
|
||||||
import org.briarproject.bramble.api.properties.TransportProperties;
|
import org.briarproject.bramble.api.properties.TransportProperties;
|
||||||
@@ -19,6 +20,7 @@ import org.briarproject.bramble.api.sync.MessageId;
|
|||||||
|
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
@@ -134,6 +136,9 @@ public interface ClientHelper {
|
|||||||
BdfList serverSupports, BdfDictionary properties)
|
BdfList serverSupports, BdfDictionary properties)
|
||||||
throws FormatException;
|
throws FormatException;
|
||||||
|
|
||||||
|
List<MailboxVersion> parseMailboxVersionList(BdfList bdfList)
|
||||||
|
throws FormatException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the contact ID from the group metadata of the given contact
|
* Retrieves the contact ID from the group metadata of the given contact
|
||||||
* group.
|
* group.
|
||||||
|
|||||||
@@ -57,6 +57,12 @@ public interface MailboxUpdateManager {
|
|||||||
*/
|
*/
|
||||||
String MSG_KEY_LOCAL = "local";
|
String MSG_KEY_LOCAL = "local";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key in the client's local group for storing the clientSupports list that
|
||||||
|
* was last sent out.
|
||||||
|
*/
|
||||||
|
String GROUP_KEY_SENT_CLIENT_SUPPORTS = "sentClientSupports";
|
||||||
|
|
||||||
MailboxUpdate getLocalUpdate(Transaction txn, ContactId c)
|
MailboxUpdate getLocalUpdate(Transaction txn, ContactId c)
|
||||||
throws DbException;
|
throws DbException;
|
||||||
|
|
||||||
|
|||||||
@@ -419,9 +419,9 @@ class ClientHelperImpl implements ClientHelper {
|
|||||||
BdfList serverSupports, BdfDictionary properties)
|
BdfList serverSupports, BdfDictionary properties)
|
||||||
throws FormatException {
|
throws FormatException {
|
||||||
List<MailboxVersion> clientSupportsList =
|
List<MailboxVersion> clientSupportsList =
|
||||||
getMailboxVersionList(clientSupports);
|
parseMailboxVersionList(clientSupports);
|
||||||
List<MailboxVersion> serverSupportsList =
|
List<MailboxVersion> serverSupportsList =
|
||||||
getMailboxVersionList(serverSupports);
|
parseMailboxVersionList(serverSupports);
|
||||||
|
|
||||||
// We must always learn what Mailbox API version(s) the client supports
|
// We must always learn what Mailbox API version(s) the client supports
|
||||||
if (clientSupports.isEmpty()) {
|
if (clientSupports.isEmpty()) {
|
||||||
@@ -460,7 +460,8 @@ class ClientHelperImpl implements ClientHelper {
|
|||||||
new MailboxFolderId(inboxId), new MailboxFolderId(outboxId));
|
new MailboxFolderId(inboxId), new MailboxFolderId(outboxId));
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<MailboxVersion> getMailboxVersionList(BdfList bdfList)
|
@Override
|
||||||
|
public List<MailboxVersion> parseMailboxVersionList(BdfList bdfList)
|
||||||
throws FormatException {
|
throws FormatException {
|
||||||
List<MailboxVersion> list = new ArrayList<>();
|
List<MailboxVersion> list = new ArrayList<>();
|
||||||
for (int i = 0; i < bdfList.size(); i++) {
|
for (int i = 0; i < bdfList.size(); i++) {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import org.briarproject.bramble.api.contact.ContactId;
|
|||||||
import org.briarproject.bramble.api.contact.ContactManager.ContactHook;
|
import org.briarproject.bramble.api.contact.ContactManager.ContactHook;
|
||||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
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.BdfList;
|
||||||
import org.briarproject.bramble.api.data.MetadataParser;
|
import org.briarproject.bramble.api.data.MetadataParser;
|
||||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||||
@@ -84,27 +85,47 @@ class MailboxUpdateManagerImpl implements MailboxUpdateManager,
|
|||||||
@Override
|
@Override
|
||||||
public void onDatabaseOpened(Transaction txn) throws DbException {
|
public void onDatabaseOpened(Transaction txn) throws DbException {
|
||||||
if (db.containsGroup(txn, localGroup.getId())) {
|
if (db.containsGroup(txn, localGroup.getId())) {
|
||||||
|
try {
|
||||||
|
BdfDictionary meta = clientHelper.getGroupMetadataAsDictionary(
|
||||||
|
txn, localGroup.getId());
|
||||||
|
BdfList sent = meta.getList(GROUP_KEY_SENT_CLIENT_SUPPORTS);
|
||||||
|
if (clientHelper.parseMailboxVersionList(sent)
|
||||||
|
.equals(CLIENT_SUPPORTS)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (FormatException e) {
|
||||||
|
throw new DbException();
|
||||||
|
}
|
||||||
|
// Our current clientSupports list has changed compared to what we
|
||||||
|
// last sent out.
|
||||||
for (Contact c : db.getContacts(txn)) {
|
for (Contact c : db.getContacts(txn)) {
|
||||||
MailboxUpdate latest = getLocalUpdate(txn, c.getId());
|
MailboxUpdate latest = getLocalUpdate(txn, c.getId());
|
||||||
if (!latest.getClientSupports().equals(CLIENT_SUPPORTS)) {
|
MailboxUpdate updated;
|
||||||
MailboxUpdate updated;
|
if (latest.hasMailbox()) {
|
||||||
if (latest.hasMailbox()) {
|
updated = new MailboxUpdateWithMailbox(
|
||||||
updated = new MailboxUpdateWithMailbox(
|
(MailboxUpdateWithMailbox) latest,
|
||||||
(MailboxUpdateWithMailbox) latest,
|
CLIENT_SUPPORTS);
|
||||||
CLIENT_SUPPORTS);
|
} else {
|
||||||
} else {
|
updated = new MailboxUpdate(CLIENT_SUPPORTS);
|
||||||
updated = new MailboxUpdate(CLIENT_SUPPORTS);
|
|
||||||
}
|
|
||||||
Group g = getContactGroup(c);
|
|
||||||
storeMessageReplaceLatest(txn, g.getId(), updated);
|
|
||||||
}
|
}
|
||||||
|
Group g = getContactGroup(c);
|
||||||
|
storeMessageReplaceLatest(txn, g.getId(), updated);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
db.addGroup(txn, localGroup);
|
||||||
|
// Set things up for any pre-existing contacts
|
||||||
|
for (Contact c : db.getContacts(txn)) {
|
||||||
|
addingContact(txn, c);
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
db.addGroup(txn, localGroup);
|
|
||||||
// Set things up for any pre-existing contacts
|
try {
|
||||||
for (Contact c : db.getContacts(txn)) {
|
BdfDictionary meta = BdfDictionary.of(new BdfEntry(
|
||||||
addingContact(txn, c);
|
GROUP_KEY_SENT_CLIENT_SUPPORTS,
|
||||||
|
encodeSupportsList(CLIENT_SUPPORTS)));
|
||||||
|
clientHelper.mergeGroupMetadata(txn, localGroup.getId(), meta);
|
||||||
|
} catch (FormatException e) {
|
||||||
|
throw new DbException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
import static java.util.Collections.singletonList;
|
import static java.util.Collections.singletonList;
|
||||||
import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.CLIENT_ID;
|
import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.CLIENT_ID;
|
||||||
|
import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.GROUP_KEY_SENT_CLIENT_SUPPORTS;
|
||||||
import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.MAJOR_VERSION;
|
import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.MAJOR_VERSION;
|
||||||
import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.MSG_KEY_LOCAL;
|
import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.MSG_KEY_LOCAL;
|
||||||
import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.MSG_KEY_VERSION;
|
import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.MSG_KEY_VERSION;
|
||||||
@@ -132,6 +133,9 @@ public class MailboxUpdateManagerImplTest extends BrambleMockTestCase {
|
|||||||
Contact contact = getContact();
|
Contact contact = getContact();
|
||||||
Group contactGroup = getGroup(CLIENT_ID, MAJOR_VERSION);
|
Group contactGroup = getGroup(CLIENT_ID, MAJOR_VERSION);
|
||||||
Map<MessageId, BdfDictionary> messageMetadata = new LinkedHashMap<>();
|
Map<MessageId, BdfDictionary> messageMetadata = new LinkedHashMap<>();
|
||||||
|
BdfDictionary sentDict = BdfDictionary.of(new BdfEntry(
|
||||||
|
GROUP_KEY_SENT_CLIENT_SUPPORTS,
|
||||||
|
realClientSupports));
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(db).containsGroup(txn, localGroup.getId());
|
oneOf(db).containsGroup(txn, localGroup.getId());
|
||||||
@@ -139,6 +143,8 @@ public class MailboxUpdateManagerImplTest extends BrambleMockTestCase {
|
|||||||
oneOf(db).addGroup(txn, localGroup);
|
oneOf(db).addGroup(txn, localGroup);
|
||||||
oneOf(db).getContacts(txn);
|
oneOf(db).getContacts(txn);
|
||||||
will(returnValue(singletonList(contact)));
|
will(returnValue(singletonList(contact)));
|
||||||
|
|
||||||
|
// addingContact()
|
||||||
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
|
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
|
||||||
MAJOR_VERSION, contact);
|
MAJOR_VERSION, contact);
|
||||||
will(returnValue(contactGroup));
|
will(returnValue(contactGroup));
|
||||||
@@ -160,6 +166,9 @@ public class MailboxUpdateManagerImplTest extends BrambleMockTestCase {
|
|||||||
will(returnValue(messageMetadata));
|
will(returnValue(messageMetadata));
|
||||||
expectStoreMessage(txn, contactGroup.getId(), 1, realClientSupports,
|
expectStoreMessage(txn, contactGroup.getId(), 1, realClientSupports,
|
||||||
emptyServerSupports, emptyPropsDict, true);
|
emptyServerSupports, emptyPropsDict, true);
|
||||||
|
|
||||||
|
oneOf(clientHelper).mergeGroupMetadata(txn, localGroup.getId(),
|
||||||
|
sentDict);
|
||||||
}});
|
}});
|
||||||
|
|
||||||
MailboxUpdateManagerImpl t = createInstance();
|
MailboxUpdateManagerImpl t = createInstance();
|
||||||
@@ -173,6 +182,9 @@ public class MailboxUpdateManagerImplTest extends BrambleMockTestCase {
|
|||||||
Contact contact = getContact();
|
Contact contact = getContact();
|
||||||
Group contactGroup = getGroup(CLIENT_ID, MAJOR_VERSION);
|
Group contactGroup = getGroup(CLIENT_ID, MAJOR_VERSION);
|
||||||
Map<MessageId, BdfDictionary> messageMetadata = new LinkedHashMap<>();
|
Map<MessageId, BdfDictionary> messageMetadata = new LinkedHashMap<>();
|
||||||
|
BdfDictionary sentDict = BdfDictionary.of(new BdfEntry(
|
||||||
|
GROUP_KEY_SENT_CLIENT_SUPPORTS,
|
||||||
|
realClientSupports));
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(db).containsGroup(txn, localGroup.getId());
|
oneOf(db).containsGroup(txn, localGroup.getId());
|
||||||
@@ -180,6 +192,8 @@ public class MailboxUpdateManagerImplTest extends BrambleMockTestCase {
|
|||||||
oneOf(db).addGroup(txn, localGroup);
|
oneOf(db).addGroup(txn, localGroup);
|
||||||
oneOf(db).getContacts(txn);
|
oneOf(db).getContacts(txn);
|
||||||
will(returnValue(singletonList(contact)));
|
will(returnValue(singletonList(contact)));
|
||||||
|
|
||||||
|
// addingContact()
|
||||||
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
|
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
|
||||||
MAJOR_VERSION, contact);
|
MAJOR_VERSION, contact);
|
||||||
will(returnValue(contactGroup));
|
will(returnValue(contactGroup));
|
||||||
@@ -207,6 +221,9 @@ public class MailboxUpdateManagerImplTest extends BrambleMockTestCase {
|
|||||||
will(returnValue(messageMetadata));
|
will(returnValue(messageMetadata));
|
||||||
expectStoreMessage(txn, contactGroup.getId(), 1, realClientSupports,
|
expectStoreMessage(txn, contactGroup.getId(), 1, realClientSupports,
|
||||||
someServerSupports, propsDict, true);
|
someServerSupports, propsDict, true);
|
||||||
|
|
||||||
|
oneOf(clientHelper).mergeGroupMetadata(txn, localGroup.getId(),
|
||||||
|
sentDict);
|
||||||
}});
|
}});
|
||||||
|
|
||||||
MailboxUpdateManagerImpl t = createInstance();
|
MailboxUpdateManagerImpl t = createInstance();
|
||||||
@@ -214,18 +231,27 @@ public class MailboxUpdateManagerImplTest extends BrambleMockTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testChecksForCurrentClientSupportsInLatestUpdateOnSecondStartup()
|
public void testChecksLatestSentClientSupportsOnSecondStartup()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
Transaction txn = new Transaction(null, false);
|
Transaction txn = new Transaction(null, false);
|
||||||
|
|
||||||
Contact contact = getContact();
|
Contact contact = getContact();
|
||||||
List<Contact> contacts = singletonList(contact);
|
|
||||||
Group contactGroup = getGroup(CLIENT_ID, MAJOR_VERSION);
|
Group contactGroup = getGroup(CLIENT_ID, MAJOR_VERSION);
|
||||||
|
|
||||||
Map<MessageId, BdfDictionary> emptyMessageMetadata =
|
Map<MessageId, BdfDictionary> emptyMessageMetadata =
|
||||||
new LinkedHashMap<>();
|
new LinkedHashMap<>();
|
||||||
|
BdfDictionary sentDict = BdfDictionary.of(new BdfEntry(
|
||||||
|
GROUP_KEY_SENT_CLIENT_SUPPORTS,
|
||||||
|
realClientSupports));
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
|
oneOf(db).containsGroup(txn, localGroup.getId());
|
||||||
|
will(returnValue(false));
|
||||||
|
oneOf(db).addGroup(txn, localGroup);
|
||||||
|
oneOf(db).getContacts(txn);
|
||||||
|
will(returnValue(singletonList(contact)));
|
||||||
|
|
||||||
|
// addingContact()
|
||||||
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
|
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
|
||||||
MAJOR_VERSION, contact);
|
MAJOR_VERSION, contact);
|
||||||
will(returnValue(contactGroup));
|
will(returnValue(contactGroup));
|
||||||
@@ -247,41 +273,25 @@ public class MailboxUpdateManagerImplTest extends BrambleMockTestCase {
|
|||||||
will(returnValue(emptyMessageMetadata));
|
will(returnValue(emptyMessageMetadata));
|
||||||
expectStoreMessage(txn, contactGroup.getId(), 1, realClientSupports,
|
expectStoreMessage(txn, contactGroup.getId(), 1, realClientSupports,
|
||||||
emptyServerSupports, emptyPropsDict, true);
|
emptyServerSupports, emptyPropsDict, true);
|
||||||
|
|
||||||
|
oneOf(clientHelper).mergeGroupMetadata(txn, localGroup.getId(),
|
||||||
|
sentDict);
|
||||||
}});
|
}});
|
||||||
|
|
||||||
MailboxUpdateManagerImpl t = createInstance();
|
MailboxUpdateManagerImpl t = createInstance();
|
||||||
t.addingContact(txn, contact);
|
t.onDatabaseOpened(txn);
|
||||||
|
|
||||||
Message message = getMessage(contactGroup.getId());
|
|
||||||
BdfList body = BdfList.of(1, realClientSupports, emptyServerSupports,
|
|
||||||
emptyPropsDict);
|
|
||||||
BdfDictionary metaDictionary = BdfDictionary.of(
|
|
||||||
new BdfEntry(MSG_KEY_VERSION, 1),
|
|
||||||
new BdfEntry(MSG_KEY_LOCAL, true)
|
|
||||||
);
|
|
||||||
Map<MessageId, BdfDictionary> messageMetadata = new LinkedHashMap<>();
|
|
||||||
messageMetadata.put(message.getId(), metaDictionary);
|
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(db).containsGroup(txn, localGroup.getId());
|
oneOf(db).containsGroup(txn, localGroup.getId());
|
||||||
will(returnValue(true));
|
will(returnValue(true));
|
||||||
oneOf(db).getContacts(txn);
|
oneOf(clientHelper).getGroupMetadataAsDictionary(txn,
|
||||||
will(returnValue(contacts));
|
localGroup.getId());
|
||||||
oneOf(db).getContact(txn, contact.getId());
|
will(returnValue(sentDict));
|
||||||
will(returnValue(contact));
|
oneOf(clientHelper).parseMailboxVersionList(realClientSupports);
|
||||||
oneOf(contactGroupFactory)
|
will(returnValue(CLIENT_SUPPORTS));
|
||||||
.createContactGroup(CLIENT_ID, MAJOR_VERSION, contact);
|
|
||||||
will(returnValue(contactGroup));
|
|
||||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
|
||||||
contactGroup.getId());
|
|
||||||
will(returnValue(messageMetadata));
|
|
||||||
oneOf(clientHelper).getMessageAsList(txn, message.getId());
|
|
||||||
will(returnValue(body));
|
|
||||||
oneOf(clientHelper).parseAndValidateMailboxUpdate(
|
|
||||||
realClientSupports, emptyServerSupports, emptyPropsDict);
|
|
||||||
will(returnValue(updateNoMailbox));
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
|
t = createInstance();
|
||||||
t.onDatabaseOpened(txn);
|
t.onDatabaseOpened(txn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user