mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-21 23:29:52 +01:00
Use ClientHelper in TransportPropertyManagerImpl.
This commit is contained in:
@@ -5,21 +5,16 @@ import com.google.inject.Inject;
|
|||||||
import org.briarproject.api.DeviceId;
|
import org.briarproject.api.DeviceId;
|
||||||
import org.briarproject.api.FormatException;
|
import org.briarproject.api.FormatException;
|
||||||
import org.briarproject.api.TransportId;
|
import org.briarproject.api.TransportId;
|
||||||
|
import org.briarproject.api.clients.ClientHelper;
|
||||||
import org.briarproject.api.clients.PrivateGroupFactory;
|
import org.briarproject.api.clients.PrivateGroupFactory;
|
||||||
import org.briarproject.api.contact.Contact;
|
import org.briarproject.api.contact.Contact;
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
import org.briarproject.api.contact.ContactManager.AddContactHook;
|
import org.briarproject.api.contact.ContactManager.AddContactHook;
|
||||||
import org.briarproject.api.contact.ContactManager.RemoveContactHook;
|
import org.briarproject.api.contact.ContactManager.RemoveContactHook;
|
||||||
import org.briarproject.api.data.BdfDictionary;
|
import org.briarproject.api.data.BdfDictionary;
|
||||||
import org.briarproject.api.data.BdfReader;
|
import org.briarproject.api.data.BdfList;
|
||||||
import org.briarproject.api.data.BdfReaderFactory;
|
|
||||||
import org.briarproject.api.data.BdfWriter;
|
|
||||||
import org.briarproject.api.data.BdfWriterFactory;
|
|
||||||
import org.briarproject.api.data.MetadataEncoder;
|
|
||||||
import org.briarproject.api.data.MetadataParser;
|
|
||||||
import org.briarproject.api.db.DatabaseComponent;
|
import org.briarproject.api.db.DatabaseComponent;
|
||||||
import org.briarproject.api.db.DbException;
|
import org.briarproject.api.db.DbException;
|
||||||
import org.briarproject.api.db.Metadata;
|
|
||||||
import org.briarproject.api.db.NoSuchGroupException;
|
import org.briarproject.api.db.NoSuchGroupException;
|
||||||
import org.briarproject.api.db.Transaction;
|
import org.briarproject.api.db.Transaction;
|
||||||
import org.briarproject.api.properties.TransportProperties;
|
import org.briarproject.api.properties.TransportProperties;
|
||||||
@@ -29,22 +24,15 @@ import org.briarproject.api.sync.Group;
|
|||||||
import org.briarproject.api.sync.GroupFactory;
|
import org.briarproject.api.sync.GroupFactory;
|
||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.Message;
|
import org.briarproject.api.sync.Message;
|
||||||
import org.briarproject.api.sync.MessageFactory;
|
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
import org.briarproject.api.system.Clock;
|
import org.briarproject.api.system.Clock;
|
||||||
import org.briarproject.util.StringUtils;
|
import org.briarproject.util.StringUtils;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import static org.briarproject.api.properties.TransportPropertyConstants.MAX_PROPERTY_LENGTH;
|
|
||||||
import static org.briarproject.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
|
|
||||||
|
|
||||||
class TransportPropertyManagerImpl implements TransportPropertyManager,
|
class TransportPropertyManagerImpl implements TransportPropertyManager,
|
||||||
AddContactHook, RemoveContactHook {
|
AddContactHook, RemoveContactHook {
|
||||||
|
|
||||||
@@ -55,28 +43,18 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
|||||||
private static final byte[] LOCAL_GROUP_DESCRIPTOR = new byte[0];
|
private static final byte[] LOCAL_GROUP_DESCRIPTOR = new byte[0];
|
||||||
|
|
||||||
private final DatabaseComponent db;
|
private final DatabaseComponent db;
|
||||||
|
private final ClientHelper clientHelper;
|
||||||
private final PrivateGroupFactory privateGroupFactory;
|
private final PrivateGroupFactory privateGroupFactory;
|
||||||
private final MessageFactory messageFactory;
|
|
||||||
private final BdfReaderFactory bdfReaderFactory;
|
|
||||||
private final BdfWriterFactory bdfWriterFactory;
|
|
||||||
private final MetadataEncoder metadataEncoder;
|
|
||||||
private final MetadataParser metadataParser;
|
|
||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
private final Group localGroup;
|
private final Group localGroup;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
TransportPropertyManagerImpl(DatabaseComponent db,
|
TransportPropertyManagerImpl(DatabaseComponent db,
|
||||||
GroupFactory groupFactory, PrivateGroupFactory privateGroupFactory,
|
ClientHelper clientHelper, GroupFactory groupFactory,
|
||||||
MessageFactory messageFactory, BdfReaderFactory bdfReaderFactory,
|
PrivateGroupFactory privateGroupFactory, Clock clock) {
|
||||||
BdfWriterFactory bdfWriterFactory, MetadataEncoder metadataEncoder,
|
|
||||||
MetadataParser metadataParser, Clock clock) {
|
|
||||||
this.db = db;
|
this.db = db;
|
||||||
|
this.clientHelper = clientHelper;
|
||||||
this.privateGroupFactory = privateGroupFactory;
|
this.privateGroupFactory = privateGroupFactory;
|
||||||
this.messageFactory = messageFactory;
|
|
||||||
this.bdfReaderFactory = bdfReaderFactory;
|
|
||||||
this.bdfWriterFactory = bdfWriterFactory;
|
|
||||||
this.metadataEncoder = metadataEncoder;
|
|
||||||
this.metadataParser = metadataParser;
|
|
||||||
this.clock = clock;
|
this.clock = clock;
|
||||||
localGroup = groupFactory.createGroup(CLIENT_ID,
|
localGroup = groupFactory.createGroup(CLIENT_ID,
|
||||||
LOCAL_GROUP_DESCRIPTOR);
|
LOCAL_GROUP_DESCRIPTOR);
|
||||||
@@ -145,8 +123,9 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
|||||||
true);
|
true);
|
||||||
if (latest != null) {
|
if (latest != null) {
|
||||||
// Retrieve and parse the latest local properties
|
// Retrieve and parse the latest local properties
|
||||||
byte[] raw = db.getRawMessage(txn, latest.messageId);
|
BdfList message = clientHelper.getMessageAsList(txn,
|
||||||
p = parseProperties(raw);
|
latest.messageId);
|
||||||
|
p = parseProperties(message);
|
||||||
}
|
}
|
||||||
txn.setComplete();
|
txn.setComplete();
|
||||||
} finally {
|
} finally {
|
||||||
@@ -175,8 +154,9 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
|||||||
LatestUpdate latest = findLatest(txn, g.getId(), t, false);
|
LatestUpdate latest = findLatest(txn, g.getId(), t, false);
|
||||||
if (latest != null) {
|
if (latest != null) {
|
||||||
// Retrieve and parse the latest remote properties
|
// Retrieve and parse the latest remote properties
|
||||||
byte[] raw = db.getRawMessage(txn, latest.messageId);
|
BdfList message = clientHelper.getMessageAsList(txn,
|
||||||
remote.put(c.getId(), parseProperties(raw));
|
latest.messageId);
|
||||||
|
remote.put(c.getId(), parseProperties(message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
txn.setComplete();
|
txn.setComplete();
|
||||||
@@ -206,8 +186,9 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
|||||||
merged = p;
|
merged = p;
|
||||||
changed = true;
|
changed = true;
|
||||||
} else {
|
} else {
|
||||||
byte[] raw = db.getRawMessage(txn, latest.messageId);
|
BdfList message = clientHelper.getMessageAsList(txn,
|
||||||
TransportProperties old = parseProperties(raw);
|
latest.messageId);
|
||||||
|
TransportProperties old = parseProperties(message);
|
||||||
merged = new TransportProperties(old);
|
merged = new TransportProperties(old);
|
||||||
merged.putAll(p);
|
merged.putAll(p);
|
||||||
changed = !merged.equals(old);
|
changed = !merged.equals(old);
|
||||||
@@ -250,8 +231,9 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
|||||||
localGroup.getId(), true);
|
localGroup.getId(), true);
|
||||||
// Retrieve and parse the latest local properties
|
// Retrieve and parse the latest local properties
|
||||||
for (Entry<TransportId, LatestUpdate> e : latest.entrySet()) {
|
for (Entry<TransportId, LatestUpdate> e : latest.entrySet()) {
|
||||||
byte[] raw = db.getRawMessage(txn, e.getValue().messageId);
|
BdfList message = clientHelper.getMessageAsList(txn,
|
||||||
local.put(e.getKey(), parseProperties(raw));
|
e.getValue().messageId);
|
||||||
|
local.put(e.getKey(), parseProperties(message));
|
||||||
}
|
}
|
||||||
return local;
|
return local;
|
||||||
} catch (NoSuchGroupException e) {
|
} catch (NoSuchGroupException e) {
|
||||||
@@ -266,48 +248,35 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
|||||||
TransportId t, TransportProperties p, long version, boolean local,
|
TransportId t, TransportProperties p, long version, boolean local,
|
||||||
boolean shared) throws DbException {
|
boolean shared) throws DbException {
|
||||||
try {
|
try {
|
||||||
byte[] body = encodeProperties(dev, t, p, version);
|
BdfList body = encodeProperties(dev, t, p, version);
|
||||||
long now = clock.currentTimeMillis();
|
long now = clock.currentTimeMillis();
|
||||||
Message m = messageFactory.createMessage(g, now, body);
|
Message m = clientHelper.createMessage(g, now, body);
|
||||||
BdfDictionary d = new BdfDictionary();
|
BdfDictionary meta = new BdfDictionary();
|
||||||
d.put("transportId", t.getString());
|
meta.put("transportId", t.getString());
|
||||||
d.put("version", version);
|
meta.put("version", version);
|
||||||
d.put("local", local);
|
meta.put("local", local);
|
||||||
Metadata meta = metadataEncoder.encode(d);
|
clientHelper.addLocalMessage(txn, m, CLIENT_ID, meta, shared);
|
||||||
db.addLocalMessage(txn, m, CLIENT_ID, meta, shared);
|
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] encodeProperties(DeviceId dev, TransportId t,
|
private BdfList encodeProperties(DeviceId dev, TransportId t,
|
||||||
TransportProperties p, long version) {
|
TransportProperties p, long version) {
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
return BdfList.of(dev, t.getString(), version, p);
|
||||||
BdfWriter w = bdfWriterFactory.createWriter(out);
|
|
||||||
try {
|
|
||||||
w.writeListStart();
|
|
||||||
w.writeRaw(dev.getBytes());
|
|
||||||
w.writeString(t.getString());
|
|
||||||
w.writeLong(version);
|
|
||||||
w.writeDictionary(p);
|
|
||||||
w.writeListEnd();
|
|
||||||
} catch (IOException e) {
|
|
||||||
// Shouldn't happen with ByteArrayOutputStream
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
return out.toByteArray();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<TransportId, LatestUpdate> findLatest(Transaction txn,
|
private Map<TransportId, LatestUpdate> findLatest(Transaction txn,
|
||||||
GroupId g, boolean local) throws DbException, FormatException {
|
GroupId g, boolean local) throws DbException, FormatException {
|
||||||
Map<TransportId, LatestUpdate> latestUpdates =
|
Map<TransportId, LatestUpdate> latestUpdates =
|
||||||
new HashMap<TransportId, LatestUpdate>();
|
new HashMap<TransportId, LatestUpdate>();
|
||||||
Map<MessageId, Metadata> metadata = db.getMessageMetadata(txn, g);
|
Map<MessageId, BdfDictionary> metadata =
|
||||||
for (Entry<MessageId, Metadata> e : metadata.entrySet()) {
|
clientHelper.getMessageMetadataAsDictionary(txn, g);
|
||||||
BdfDictionary d = metadataParser.parse(e.getValue());
|
for (Entry<MessageId, BdfDictionary> e : metadata.entrySet()) {
|
||||||
if (d.getBoolean("local") == local) {
|
BdfDictionary meta = e.getValue();
|
||||||
TransportId t = new TransportId(d.getString("transportId"));
|
if (meta.getBoolean("local") == local) {
|
||||||
long version = d.getLong("version");
|
TransportId t = new TransportId(meta.getString("transportId"));
|
||||||
|
long version = meta.getLong("version");
|
||||||
LatestUpdate latest = latestUpdates.get(t);
|
LatestUpdate latest = latestUpdates.get(t);
|
||||||
if (latest == null || version > latest.version)
|
if (latest == null || version > latest.version)
|
||||||
latestUpdates.put(t, new LatestUpdate(e.getKey(), version));
|
latestUpdates.put(t, new LatestUpdate(e.getKey(), version));
|
||||||
@@ -319,12 +288,13 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
|||||||
private LatestUpdate findLatest(Transaction txn, GroupId g, TransportId t,
|
private LatestUpdate findLatest(Transaction txn, GroupId g, TransportId t,
|
||||||
boolean local) throws DbException, FormatException {
|
boolean local) throws DbException, FormatException {
|
||||||
LatestUpdate latest = null;
|
LatestUpdate latest = null;
|
||||||
Map<MessageId, Metadata> metadata = db.getMessageMetadata(txn, g);
|
Map<MessageId, BdfDictionary> metadata =
|
||||||
for (Entry<MessageId, Metadata> e : metadata.entrySet()) {
|
clientHelper.getMessageMetadataAsDictionary(txn, g);
|
||||||
BdfDictionary d = metadataParser.parse(e.getValue());
|
for (Entry<MessageId, BdfDictionary> e : metadata.entrySet()) {
|
||||||
if (d.getString("transportId").equals(t.getString())
|
BdfDictionary meta = e.getValue();
|
||||||
&& d.getBoolean("local") == local) {
|
if (meta.getString("transportId").equals(t.getString())
|
||||||
long version = d.getLong("version");
|
&& meta.getBoolean("local") == local) {
|
||||||
|
long version = meta.getLong("version");
|
||||||
if (latest == null || version > latest.version)
|
if (latest == null || version > latest.version)
|
||||||
latest = new LatestUpdate(e.getKey(), version);
|
latest = new LatestUpdate(e.getKey(), version);
|
||||||
}
|
}
|
||||||
@@ -332,33 +302,14 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
|||||||
return latest;
|
return latest;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TransportProperties parseProperties(byte[] raw)
|
private TransportProperties parseProperties(BdfList message)
|
||||||
throws FormatException {
|
throws FormatException {
|
||||||
|
// Device ID, transport ID, version, properties
|
||||||
|
BdfDictionary dictionary = message.getDictionary(3);
|
||||||
TransportProperties p = new TransportProperties();
|
TransportProperties p = new TransportProperties();
|
||||||
ByteArrayInputStream in = new ByteArrayInputStream(raw,
|
for (String key : dictionary.keySet())
|
||||||
MESSAGE_HEADER_LENGTH, raw.length - MESSAGE_HEADER_LENGTH);
|
p.put(key, dictionary.getString(key));
|
||||||
BdfReader r = bdfReaderFactory.createReader(in);
|
return p;
|
||||||
try {
|
|
||||||
r.readListStart();
|
|
||||||
r.skipRaw(); // Device ID
|
|
||||||
r.skipString(); // Transport ID
|
|
||||||
r.skipLong(); // Version
|
|
||||||
r.readDictionaryStart();
|
|
||||||
while (!r.hasDictionaryEnd()) {
|
|
||||||
String key = r.readString(MAX_PROPERTY_LENGTH);
|
|
||||||
String value = r.readString(MAX_PROPERTY_LENGTH);
|
|
||||||
p.put(key, value);
|
|
||||||
}
|
|
||||||
r.readDictionaryEnd();
|
|
||||||
r.readListEnd();
|
|
||||||
if (!r.eof()) throw new FormatException();
|
|
||||||
return p;
|
|
||||||
} catch (FormatException e) {
|
|
||||||
throw e;
|
|
||||||
} catch (IOException e) {
|
|
||||||
// Shouldn't happen with ByteArrayInputStream
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class LatestUpdate {
|
private static class LatestUpdate {
|
||||||
|
|||||||
Reference in New Issue
Block a user