mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-17 13:19:52 +01:00
Added the ability to store transport configuration details in the
database - unlike transport properties, these are not shared with contacts. For example, when using email as a transport, the address for sending and receiving emails would be a transport property, while the username and password for the email server would be transport configuration details. Transport plugins can update their configuration details atomically. Also clarified the terminology for transport and subscription updates.
This commit is contained in:
@@ -14,8 +14,8 @@ import net.sf.briar.api.protocol.GroupId;
|
|||||||
import net.sf.briar.api.protocol.Message;
|
import net.sf.briar.api.protocol.Message;
|
||||||
import net.sf.briar.api.protocol.MessageId;
|
import net.sf.briar.api.protocol.MessageId;
|
||||||
import net.sf.briar.api.protocol.Offer;
|
import net.sf.briar.api.protocol.Offer;
|
||||||
import net.sf.briar.api.protocol.Subscriptions;
|
import net.sf.briar.api.protocol.SubscriptionUpdate;
|
||||||
import net.sf.briar.api.protocol.Transports;
|
import net.sf.briar.api.protocol.TransportUpdate;
|
||||||
import net.sf.briar.api.protocol.writers.AckWriter;
|
import net.sf.briar.api.protocol.writers.AckWriter;
|
||||||
import net.sf.briar.api.protocol.writers.BatchWriter;
|
import net.sf.briar.api.protocol.writers.BatchWriter;
|
||||||
import net.sf.briar.api.protocol.writers.OfferWriter;
|
import net.sf.briar.api.protocol.writers.OfferWriter;
|
||||||
@@ -95,11 +95,11 @@ public interface DatabaseComponent {
|
|||||||
throws DbException, IOException;
|
throws DbException, IOException;
|
||||||
|
|
||||||
/** Generates a subscription update for the given contact. */
|
/** Generates a subscription update for the given contact. */
|
||||||
void generateSubscriptions(ContactId c, SubscriptionWriter s) throws
|
void generateSubscriptionUpdate(ContactId c, SubscriptionWriter s) throws
|
||||||
DbException, IOException;
|
DbException, IOException;
|
||||||
|
|
||||||
/** Generates a transport update for the given contact. */
|
/** Generates a transport update for the given contact. */
|
||||||
void generateTransports(ContactId c, TransportWriter t) throws
|
void generateTransportUpdate(ContactId c, TransportWriter t) throws
|
||||||
DbException, IOException;
|
DbException, IOException;
|
||||||
|
|
||||||
/** Returns the IDs of all contacts. */
|
/** Returns the IDs of all contacts. */
|
||||||
@@ -111,10 +111,13 @@ public interface DatabaseComponent {
|
|||||||
/** Returns the set of groups to which the user subscribes. */
|
/** Returns the set of groups to which the user subscribes. */
|
||||||
Collection<Group> getSubscriptions() throws DbException;
|
Collection<Group> getSubscriptions() throws DbException;
|
||||||
|
|
||||||
/** Returns the local transport properties. */
|
/** Returns the configuration for the transport with the given name. */
|
||||||
|
Map<String, String> getTransportConfig(String name) throws DbException;
|
||||||
|
|
||||||
|
/** Returns all local transport properties. */
|
||||||
Map<String, Map<String, String>> getTransports() throws DbException;
|
Map<String, Map<String, String>> getTransports() throws DbException;
|
||||||
|
|
||||||
/** Returns the transport properties for the given contact. */
|
/** Returns all transport properties for the given contact. */
|
||||||
Map<String, Map<String, String>> getTransports(ContactId c)
|
Map<String, Map<String, String>> getTransports(ContactId c)
|
||||||
throws DbException;
|
throws DbException;
|
||||||
|
|
||||||
@@ -142,10 +145,12 @@ public interface DatabaseComponent {
|
|||||||
IOException;
|
IOException;
|
||||||
|
|
||||||
/** Processes a subscription update from the given contact. */
|
/** Processes a subscription update from the given contact. */
|
||||||
void receiveSubscriptions(ContactId c, Subscriptions s) throws DbException;
|
void receiveSubscriptionUpdate(ContactId c, SubscriptionUpdate s)
|
||||||
|
throws DbException;
|
||||||
|
|
||||||
/** Processes a transport update from the given contact. */
|
/** Processes a transport update from the given contact. */
|
||||||
void receiveTransports(ContactId c, Transports t) throws DbException;
|
void receiveTransportUpdate(ContactId c, TransportUpdate t)
|
||||||
|
throws DbException;
|
||||||
|
|
||||||
/** Removes a contact (and all associated state) from the database. */
|
/** Removes a contact (and all associated state) from the database. */
|
||||||
void removeContact(ContactId c) throws DbException;
|
void removeContact(ContactId c) throws DbException;
|
||||||
@@ -154,10 +159,17 @@ public interface DatabaseComponent {
|
|||||||
void setRating(AuthorId a, Rating r) throws DbException;
|
void setRating(AuthorId a, Rating r) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the local transport properties for the transport with the given
|
* Sets the configuration for the transport with the given name, replacing
|
||||||
* name, replacing any existing properties for that transport.
|
* any existing configuration for that transport.
|
||||||
*/
|
*/
|
||||||
void setTransports(String name, Map<String, String> transports)
|
void setTransportConfig(String name, Map<String, String> config)
|
||||||
|
throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the transport properties for the transport with the given name,
|
||||||
|
* replacing any existing properties for that transport.
|
||||||
|
*/
|
||||||
|
void setTransportProperties(String name, Map<String, String> properties)
|
||||||
throws DbException;
|
throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ package net.sf.briar.api.protocol;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
/** A packet updating the sender's subscriptions. */
|
/** A packet updating the sender's subscriptions. */
|
||||||
public interface Subscriptions {
|
public interface SubscriptionUpdate {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The maximum size of a serialized subscriptions update, excluding
|
* The maximum size of a serialized subscription update, excluding
|
||||||
* encryption and authentication.
|
* encryption and authentication.
|
||||||
*/
|
*/
|
||||||
static final int MAX_SIZE = (1024 * 1024) - 100;
|
static final int MAX_SIZE = (1024 * 1024) - 100;
|
||||||
@@ -2,16 +2,16 @@ package net.sf.briar.api.protocol;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/** A packet updating the sender's transports. */
|
/** A packet updating the sender's transport properties. */
|
||||||
public interface Transports {
|
public interface TransportUpdate {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The maximum size of a serialised transports update, excluding
|
* The maximum size of a serialised transport update, excluding
|
||||||
* encryption and authentication.
|
* encryption and authentication.
|
||||||
*/
|
*/
|
||||||
static final int MAX_SIZE = (1024 * 1024) - 100;
|
static final int MAX_SIZE = (1024 * 1024) - 100;
|
||||||
|
|
||||||
/** Returns the transports contained in the update. */
|
/** Returns the transport properties contained in the update. */
|
||||||
Map<String, Map<String, String>> getTransports();
|
Map<String, Map<String, String>> getTransports();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -3,7 +3,7 @@ package net.sf.briar.api.protocol.writers;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/** An interface for creating a transports update. */
|
/** An interface for creating a transport update. */
|
||||||
public interface TransportWriter {
|
public interface TransportWriter {
|
||||||
|
|
||||||
/** Writes the contents of the update. */
|
/** Writes the contents of the update. */
|
||||||
|
|||||||
@@ -268,14 +268,22 @@ interface Database<T> {
|
|||||||
Collection<Group> getSubscriptions(T txn, ContactId c) throws DbException;
|
Collection<Group> getSubscriptions(T txn, ContactId c) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the local transport properties.
|
* Returns the configuration for the transport with the given name.
|
||||||
|
* <p>
|
||||||
|
* Locking: transports read.
|
||||||
|
*/
|
||||||
|
Map<String, String> getTransportConfig(T txn, String name)
|
||||||
|
throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all local transport properties.
|
||||||
* <p>
|
* <p>
|
||||||
* Locking: transports read.
|
* Locking: transports read.
|
||||||
*/
|
*/
|
||||||
Map<String, Map<String, String>> getTransports(T txn) throws DbException;
|
Map<String, Map<String, String>> getTransports(T txn) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the transport properties for the given contact.
|
* Returns all transport properties for the given contact.
|
||||||
* <p>
|
* <p>
|
||||||
* Locking: contacts read, transports read.
|
* Locking: contacts read, transports read.
|
||||||
*/
|
*/
|
||||||
@@ -398,14 +406,23 @@ interface Database<T> {
|
|||||||
long timestamp) throws DbException;
|
long timestamp) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the local transport properties for the transport with the given
|
* Sets the configuration for the transport with the given name, replacing
|
||||||
* name, replacing any existing properties for that transport.
|
* any existing configuration for that transport.
|
||||||
* <p>
|
* <p>
|
||||||
* Locking: transports write.
|
* Locking: transports write.
|
||||||
*/
|
*/
|
||||||
void setTransports(T txn, String name, Map<String, String> transports)
|
void setTransportConfig(T txn, String name, Map<String, String> config)
|
||||||
throws DbException;
|
throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the transport properties for the transport with the given name,
|
||||||
|
* replacing any existing properties for that transport.
|
||||||
|
* <p>
|
||||||
|
* Locking: transports write.
|
||||||
|
*/
|
||||||
|
void setTransportProperties(T txn, String name,
|
||||||
|
Map<String, String> properties) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the transport properties for the given contact, replacing any
|
* Sets the transport properties for the given contact, replacing any
|
||||||
* existing properties unless the existing properties have a newer
|
* existing properties unless the existing properties have a newer
|
||||||
|
|||||||
@@ -173,6 +173,13 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
+ " value VARCHAR NOT NULL,"
|
+ " value VARCHAR NOT NULL,"
|
||||||
+ " PRIMARY KEY (transportName, key))";
|
+ " PRIMARY KEY (transportName, key))";
|
||||||
|
|
||||||
|
private static final String CREATE_TRANSPORT_CONFIG =
|
||||||
|
"CREATE TABLE transportConfig"
|
||||||
|
+ " (transportName VARCHAR NOT NULL,"
|
||||||
|
+ " key VARCHAR NOT NULL,"
|
||||||
|
+ " value VARCHAR NOT NULL,"
|
||||||
|
+ " PRIMARY KEY (transportName, key))";
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(JdbcDatabase.class.getName());
|
Logger.getLogger(JdbcDatabase.class.getName());
|
||||||
|
|
||||||
@@ -255,6 +262,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
s.executeUpdate(INDEX_STATUSES_BY_CONTACT);
|
s.executeUpdate(INDEX_STATUSES_BY_CONTACT);
|
||||||
s.executeUpdate(insertTypeNames(CREATE_CONTACT_TRANSPORTS));
|
s.executeUpdate(insertTypeNames(CREATE_CONTACT_TRANSPORTS));
|
||||||
s.executeUpdate(insertTypeNames(CREATE_TRANSPORTS));
|
s.executeUpdate(insertTypeNames(CREATE_TRANSPORTS));
|
||||||
|
s.executeUpdate(insertTypeNames(CREATE_TRANSPORT_CONFIG));
|
||||||
s.close();
|
s.close();
|
||||||
} catch(SQLException e) {
|
} catch(SQLException e) {
|
||||||
tryToClose(s);
|
tryToClose(s);
|
||||||
@@ -1096,6 +1104,115 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getTransportConfig(Connection txn,
|
||||||
|
String name) throws DbException {
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try {
|
||||||
|
String sql = "SELECT key, value FROM transportConfig"
|
||||||
|
+ " WHERE transportName = ?";
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
ps.setString(1, name);
|
||||||
|
rs = ps.executeQuery();
|
||||||
|
Map<String, String> config = new TreeMap<String, String>();
|
||||||
|
while(rs.next()) config.put(rs.getString(1), rs.getString(2));
|
||||||
|
rs.close();
|
||||||
|
ps.close();
|
||||||
|
return config;
|
||||||
|
} catch(SQLException e) {
|
||||||
|
tryToClose(rs);
|
||||||
|
tryToClose(ps);
|
||||||
|
throw new DbException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Map<String, String>> getTransports(Connection txn)
|
||||||
|
throws DbException {
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try {
|
||||||
|
String sql = "SELECT transportName, key, value"
|
||||||
|
+ " FROM transports"
|
||||||
|
+ " ORDER BY transportName";
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
rs = ps.executeQuery();
|
||||||
|
Map<String, Map<String, String>> transports =
|
||||||
|
new TreeMap<String, Map<String, String>>();
|
||||||
|
Map<String, String> properties = null;
|
||||||
|
String lastName = null;
|
||||||
|
while(rs.next()) {
|
||||||
|
String name = rs.getString(1);
|
||||||
|
if(!name.equals(lastName)) {
|
||||||
|
properties = new TreeMap<String, String>();
|
||||||
|
transports.put(name, properties);
|
||||||
|
}
|
||||||
|
properties.put(rs.getString(2), rs.getString(3));
|
||||||
|
}
|
||||||
|
rs.close();
|
||||||
|
ps.close();
|
||||||
|
return transports;
|
||||||
|
} catch(SQLException e) {
|
||||||
|
tryToClose(rs);
|
||||||
|
tryToClose(ps);
|
||||||
|
throw new DbException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Map<String, String>> getTransports(Connection txn,
|
||||||
|
ContactId c) throws DbException {
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try {
|
||||||
|
String sql = "SELECT transportName, key, value"
|
||||||
|
+ " FROM contactTransports"
|
||||||
|
+ " WHERE contactId = ?"
|
||||||
|
+ " ORDER BY transportName";
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
ps.setInt(1, c.getInt());
|
||||||
|
rs = ps.executeQuery();
|
||||||
|
Map<String, Map<String, String>> transports =
|
||||||
|
new TreeMap<String, Map<String, String>>();
|
||||||
|
Map<String, String> properties = null;
|
||||||
|
String lastName = null;
|
||||||
|
while(rs.next()) {
|
||||||
|
String name = rs.getString(1);
|
||||||
|
if(!name.equals(lastName)) {
|
||||||
|
properties = new TreeMap<String, String>();
|
||||||
|
transports.put(name, properties);
|
||||||
|
}
|
||||||
|
properties.put(rs.getString(2), rs.getString(3));
|
||||||
|
}
|
||||||
|
rs.close();
|
||||||
|
ps.close();
|
||||||
|
return transports;
|
||||||
|
} catch(SQLException e) {
|
||||||
|
tryToClose(rs);
|
||||||
|
tryToClose(ps);
|
||||||
|
throw new DbException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<ContactId> getVisibility(Connection txn, GroupId g)
|
||||||
|
throws DbException {
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try {
|
||||||
|
String sql = "SELECT contactId FROM visibilities WHERE groupId = ?";
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
ps.setBytes(1, g.getBytes());
|
||||||
|
rs = ps.executeQuery();
|
||||||
|
Collection<ContactId> visible = new ArrayList<ContactId>();
|
||||||
|
while(rs.next()) visible.add(new ContactId(rs.getInt(1)));
|
||||||
|
rs.close();
|
||||||
|
ps.close();
|
||||||
|
return visible;
|
||||||
|
} catch(SQLException e) {
|
||||||
|
tryToClose(rs);
|
||||||
|
tryToClose(ps);
|
||||||
|
throw new DbException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Collection<Group> getVisibleSubscriptions(Connection txn,
|
public Collection<Group> getVisibleSubscriptions(Connection txn,
|
||||||
ContactId c) throws DbException {
|
ContactId c) throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
@@ -1125,93 +1242,6 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Map<String, String>> getTransports(Connection txn)
|
|
||||||
throws DbException {
|
|
||||||
PreparedStatement ps = null;
|
|
||||||
ResultSet rs = null;
|
|
||||||
try {
|
|
||||||
String sql = "SELECT transportName, key, value"
|
|
||||||
+ " FROM transports"
|
|
||||||
+ " ORDER BY transportName";
|
|
||||||
ps = txn.prepareStatement(sql);
|
|
||||||
rs = ps.executeQuery();
|
|
||||||
Map<String, Map<String, String>> outer =
|
|
||||||
new TreeMap<String, Map<String, String>>();
|
|
||||||
Map<String, String> inner = null;
|
|
||||||
String lastName = null;
|
|
||||||
while(rs.next()) {
|
|
||||||
String name = rs.getString(1);
|
|
||||||
if(!name.equals(lastName)) {
|
|
||||||
inner = new TreeMap<String, String>();
|
|
||||||
outer.put(name, inner);
|
|
||||||
}
|
|
||||||
inner.put(rs.getString(2), rs.getString(3));
|
|
||||||
}
|
|
||||||
rs.close();
|
|
||||||
ps.close();
|
|
||||||
return outer;
|
|
||||||
} catch(SQLException e) {
|
|
||||||
tryToClose(rs);
|
|
||||||
tryToClose(ps);
|
|
||||||
throw new DbException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, Map<String, String>> getTransports(Connection txn,
|
|
||||||
ContactId c) throws DbException {
|
|
||||||
PreparedStatement ps = null;
|
|
||||||
ResultSet rs = null;
|
|
||||||
try {
|
|
||||||
String sql = "SELECT transportName, key, value"
|
|
||||||
+ " FROM contactTransports"
|
|
||||||
+ " WHERE contactId = ?"
|
|
||||||
+ " ORDER BY transportName";
|
|
||||||
ps = txn.prepareStatement(sql);
|
|
||||||
ps.setInt(1, c.getInt());
|
|
||||||
rs = ps.executeQuery();
|
|
||||||
Map<String, Map<String, String>> outer =
|
|
||||||
new TreeMap<String, Map<String, String>>();
|
|
||||||
Map<String, String> inner = null;
|
|
||||||
String lastName = null;
|
|
||||||
while(rs.next()) {
|
|
||||||
String name = rs.getString(1);
|
|
||||||
if(!name.equals(lastName)) {
|
|
||||||
inner = new TreeMap<String, String>();
|
|
||||||
outer.put(name, inner);
|
|
||||||
}
|
|
||||||
inner.put(rs.getString(2), rs.getString(3));
|
|
||||||
}
|
|
||||||
rs.close();
|
|
||||||
ps.close();
|
|
||||||
return outer;
|
|
||||||
} catch(SQLException e) {
|
|
||||||
tryToClose(rs);
|
|
||||||
tryToClose(ps);
|
|
||||||
throw new DbException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Collection<ContactId> getVisibility(Connection txn, GroupId g)
|
|
||||||
throws DbException {
|
|
||||||
PreparedStatement ps = null;
|
|
||||||
ResultSet rs = null;
|
|
||||||
try {
|
|
||||||
String sql = "SELECT contactId FROM visibilities WHERE groupId = ?";
|
|
||||||
ps = txn.prepareStatement(sql);
|
|
||||||
ps.setBytes(1, g.getBytes());
|
|
||||||
rs = ps.executeQuery();
|
|
||||||
Collection<ContactId> visible = new ArrayList<ContactId>();
|
|
||||||
while(rs.next()) visible.add(new ContactId(rs.getInt(1)));
|
|
||||||
rs.close();
|
|
||||||
ps.close();
|
|
||||||
return visible;
|
|
||||||
} catch(SQLException e) {
|
|
||||||
tryToClose(rs);
|
|
||||||
tryToClose(ps);
|
|
||||||
throw new DbException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasSendableMessages(Connection txn, ContactId c)
|
public boolean hasSendableMessages(Connection txn, ContactId c)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
@@ -1609,28 +1639,33 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTransports(Connection txn, String name,
|
public void setTransportConfig(Connection txn, String name,
|
||||||
Map<String, String> transports) throws DbException {
|
Map<String, String> config) throws DbException {
|
||||||
|
setTransportDetails(txn, name, config, "transportConfig");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setTransportDetails(Connection txn, String name,
|
||||||
|
Map<String, String> details, String table) throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
try {
|
try {
|
||||||
// Delete any existing properties for the named transport
|
// Delete any existing details for the named transport
|
||||||
String sql = "DELETE FROM transports WHERE transportName = ?";
|
String sql = "DELETE FROM " + table + " WHERE transportName = ?";
|
||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
ps.setString(1, name);
|
ps.setString(1, name);
|
||||||
ps.executeUpdate();
|
ps.executeUpdate();
|
||||||
ps.close();
|
ps.close();
|
||||||
// Store the new properties
|
// Store the new details
|
||||||
sql = "INSERT INTO transports (transportName, key, value)"
|
sql = "INSERT INTO " + table + " (transportName, key, value)"
|
||||||
+ " VALUES (?, ?, ?)";
|
+ " VALUES (?, ?, ?)";
|
||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
ps.setString(1, name);
|
ps.setString(1, name);
|
||||||
for(Entry<String, String> e : transports.entrySet()) {
|
for(Entry<String, String> e : details.entrySet()) {
|
||||||
ps.setString(2, e.getKey());
|
ps.setString(2, e.getKey());
|
||||||
ps.setString(3, e.getValue());
|
ps.setString(3, e.getValue());
|
||||||
ps.addBatch();
|
ps.addBatch();
|
||||||
}
|
}
|
||||||
int[] batchAffected = ps.executeBatch();
|
int[] batchAffected = ps.executeBatch();
|
||||||
if(batchAffected.length != transports.size())
|
if(batchAffected.length != details.size())
|
||||||
throw new DbStateException();
|
throw new DbStateException();
|
||||||
for(int i = 0; i < batchAffected.length; i++) {
|
for(int i = 0; i < batchAffected.length; i++) {
|
||||||
if(batchAffected[i] != 1) throw new DbStateException();
|
if(batchAffected[i] != 1) throw new DbStateException();
|
||||||
@@ -1642,6 +1677,11 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setTransportProperties(Connection txn, String name,
|
||||||
|
Map<String, String> properties) throws DbException {
|
||||||
|
setTransportDetails(txn, name, properties, "transports");
|
||||||
|
}
|
||||||
|
|
||||||
public void setTransports(Connection txn, ContactId c,
|
public void setTransports(Connection txn, ContactId c,
|
||||||
Map<String, Map<String, String>> transports, long timestamp)
|
Map<String, Map<String, String>> transports, long timestamp)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ import net.sf.briar.api.protocol.GroupId;
|
|||||||
import net.sf.briar.api.protocol.Message;
|
import net.sf.briar.api.protocol.Message;
|
||||||
import net.sf.briar.api.protocol.MessageId;
|
import net.sf.briar.api.protocol.MessageId;
|
||||||
import net.sf.briar.api.protocol.Offer;
|
import net.sf.briar.api.protocol.Offer;
|
||||||
import net.sf.briar.api.protocol.Subscriptions;
|
import net.sf.briar.api.protocol.SubscriptionUpdate;
|
||||||
import net.sf.briar.api.protocol.Transports;
|
import net.sf.briar.api.protocol.TransportUpdate;
|
||||||
import net.sf.briar.api.protocol.writers.AckWriter;
|
import net.sf.briar.api.protocol.writers.AckWriter;
|
||||||
import net.sf.briar.api.protocol.writers.BatchWriter;
|
import net.sf.briar.api.protocol.writers.BatchWriter;
|
||||||
import net.sf.briar.api.protocol.writers.OfferWriter;
|
import net.sf.briar.api.protocol.writers.OfferWriter;
|
||||||
@@ -107,7 +107,12 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
|||||||
try {
|
try {
|
||||||
subscriptionLock.writeLock().lock();
|
subscriptionLock.writeLock().lock();
|
||||||
try {
|
try {
|
||||||
db.close();
|
transportLock.writeLock().lock();
|
||||||
|
try {
|
||||||
|
db.close();
|
||||||
|
} finally {
|
||||||
|
transportLock.writeLock().unlock();
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
subscriptionLock.writeLock().unlock();
|
subscriptionLock.writeLock().unlock();
|
||||||
}
|
}
|
||||||
@@ -459,7 +464,7 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generateSubscriptions(ContactId c, SubscriptionWriter s)
|
public void generateSubscriptionUpdate(ContactId c, SubscriptionWriter s)
|
||||||
throws DbException, IOException {
|
throws DbException, IOException {
|
||||||
contactLock.readLock().lock();
|
contactLock.readLock().lock();
|
||||||
try {
|
try {
|
||||||
@@ -488,7 +493,7 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generateTransports(ContactId c, TransportWriter t)
|
public void generateTransportUpdate(ContactId c, TransportWriter t)
|
||||||
throws DbException, IOException {
|
throws DbException, IOException {
|
||||||
contactLock.readLock().lock();
|
contactLock.readLock().lock();
|
||||||
try {
|
try {
|
||||||
@@ -569,6 +574,24 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getTransportConfig(String name)
|
||||||
|
throws DbException {
|
||||||
|
transportLock.readLock().lock();
|
||||||
|
try {
|
||||||
|
Txn txn = db.startTransaction();
|
||||||
|
try {
|
||||||
|
Map<String, String> config = db.getTransportConfig(txn, name);
|
||||||
|
db.commitTransaction(txn);
|
||||||
|
return config;
|
||||||
|
} catch(DbException e) {
|
||||||
|
db.abortTransaction(txn);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
transportLock.readLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Map<String, Map<String, String>> getTransports() throws DbException {
|
public Map<String, Map<String, String>> getTransports() throws DbException {
|
||||||
transportLock.readLock().lock();
|
transportLock.readLock().lock();
|
||||||
try {
|
try {
|
||||||
@@ -793,7 +816,7 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void receiveSubscriptions(ContactId c, Subscriptions s)
|
public void receiveSubscriptionUpdate(ContactId c, SubscriptionUpdate s)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
// Update the contact's subscriptions
|
// Update the contact's subscriptions
|
||||||
contactLock.writeLock().lock();
|
contactLock.writeLock().lock();
|
||||||
@@ -820,7 +843,7 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void receiveTransports(ContactId c, Transports t)
|
public void receiveTransportUpdate(ContactId c, TransportUpdate t)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
// Update the contact's transport properties
|
// Update the contact's transport properties
|
||||||
contactLock.writeLock().lock();
|
contactLock.writeLock().lock();
|
||||||
@@ -907,15 +930,40 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTransports(String name, Map<String, String> transports)
|
public void setTransportConfig(String name,
|
||||||
throws DbException {
|
Map<String, String> config) throws DbException {
|
||||||
boolean changed = false;
|
boolean changed = false;
|
||||||
transportLock.writeLock().lock();
|
transportLock.writeLock().lock();
|
||||||
try {
|
try {
|
||||||
Txn txn = db.startTransaction();
|
Txn txn = db.startTransaction();
|
||||||
try {
|
try {
|
||||||
if(!transports.equals(db.getTransports(txn).get(name))) {
|
Map<String, String> old = db.getTransportConfig(txn, name);
|
||||||
db.setTransports(txn, name, transports);
|
if(!config.equals(old)) {
|
||||||
|
db.setTransportConfig(txn, name, config);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
db.commitTransaction(txn);
|
||||||
|
} catch(DbException e) {
|
||||||
|
db.abortTransaction(txn);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
transportLock.writeLock().unlock();
|
||||||
|
}
|
||||||
|
// Call the listeners outside the lock
|
||||||
|
if(changed) callListeners(DatabaseListener.Event.TRANSPORTS_UPDATED);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransportProperties(String name,
|
||||||
|
Map<String, String> properties) throws DbException {
|
||||||
|
boolean changed = false;
|
||||||
|
transportLock.writeLock().lock();
|
||||||
|
try {
|
||||||
|
Txn txn = db.startTransaction();
|
||||||
|
try {
|
||||||
|
Map<String, String> old = db.getTransports(txn).get(name);
|
||||||
|
if(!properties.equals(old)) {
|
||||||
|
db.setTransportProperties(txn, name, properties);
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
db.commitTransaction(txn);
|
db.commitTransaction(txn);
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ import net.sf.briar.api.protocol.GroupId;
|
|||||||
import net.sf.briar.api.protocol.Message;
|
import net.sf.briar.api.protocol.Message;
|
||||||
import net.sf.briar.api.protocol.MessageId;
|
import net.sf.briar.api.protocol.MessageId;
|
||||||
import net.sf.briar.api.protocol.Offer;
|
import net.sf.briar.api.protocol.Offer;
|
||||||
import net.sf.briar.api.protocol.Subscriptions;
|
import net.sf.briar.api.protocol.SubscriptionUpdate;
|
||||||
import net.sf.briar.api.protocol.Transports;
|
import net.sf.briar.api.protocol.TransportUpdate;
|
||||||
import net.sf.briar.api.protocol.writers.AckWriter;
|
import net.sf.briar.api.protocol.writers.AckWriter;
|
||||||
import net.sf.briar.api.protocol.writers.BatchWriter;
|
import net.sf.briar.api.protocol.writers.BatchWriter;
|
||||||
import net.sf.briar.api.protocol.writers.OfferWriter;
|
import net.sf.briar.api.protocol.writers.OfferWriter;
|
||||||
@@ -336,7 +336,7 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generateSubscriptions(ContactId c, SubscriptionWriter s)
|
public void generateSubscriptionUpdate(ContactId c, SubscriptionWriter s)
|
||||||
throws DbException, IOException {
|
throws DbException, IOException {
|
||||||
synchronized(contactLock) {
|
synchronized(contactLock) {
|
||||||
if(!containsContact(c)) throw new NoSuchContactException();
|
if(!containsContact(c)) throw new NoSuchContactException();
|
||||||
@@ -359,7 +359,7 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generateTransports(ContactId c, TransportWriter t)
|
public void generateTransportUpdate(ContactId c, TransportWriter t)
|
||||||
throws DbException, IOException {
|
throws DbException, IOException {
|
||||||
synchronized(contactLock) {
|
synchronized(contactLock) {
|
||||||
if(!containsContact(c)) throw new NoSuchContactException();
|
if(!containsContact(c)) throw new NoSuchContactException();
|
||||||
@@ -425,6 +425,21 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getTransportConfig(String name)
|
||||||
|
throws DbException {
|
||||||
|
synchronized(transportLock) {
|
||||||
|
Txn txn = db.startTransaction();
|
||||||
|
try {
|
||||||
|
Map<String, String> config = db.getTransportConfig(txn, name);
|
||||||
|
db.commitTransaction(txn);
|
||||||
|
return config;
|
||||||
|
} catch(DbException e) {
|
||||||
|
db.abortTransaction(txn);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Map<String, Map<String, String>> getTransports() throws DbException {
|
public Map<String, Map<String, String>> getTransports() throws DbException {
|
||||||
synchronized(transportLock) {
|
synchronized(transportLock) {
|
||||||
Txn txn = db.startTransaction();
|
Txn txn = db.startTransaction();
|
||||||
@@ -589,7 +604,7 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void receiveSubscriptions(ContactId c, Subscriptions s)
|
public void receiveSubscriptionUpdate(ContactId c, SubscriptionUpdate s)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
// Update the contact's subscriptions
|
// Update the contact's subscriptions
|
||||||
synchronized(contactLock) {
|
synchronized(contactLock) {
|
||||||
@@ -610,7 +625,7 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void receiveTransports(ContactId c, Transports t)
|
public void receiveTransportUpdate(ContactId c, TransportUpdate t)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
// Update the contact's transport properties
|
// Update the contact's transport properties
|
||||||
synchronized(contactLock) {
|
synchronized(contactLock) {
|
||||||
@@ -673,14 +688,36 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTransports(String name, Map<String, String> transports)
|
public void setTransportConfig(String name,
|
||||||
throws DbException {
|
Map<String, String> config) throws DbException {
|
||||||
boolean changed = false;
|
boolean changed = false;
|
||||||
synchronized(transportLock) {
|
synchronized(transportLock) {
|
||||||
Txn txn = db.startTransaction();
|
Txn txn = db.startTransaction();
|
||||||
try {
|
try {
|
||||||
if(!transports.equals(db.getTransports(txn).get(name))) {
|
Map<String, String> old = db.getTransportConfig(txn, name);
|
||||||
db.setTransports(txn, name, transports);
|
if(!config.equals(old)) {
|
||||||
|
db.setTransportConfig(txn, name, config);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
db.commitTransaction(txn);
|
||||||
|
} catch(DbException e) {
|
||||||
|
db.abortTransaction(txn);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Call the listeners outside the lock
|
||||||
|
if(changed) callListeners(DatabaseListener.Event.TRANSPORTS_UPDATED);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransportProperties(String name,
|
||||||
|
Map<String, String> properties) throws DbException {
|
||||||
|
boolean changed = false;
|
||||||
|
synchronized(transportLock) {
|
||||||
|
Txn txn = db.startTransaction();
|
||||||
|
try {
|
||||||
|
Map<String, String> old = db.getTransports(txn).get(name);
|
||||||
|
if(!properties.equals(old)) {
|
||||||
|
db.setTransportProperties(txn, name, properties);
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
db.commitTransaction(txn);
|
db.commitTransaction(txn);
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ package net.sf.briar.protocol;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import net.sf.briar.api.protocol.Group;
|
import net.sf.briar.api.protocol.Group;
|
||||||
import net.sf.briar.api.protocol.Subscriptions;
|
import net.sf.briar.api.protocol.SubscriptionUpdate;
|
||||||
|
|
||||||
interface SubscriptionFactory {
|
interface SubscriptionFactory {
|
||||||
|
|
||||||
Subscriptions createSubscriptions(Collection<Group> subs, long timestamp);
|
SubscriptionUpdate createSubscriptions(Collection<Group> subs, long timestamp);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ package net.sf.briar.protocol;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import net.sf.briar.api.protocol.Group;
|
import net.sf.briar.api.protocol.Group;
|
||||||
import net.sf.briar.api.protocol.Subscriptions;
|
import net.sf.briar.api.protocol.SubscriptionUpdate;
|
||||||
|
|
||||||
class SubscriptionFactoryImpl implements SubscriptionFactory {
|
class SubscriptionFactoryImpl implements SubscriptionFactory {
|
||||||
|
|
||||||
public Subscriptions createSubscriptions(Collection<Group> subs,
|
public SubscriptionUpdate createSubscriptions(Collection<Group> subs,
|
||||||
long timestamp) {
|
long timestamp) {
|
||||||
return new SubscriptionsImpl(subs, timestamp);
|
return new SubscriptionsImpl(subs, timestamp);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import java.io.IOException;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import net.sf.briar.api.protocol.Group;
|
import net.sf.briar.api.protocol.Group;
|
||||||
import net.sf.briar.api.protocol.Subscriptions;
|
import net.sf.briar.api.protocol.SubscriptionUpdate;
|
||||||
import net.sf.briar.api.protocol.Tags;
|
import net.sf.briar.api.protocol.Tags;
|
||||||
import net.sf.briar.api.serial.Consumer;
|
import net.sf.briar.api.serial.Consumer;
|
||||||
import net.sf.briar.api.serial.ObjectReader;
|
import net.sf.briar.api.serial.ObjectReader;
|
||||||
@@ -12,7 +12,7 @@ import net.sf.briar.api.serial.Reader;
|
|||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
class SubscriptionReader implements ObjectReader<Subscriptions> {
|
class SubscriptionReader implements ObjectReader<SubscriptionUpdate> {
|
||||||
|
|
||||||
private final ObjectReader<Group> groupReader;
|
private final ObjectReader<Group> groupReader;
|
||||||
private final SubscriptionFactory subscriptionFactory;
|
private final SubscriptionFactory subscriptionFactory;
|
||||||
@@ -24,9 +24,9 @@ class SubscriptionReader implements ObjectReader<Subscriptions> {
|
|||||||
this.subscriptionFactory = subscriptionFactory;
|
this.subscriptionFactory = subscriptionFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Subscriptions readObject(Reader r) throws IOException {
|
public SubscriptionUpdate readObject(Reader r) throws IOException {
|
||||||
// Initialise the consumer
|
// Initialise the consumer
|
||||||
Consumer counting = new CountingConsumer(Subscriptions.MAX_SIZE);
|
Consumer counting = new CountingConsumer(SubscriptionUpdate.MAX_SIZE);
|
||||||
// Read the data
|
// Read the data
|
||||||
r.addConsumer(counting);
|
r.addConsumer(counting);
|
||||||
r.readUserDefinedTag(Tags.SUBSCRIPTIONS);
|
r.readUserDefinedTag(Tags.SUBSCRIPTIONS);
|
||||||
@@ -35,7 +35,7 @@ class SubscriptionReader implements ObjectReader<Subscriptions> {
|
|||||||
r.removeObjectReader(Tags.GROUP);
|
r.removeObjectReader(Tags.GROUP);
|
||||||
long timestamp = r.readInt64();
|
long timestamp = r.readInt64();
|
||||||
r.removeConsumer(counting);
|
r.removeConsumer(counting);
|
||||||
// Build and return the subscriptions update
|
// Build and return the subscription update
|
||||||
return subscriptionFactory.createSubscriptions(subs, timestamp);
|
return subscriptionFactory.createSubscriptions(subs, timestamp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ package net.sf.briar.protocol;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import net.sf.briar.api.protocol.Group;
|
import net.sf.briar.api.protocol.Group;
|
||||||
import net.sf.briar.api.protocol.Subscriptions;
|
import net.sf.briar.api.protocol.SubscriptionUpdate;
|
||||||
|
|
||||||
class SubscriptionsImpl implements Subscriptions {
|
class SubscriptionsImpl implements SubscriptionUpdate {
|
||||||
|
|
||||||
private final Collection<Group> subs;
|
private final Collection<Group> subs;
|
||||||
private final long timestamp;
|
private final long timestamp;
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ package net.sf.briar.protocol;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import net.sf.briar.api.protocol.Transports;
|
import net.sf.briar.api.protocol.TransportUpdate;
|
||||||
|
|
||||||
interface TransportFactory {
|
interface TransportFactory {
|
||||||
|
|
||||||
Transports createTransports(Map<String, Map<String, String>> transports,
|
TransportUpdate createTransports(Map<String, Map<String, String>> transports,
|
||||||
long timestamp);
|
long timestamp);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ package net.sf.briar.protocol;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import net.sf.briar.api.protocol.Transports;
|
import net.sf.briar.api.protocol.TransportUpdate;
|
||||||
|
|
||||||
class TransportFactoryImpl implements TransportFactory {
|
class TransportFactoryImpl implements TransportFactory {
|
||||||
|
|
||||||
public Transports createTransports(Map<String, Map<String, String>> transports,
|
public TransportUpdate createTransports(Map<String, Map<String, String>> transports,
|
||||||
long timestamp) {
|
long timestamp) {
|
||||||
return new TransportsImpl(transports, timestamp);
|
return new TransportsImpl(transports, timestamp);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,14 +5,14 @@ import java.util.Map;
|
|||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
import net.sf.briar.api.protocol.Tags;
|
import net.sf.briar.api.protocol.Tags;
|
||||||
import net.sf.briar.api.protocol.Transports;
|
import net.sf.briar.api.protocol.TransportUpdate;
|
||||||
import net.sf.briar.api.serial.Consumer;
|
import net.sf.briar.api.serial.Consumer;
|
||||||
import net.sf.briar.api.serial.ObjectReader;
|
import net.sf.briar.api.serial.ObjectReader;
|
||||||
import net.sf.briar.api.serial.Reader;
|
import net.sf.briar.api.serial.Reader;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
class TransportReader implements ObjectReader<Transports> {
|
class TransportReader implements ObjectReader<TransportUpdate> {
|
||||||
|
|
||||||
private final TransportFactory transportFactory;
|
private final TransportFactory transportFactory;
|
||||||
|
|
||||||
@@ -21,32 +21,32 @@ class TransportReader implements ObjectReader<Transports> {
|
|||||||
this.transportFactory = transportFactory;
|
this.transportFactory = transportFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Transports readObject(Reader r) throws IOException {
|
public TransportUpdate readObject(Reader r) throws IOException {
|
||||||
// Initialise the consumer
|
// Initialise the consumer
|
||||||
Consumer counting = new CountingConsumer(Transports.MAX_SIZE);
|
Consumer counting = new CountingConsumer(TransportUpdate.MAX_SIZE);
|
||||||
// Read the data
|
// Read the data
|
||||||
r.addConsumer(counting);
|
r.addConsumer(counting);
|
||||||
r.readUserDefinedTag(Tags.TRANSPORTS);
|
r.readUserDefinedTag(Tags.TRANSPORTS);
|
||||||
// Transport maps are always written in delimited form
|
// Transport maps are always written in delimited form
|
||||||
Map<String, Map<String, String>> outer =
|
Map<String, Map<String, String>> transports =
|
||||||
new TreeMap<String, Map<String, String>>();
|
new TreeMap<String, Map<String, String>>();
|
||||||
r.readMapStart();
|
r.readMapStart();
|
||||||
while(!r.hasMapEnd()) {
|
while(!r.hasMapEnd()) {
|
||||||
String name = r.readString(Transports.MAX_SIZE);
|
String name = r.readString(TransportUpdate.MAX_SIZE);
|
||||||
Map<String, String> inner = new TreeMap<String, String>();
|
Map<String, String> properties = new TreeMap<String, String>();
|
||||||
r.readMapStart();
|
r.readMapStart();
|
||||||
while(!r.hasMapEnd()) {
|
while(!r.hasMapEnd()) {
|
||||||
String key = r.readString(Transports.MAX_SIZE);
|
String key = r.readString(TransportUpdate.MAX_SIZE);
|
||||||
String value = r.readString(Transports.MAX_SIZE);
|
String value = r.readString(TransportUpdate.MAX_SIZE);
|
||||||
inner.put(key, value);
|
properties.put(key, value);
|
||||||
}
|
}
|
||||||
r.readMapEnd();
|
r.readMapEnd();
|
||||||
outer.put(name, inner);
|
transports.put(name, properties);
|
||||||
}
|
}
|
||||||
r.readMapEnd();
|
r.readMapEnd();
|
||||||
long timestamp = r.readInt64();
|
long timestamp = r.readInt64();
|
||||||
r.removeConsumer(counting);
|
r.removeConsumer(counting);
|
||||||
// Build and return the transports update
|
// Build and return the transport update
|
||||||
return transportFactory.createTransports(outer, timestamp);
|
return transportFactory.createTransports(transports, timestamp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ package net.sf.briar.protocol;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import net.sf.briar.api.protocol.Transports;
|
import net.sf.briar.api.protocol.TransportUpdate;
|
||||||
|
|
||||||
class TransportsImpl implements Transports {
|
class TransportsImpl implements TransportUpdate {
|
||||||
|
|
||||||
private final Map<String, Map<String, String>> transports;
|
private final Map<String, Map<String, String>> transports;
|
||||||
private final long timestamp;
|
private final long timestamp;
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ import net.sf.briar.api.protocol.GroupId;
|
|||||||
import net.sf.briar.api.protocol.Message;
|
import net.sf.briar.api.protocol.Message;
|
||||||
import net.sf.briar.api.protocol.MessageId;
|
import net.sf.briar.api.protocol.MessageId;
|
||||||
import net.sf.briar.api.protocol.Offer;
|
import net.sf.briar.api.protocol.Offer;
|
||||||
import net.sf.briar.api.protocol.Subscriptions;
|
import net.sf.briar.api.protocol.SubscriptionUpdate;
|
||||||
import net.sf.briar.api.protocol.Transports;
|
import net.sf.briar.api.protocol.TransportUpdate;
|
||||||
import net.sf.briar.api.protocol.writers.AckWriter;
|
import net.sf.briar.api.protocol.writers.AckWriter;
|
||||||
import net.sf.briar.api.protocol.writers.BatchWriter;
|
import net.sf.briar.api.protocol.writers.BatchWriter;
|
||||||
import net.sf.briar.api.protocol.writers.OfferWriter;
|
import net.sf.briar.api.protocol.writers.OfferWriter;
|
||||||
@@ -456,9 +456,9 @@ public abstract class DatabaseComponentTest extends TestCase {
|
|||||||
final Batch batch = context.mock(Batch.class);
|
final Batch batch = context.mock(Batch.class);
|
||||||
final Offer offer = context.mock(Offer.class);
|
final Offer offer = context.mock(Offer.class);
|
||||||
final RequestWriter requestWriter = context.mock(RequestWriter.class);
|
final RequestWriter requestWriter = context.mock(RequestWriter.class);
|
||||||
final Subscriptions subscriptionsUpdate =
|
final SubscriptionUpdate subscriptionsUpdate =
|
||||||
context.mock(Subscriptions.class);
|
context.mock(SubscriptionUpdate.class);
|
||||||
final Transports transportsUpdate = context.mock(Transports.class);
|
final TransportUpdate transportsUpdate = context.mock(TransportUpdate.class);
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
// Check whether the contact is still in the DB - which it's not
|
// Check whether the contact is still in the DB - which it's not
|
||||||
exactly(12).of(database).startTransaction();
|
exactly(12).of(database).startTransaction();
|
||||||
@@ -491,12 +491,12 @@ public abstract class DatabaseComponentTest extends TestCase {
|
|||||||
} catch(NoSuchContactException expected) {}
|
} catch(NoSuchContactException expected) {}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
db.generateSubscriptions(contactId, subscriptionWriter);
|
db.generateSubscriptionUpdate(contactId, subscriptionWriter);
|
||||||
fail();
|
fail();
|
||||||
} catch(NoSuchContactException expected) {}
|
} catch(NoSuchContactException expected) {}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
db.generateTransports(contactId, transportWriter);
|
db.generateTransportUpdate(contactId, transportWriter);
|
||||||
fail();
|
fail();
|
||||||
} catch(NoSuchContactException expected) {}
|
} catch(NoSuchContactException expected) {}
|
||||||
|
|
||||||
@@ -521,12 +521,12 @@ public abstract class DatabaseComponentTest extends TestCase {
|
|||||||
} catch(NoSuchContactException expected) {}
|
} catch(NoSuchContactException expected) {}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
db.receiveSubscriptions(contactId, subscriptionsUpdate);
|
db.receiveSubscriptionUpdate(contactId, subscriptionsUpdate);
|
||||||
fail();
|
fail();
|
||||||
} catch(NoSuchContactException expected) {}
|
} catch(NoSuchContactException expected) {}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
db.receiveTransports(contactId, transportsUpdate);
|
db.receiveTransportUpdate(contactId, transportsUpdate);
|
||||||
fail();
|
fail();
|
||||||
} catch(NoSuchContactException expected) {}
|
} catch(NoSuchContactException expected) {}
|
||||||
|
|
||||||
@@ -696,7 +696,7 @@ public abstract class DatabaseComponentTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGenerateSubscriptions() throws Exception {
|
public void testGenerateSubscriptionUpdate() throws Exception {
|
||||||
final MessageId messageId1 = new MessageId(TestUtils.getRandomId());
|
final MessageId messageId1 = new MessageId(TestUtils.getRandomId());
|
||||||
final Collection<MessageId> sendable = new ArrayList<MessageId>();
|
final Collection<MessageId> sendable = new ArrayList<MessageId>();
|
||||||
sendable.add(messageId);
|
sendable.add(messageId);
|
||||||
@@ -722,13 +722,13 @@ public abstract class DatabaseComponentTest extends TestCase {
|
|||||||
}});
|
}});
|
||||||
DatabaseComponent db = createDatabaseComponent(database, cleaner);
|
DatabaseComponent db = createDatabaseComponent(database, cleaner);
|
||||||
|
|
||||||
db.generateSubscriptions(contactId, subscriptionWriter);
|
db.generateSubscriptionUpdate(contactId, subscriptionWriter);
|
||||||
|
|
||||||
context.assertIsSatisfied();
|
context.assertIsSatisfied();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGenerateTransports() throws Exception {
|
public void testGenerateTransportUpdate() throws Exception {
|
||||||
final MessageId messageId1 = new MessageId(TestUtils.getRandomId());
|
final MessageId messageId1 = new MessageId(TestUtils.getRandomId());
|
||||||
final Collection<MessageId> sendable = new ArrayList<MessageId>();
|
final Collection<MessageId> sendable = new ArrayList<MessageId>();
|
||||||
sendable.add(messageId);
|
sendable.add(messageId);
|
||||||
@@ -753,7 +753,7 @@ public abstract class DatabaseComponentTest extends TestCase {
|
|||||||
}});
|
}});
|
||||||
DatabaseComponent db = createDatabaseComponent(database, cleaner);
|
DatabaseComponent db = createDatabaseComponent(database, cleaner);
|
||||||
|
|
||||||
db.generateTransports(contactId, transportWriter);
|
db.generateTransportUpdate(contactId, transportWriter);
|
||||||
|
|
||||||
context.assertIsSatisfied();
|
context.assertIsSatisfied();
|
||||||
}
|
}
|
||||||
@@ -982,14 +982,14 @@ public abstract class DatabaseComponentTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReceiveSubscriptions() throws Exception {
|
public void testReceiveSubscriptionUpdate() throws Exception {
|
||||||
final long timestamp = 1234L;
|
final long timestamp = 1234L;
|
||||||
Mockery context = new Mockery();
|
Mockery context = new Mockery();
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
final Database<Object> database = context.mock(Database.class);
|
final Database<Object> database = context.mock(Database.class);
|
||||||
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
|
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
|
||||||
final Subscriptions subscriptionsUpdate =
|
final SubscriptionUpdate subscriptionUpdate =
|
||||||
context.mock(Subscriptions.class);
|
context.mock(SubscriptionUpdate.class);
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
allowing(database).startTransaction();
|
allowing(database).startTransaction();
|
||||||
will(returnValue(txn));
|
will(returnValue(txn));
|
||||||
@@ -997,28 +997,29 @@ public abstract class DatabaseComponentTest extends TestCase {
|
|||||||
allowing(database).containsContact(txn, contactId);
|
allowing(database).containsContact(txn, contactId);
|
||||||
will(returnValue(true));
|
will(returnValue(true));
|
||||||
// Get the contents of the update
|
// Get the contents of the update
|
||||||
oneOf(subscriptionsUpdate).getSubscriptions();
|
oneOf(subscriptionUpdate).getSubscriptions();
|
||||||
will(returnValue(Collections.singletonList(group)));
|
will(returnValue(Collections.singletonList(group)));
|
||||||
oneOf(subscriptionsUpdate).getTimestamp();
|
oneOf(subscriptionUpdate).getTimestamp();
|
||||||
will(returnValue(timestamp));
|
will(returnValue(timestamp));
|
||||||
oneOf(database).setSubscriptions(txn, contactId,
|
oneOf(database).setSubscriptions(txn, contactId,
|
||||||
Collections.singletonList(group), timestamp);
|
Collections.singletonList(group), timestamp);
|
||||||
}});
|
}});
|
||||||
DatabaseComponent db = createDatabaseComponent(database, cleaner);
|
DatabaseComponent db = createDatabaseComponent(database, cleaner);
|
||||||
|
|
||||||
db.receiveSubscriptions(contactId, subscriptionsUpdate);
|
db.receiveSubscriptionUpdate(contactId, subscriptionUpdate);
|
||||||
|
|
||||||
context.assertIsSatisfied();
|
context.assertIsSatisfied();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReceiveTransports() throws Exception {
|
public void testReceiveTransportUpdate() throws Exception {
|
||||||
final long timestamp = 1234L;
|
final long timestamp = 1234L;
|
||||||
Mockery context = new Mockery();
|
Mockery context = new Mockery();
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
final Database<Object> database = context.mock(Database.class);
|
final Database<Object> database = context.mock(Database.class);
|
||||||
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
|
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
|
||||||
final Transports transportsUpdate = context.mock(Transports.class);
|
final TransportUpdate transportUpdate =
|
||||||
|
context.mock(TransportUpdate.class);
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
allowing(database).startTransaction();
|
allowing(database).startTransaction();
|
||||||
will(returnValue(txn));
|
will(returnValue(txn));
|
||||||
@@ -1026,16 +1027,16 @@ public abstract class DatabaseComponentTest extends TestCase {
|
|||||||
allowing(database).containsContact(txn, contactId);
|
allowing(database).containsContact(txn, contactId);
|
||||||
will(returnValue(true));
|
will(returnValue(true));
|
||||||
// Get the contents of the update
|
// Get the contents of the update
|
||||||
oneOf(transportsUpdate).getTransports();
|
oneOf(transportUpdate).getTransports();
|
||||||
will(returnValue(transports));
|
will(returnValue(transports));
|
||||||
oneOf(transportsUpdate).getTimestamp();
|
oneOf(transportUpdate).getTimestamp();
|
||||||
will(returnValue(timestamp));
|
will(returnValue(timestamp));
|
||||||
oneOf(database).setTransports(txn, contactId, transports,
|
oneOf(database).setTransports(txn, contactId, transports,
|
||||||
timestamp);
|
timestamp);
|
||||||
}});
|
}});
|
||||||
DatabaseComponent db = createDatabaseComponent(database, cleaner);
|
DatabaseComponent db = createDatabaseComponent(database, cleaner);
|
||||||
|
|
||||||
db.receiveTransports(contactId, transportsUpdate);
|
db.receiveTransportUpdate(contactId, transportUpdate);
|
||||||
|
|
||||||
context.assertIsSatisfied();
|
context.assertIsSatisfied();
|
||||||
}
|
}
|
||||||
@@ -1103,7 +1104,12 @@ public abstract class DatabaseComponentTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTransportsChangedCallsListeners() throws Exception {
|
public void testTransportPropertiesChangedCallsListeners()
|
||||||
|
throws Exception {
|
||||||
|
final Map<String, String> properties =
|
||||||
|
Collections.singletonMap("bar", "baz");
|
||||||
|
final Map<String, String> properties1 =
|
||||||
|
Collections.singletonMap("baz", "bam");
|
||||||
Mockery context = new Mockery();
|
Mockery context = new Mockery();
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
final Database<Object> database = context.mock(Database.class);
|
final Database<Object> database = context.mock(Database.class);
|
||||||
@@ -1113,9 +1119,8 @@ public abstract class DatabaseComponentTest extends TestCase {
|
|||||||
oneOf(database).startTransaction();
|
oneOf(database).startTransaction();
|
||||||
will(returnValue(txn));
|
will(returnValue(txn));
|
||||||
oneOf(database).getTransports(txn);
|
oneOf(database).getTransports(txn);
|
||||||
will(returnValue(transports));
|
will(returnValue(Collections.singletonMap("foo", properties)));
|
||||||
oneOf(database).setTransports(txn, "bar",
|
oneOf(database).setTransportProperties(txn, "foo", properties1);
|
||||||
Collections.singletonMap("baz", "bam"));
|
|
||||||
oneOf(database).commitTransaction(txn);
|
oneOf(database).commitTransaction(txn);
|
||||||
oneOf(listener).eventOccurred(
|
oneOf(listener).eventOccurred(
|
||||||
DatabaseListener.Event.TRANSPORTS_UPDATED);
|
DatabaseListener.Event.TRANSPORTS_UPDATED);
|
||||||
@@ -1123,13 +1128,16 @@ public abstract class DatabaseComponentTest extends TestCase {
|
|||||||
DatabaseComponent db = createDatabaseComponent(database, cleaner);
|
DatabaseComponent db = createDatabaseComponent(database, cleaner);
|
||||||
|
|
||||||
db.addListener(listener);
|
db.addListener(listener);
|
||||||
db.setTransports("bar", Collections.singletonMap("baz", "bam"));
|
db.setTransportProperties("foo", properties1);
|
||||||
|
|
||||||
context.assertIsSatisfied();
|
context.assertIsSatisfied();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTransportsUnchangedDoesNotCallListeners() throws Exception {
|
public void testTransportPropertiesUnchangedDoesNotCallListeners()
|
||||||
|
throws Exception {
|
||||||
|
final Map<String, String> properties =
|
||||||
|
Collections.singletonMap("bar", "baz");
|
||||||
Mockery context = new Mockery();
|
Mockery context = new Mockery();
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
final Database<Object> database = context.mock(Database.class);
|
final Database<Object> database = context.mock(Database.class);
|
||||||
@@ -1139,13 +1147,67 @@ public abstract class DatabaseComponentTest extends TestCase {
|
|||||||
oneOf(database).startTransaction();
|
oneOf(database).startTransaction();
|
||||||
will(returnValue(txn));
|
will(returnValue(txn));
|
||||||
oneOf(database).getTransports(txn);
|
oneOf(database).getTransports(txn);
|
||||||
will(returnValue(transports));
|
will(returnValue(Collections.singletonMap("foo", properties)));
|
||||||
oneOf(database).commitTransaction(txn);
|
oneOf(database).commitTransaction(txn);
|
||||||
}});
|
}});
|
||||||
DatabaseComponent db = createDatabaseComponent(database, cleaner);
|
DatabaseComponent db = createDatabaseComponent(database, cleaner);
|
||||||
|
|
||||||
db.addListener(listener);
|
db.addListener(listener);
|
||||||
db.setTransports("foo", transports.get("foo"));
|
db.setTransportProperties("foo", properties);
|
||||||
|
|
||||||
|
context.assertIsSatisfied();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTransportConfigChangedCallsListeners() throws Exception {
|
||||||
|
final Map<String, String> config =
|
||||||
|
Collections.singletonMap("bar", "baz");
|
||||||
|
final Map<String, String> config1 =
|
||||||
|
Collections.singletonMap("baz", "bam");
|
||||||
|
Mockery context = new Mockery();
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
final Database<Object> database = context.mock(Database.class);
|
||||||
|
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
|
||||||
|
final DatabaseListener listener = context.mock(DatabaseListener.class);
|
||||||
|
context.checking(new Expectations() {{
|
||||||
|
oneOf(database).startTransaction();
|
||||||
|
will(returnValue(txn));
|
||||||
|
oneOf(database).getTransportConfig(txn, "foo");
|
||||||
|
will(returnValue(config));
|
||||||
|
oneOf(database).setTransportConfig(txn, "foo", config1);
|
||||||
|
oneOf(database).commitTransaction(txn);
|
||||||
|
oneOf(listener).eventOccurred(
|
||||||
|
DatabaseListener.Event.TRANSPORTS_UPDATED);
|
||||||
|
}});
|
||||||
|
DatabaseComponent db = createDatabaseComponent(database, cleaner);
|
||||||
|
|
||||||
|
db.addListener(listener);
|
||||||
|
db.setTransportConfig("foo", config1);
|
||||||
|
|
||||||
|
context.assertIsSatisfied();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTransportConfigUnchangedDoesNotCallListeners()
|
||||||
|
throws Exception {
|
||||||
|
final Map<String, String> config =
|
||||||
|
Collections.singletonMap("bar", "baz");
|
||||||
|
Mockery context = new Mockery();
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
final Database<Object> database = context.mock(Database.class);
|
||||||
|
final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class);
|
||||||
|
final DatabaseListener listener = context.mock(DatabaseListener.class);
|
||||||
|
context.checking(new Expectations() {{
|
||||||
|
oneOf(database).startTransaction();
|
||||||
|
will(returnValue(txn));
|
||||||
|
oneOf(database).getTransportConfig(txn, "foo");
|
||||||
|
will(returnValue(config));
|
||||||
|
oneOf(database).commitTransaction(txn);
|
||||||
|
}});
|
||||||
|
DatabaseComponent db = createDatabaseComponent(database, cleaner);
|
||||||
|
|
||||||
|
db.addListener(listener);
|
||||||
|
db.setTransportConfig("foo", config);
|
||||||
|
|
||||||
context.assertIsSatisfied();
|
context.assertIsSatisfied();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -780,7 +780,7 @@ public class H2DatabaseTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateTransports() throws DbException {
|
public void testUpdateTransportPropertiess() throws DbException {
|
||||||
Database<Connection> db = open(false);
|
Database<Connection> db = open(false);
|
||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
@@ -799,13 +799,14 @@ public class H2DatabaseTest extends TestCase {
|
|||||||
Collections.<String, Map<String, String>>emptyMap(), 2);
|
Collections.<String, Map<String, String>>emptyMap(), 2);
|
||||||
assertEquals(Collections.emptyMap(), db.getTransports(txn, contactId));
|
assertEquals(Collections.emptyMap(), db.getTransports(txn, contactId));
|
||||||
// Set the local transport properties
|
// Set the local transport properties
|
||||||
for(String s : transports.keySet()) {
|
for(String name : transports.keySet()) {
|
||||||
db.setTransports(txn, s, transports.get(s));
|
db.setTransportProperties(txn, name, transports.get(name));
|
||||||
}
|
}
|
||||||
assertEquals(transports, db.getTransports(txn));
|
assertEquals(transports, db.getTransports(txn));
|
||||||
// Remove the local transport properties
|
// Remove the local transport properties
|
||||||
for(String s : transports.keySet()) {
|
for(String name : transports.keySet()) {
|
||||||
db.setTransports(txn, s, Collections.<String, String>emptyMap());
|
db.setTransportProperties(txn, name,
|
||||||
|
Collections.<String, String>emptyMap());
|
||||||
}
|
}
|
||||||
assertEquals(Collections.emptyMap(), db.getTransports(txn));
|
assertEquals(Collections.emptyMap(), db.getTransports(txn));
|
||||||
|
|
||||||
@@ -813,6 +814,29 @@ public class H2DatabaseTest extends TestCase {
|
|||||||
db.close();
|
db.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateTransportConfig() throws DbException {
|
||||||
|
Map<String, String> config = Collections.singletonMap("bar", "baz");
|
||||||
|
Map<String, String> config1 = Collections.singletonMap("baz", "bam");
|
||||||
|
Database<Connection> db = open(false);
|
||||||
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
|
// Set the transport config
|
||||||
|
db.setTransportConfig(txn, "foo", config);
|
||||||
|
assertEquals(config, db.getTransportConfig(txn, "foo"));
|
||||||
|
// Update the transport config
|
||||||
|
db.setTransportConfig(txn, "foo", config1);
|
||||||
|
assertEquals(config1, db.getTransportConfig(txn, "foo"));
|
||||||
|
// Remove the transport config
|
||||||
|
db.setTransportConfig(txn, "foo",
|
||||||
|
Collections.<String, String>emptyMap());
|
||||||
|
assertEquals(Collections.emptyMap(), db.getTransportConfig(txn, "foo"));
|
||||||
|
|
||||||
|
db.commitTransaction(txn);
|
||||||
|
db.close();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTransportsNotUpdatedIfTimestampIsOld() throws DbException {
|
public void testTransportsNotUpdatedIfTimestampIsOld() throws DbException {
|
||||||
Database<Connection> db = open(false);
|
Database<Connection> db = open(false);
|
||||||
|
|||||||
@@ -27,9 +27,9 @@ import net.sf.briar.api.protocol.MessageEncoder;
|
|||||||
import net.sf.briar.api.protocol.MessageId;
|
import net.sf.briar.api.protocol.MessageId;
|
||||||
import net.sf.briar.api.protocol.Offer;
|
import net.sf.briar.api.protocol.Offer;
|
||||||
import net.sf.briar.api.protocol.Request;
|
import net.sf.briar.api.protocol.Request;
|
||||||
import net.sf.briar.api.protocol.Subscriptions;
|
import net.sf.briar.api.protocol.SubscriptionUpdate;
|
||||||
import net.sf.briar.api.protocol.Tags;
|
import net.sf.briar.api.protocol.Tags;
|
||||||
import net.sf.briar.api.protocol.Transports;
|
import net.sf.briar.api.protocol.TransportUpdate;
|
||||||
import net.sf.briar.api.protocol.UniqueId;
|
import net.sf.briar.api.protocol.UniqueId;
|
||||||
import net.sf.briar.api.protocol.writers.AckWriter;
|
import net.sf.briar.api.protocol.writers.AckWriter;
|
||||||
import net.sf.briar.api.protocol.writers.BatchWriter;
|
import net.sf.briar.api.protocol.writers.BatchWriter;
|
||||||
@@ -217,10 +217,10 @@ public class FileReadWriteTest extends TestCase {
|
|||||||
// If there are any padding bits, they should all be zero
|
// If there are any padding bits, they should all be zero
|
||||||
assertEquals(2, requested.cardinality());
|
assertEquals(2, requested.cardinality());
|
||||||
|
|
||||||
// Read the subscriptions update
|
// Read the subscription update
|
||||||
assertTrue(reader.hasUserDefined(Tags.SUBSCRIPTIONS));
|
assertTrue(reader.hasUserDefined(Tags.SUBSCRIPTIONS));
|
||||||
Subscriptions s = reader.readUserDefined(Tags.SUBSCRIPTIONS,
|
SubscriptionUpdate s = reader.readUserDefined(Tags.SUBSCRIPTIONS,
|
||||||
Subscriptions.class);
|
SubscriptionUpdate.class);
|
||||||
Collection<Group> subs = s.getSubscriptions();
|
Collection<Group> subs = s.getSubscriptions();
|
||||||
assertEquals(2, subs.size());
|
assertEquals(2, subs.size());
|
||||||
Iterator<Group> it2 = subs.iterator();
|
Iterator<Group> it2 = subs.iterator();
|
||||||
@@ -229,10 +229,10 @@ public class FileReadWriteTest extends TestCase {
|
|||||||
assertTrue(s.getTimestamp() > start);
|
assertTrue(s.getTimestamp() > start);
|
||||||
assertTrue(s.getTimestamp() <= System.currentTimeMillis());
|
assertTrue(s.getTimestamp() <= System.currentTimeMillis());
|
||||||
|
|
||||||
// Read the transports update
|
// Read the transport update
|
||||||
assertTrue(reader.hasUserDefined(Tags.TRANSPORTS));
|
assertTrue(reader.hasUserDefined(Tags.TRANSPORTS));
|
||||||
Transports t = reader.readUserDefined(Tags.TRANSPORTS,
|
TransportUpdate t = reader.readUserDefined(Tags.TRANSPORTS,
|
||||||
Transports.class);
|
TransportUpdate.class);
|
||||||
assertEquals(transports, t.getTransports());
|
assertEquals(transports, t.getTransports());
|
||||||
assertTrue(t.getTimestamp() > start);
|
assertTrue(t.getTimestamp() > start);
|
||||||
assertTrue(t.getTimestamp() <= System.currentTimeMillis());
|
assertTrue(t.getTimestamp() <= System.currentTimeMillis());
|
||||||
|
|||||||
Reference in New Issue
Block a user