Updated group-related events and exceptions.

This commit is contained in:
akwizgran
2016-01-27 17:29:17 +00:00
parent 9d537dce00
commit 3837efca6b
23 changed files with 159 additions and 226 deletions

View File

@@ -84,12 +84,11 @@ interface Database<T> {
throws DbException;
/**
* Subscribes to a group, or returns false if the user already has the
* maximum number of subscriptions.
* Stores a group.
* <p>
* Locking: write.
*/
boolean addGroup(T txn, Group g) throws DbException;
void addGroup(T txn, Group g) throws DbException;
/**
* Stores a local pseudonym.
@@ -164,7 +163,7 @@ interface Database<T> {
boolean containsContact(T txn, ContactId c) throws DbException;
/**
* Returns true if the user subscribes to the given group.
* Returns true if the database contains the given group.
* <p>
* Locking: read.
*/
@@ -192,7 +191,7 @@ interface Database<T> {
boolean containsTransport(T txn, TransportId t) throws DbException;
/**
* Returns true if the user subscribes to the given group and the group is
* Returns true if the database contains the given group and the group is
* visible to the given contact.
* <p>
* Locking: read.
@@ -259,7 +258,7 @@ interface Database<T> {
long getFreeSpace() throws DbException;
/**
* Returns the group with the given ID, if the user subscribes to it.
* Returns the group with the given ID.
* <p>
* Locking: read.
*/
@@ -273,8 +272,7 @@ interface Database<T> {
Metadata getGroupMetadata(T txn, GroupId g) throws DbException;
/**
* Returns all groups belonging to the given client to which the user
* subscribes.
* Returns all groups belonging to the given client.
* <p>
* Locking: read.
*/
@@ -500,16 +498,14 @@ interface Database<T> {
void removeContact(T txn, ContactId c) throws DbException;
/**
* Unsubscribes from a group. Any messages belonging to the group are
* deleted from the database.
* Removes a group (and all associated state) from the database.
* <p>
* Locking: write.
*/
void removeGroup(T txn, GroupId g) throws DbException;
/**
* Removes a local pseudonym (and all associated contacts) from the
* database.
* Removes a local pseudonym (and all associated state) from the database.
* <p>
* Locking: write.
*/

View File

@@ -11,13 +11,15 @@ import org.briarproject.api.db.LocalAuthorExistsException;
import org.briarproject.api.db.MessageExistsException;
import org.briarproject.api.db.Metadata;
import org.briarproject.api.db.NoSuchContactException;
import org.briarproject.api.db.NoSuchGroupException;
import org.briarproject.api.db.NoSuchLocalAuthorException;
import org.briarproject.api.db.NoSuchMessageException;
import org.briarproject.api.db.NoSuchSubscriptionException;
import org.briarproject.api.db.NoSuchTransportException;
import org.briarproject.api.db.StorageStatus;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.event.LocalSubscriptionsUpdatedEvent;
import org.briarproject.api.event.GroupAddedEvent;
import org.briarproject.api.event.GroupRemovedEvent;
import org.briarproject.api.event.GroupVisibilityUpdatedEvent;
import org.briarproject.api.event.MessageAddedEvent;
import org.briarproject.api.event.MessageRequestedEvent;
import org.briarproject.api.event.MessageSharedEvent;
@@ -27,8 +29,6 @@ import org.briarproject.api.event.MessageValidatedEvent;
import org.briarproject.api.event.MessagesAckedEvent;
import org.briarproject.api.event.MessagesSentEvent;
import org.briarproject.api.event.SettingsUpdatedEvent;
import org.briarproject.api.event.SubscriptionAddedEvent;
import org.briarproject.api.event.SubscriptionRemovedEvent;
import org.briarproject.api.event.TransportAddedEvent;
import org.briarproject.api.event.TransportRemovedEvent;
import org.briarproject.api.identity.Author;
@@ -161,14 +161,16 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
}
}
public boolean addGroup(Group g) throws DbException {
public void addGroup(Group g) throws DbException {
boolean added = false;
lock.writeLock().lock();
try {
T txn = db.startTransaction();
try {
if (!db.containsGroup(txn, g.getId()))
added = db.addGroup(txn, g);
if (!db.containsGroup(txn, g.getId())) {
added = true;
db.addGroup(txn, g);
}
db.commitTransaction(txn);
} catch (DbException e) {
db.abortTransaction(txn);
@@ -177,8 +179,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
} finally {
lock.writeLock().unlock();
}
if (added) eventBus.broadcast(new SubscriptionAddedEvent(g));
return added;
if (added) eventBus.broadcast(new GroupAddedEvent(g));
}
public void addLocalAuthor(LocalAuthor a) throws DbException {
@@ -208,7 +209,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
if (db.containsMessage(txn, m.getId()))
throw new MessageExistsException();
if (!db.containsGroup(txn, m.getGroupId()))
throw new NoSuchSubscriptionException();
throw new NoSuchGroupException();
addMessage(txn, m, VALID, shared, null);
db.mergeMessageMetadata(txn, m.getId(), meta);
db.commitTransaction(txn);
@@ -493,7 +494,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
T txn = db.startTransaction();
try {
if (!db.containsGroup(txn, g))
throw new NoSuchSubscriptionException();
throw new NoSuchGroupException();
Group group = db.getGroup(txn, g);
db.commitTransaction(txn);
return group;
@@ -512,7 +513,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
T txn = db.startTransaction();
try {
if (!db.containsGroup(txn, g))
throw new NoSuchSubscriptionException();
throw new NoSuchGroupException();
Metadata metadata = db.getGroupMetadata(txn, g);
db.commitTransaction(txn);
return metadata;
@@ -622,7 +623,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
T txn = db.startTransaction();
try {
if (!db.containsGroup(txn, g))
throw new NoSuchSubscriptionException();
throw new NoSuchGroupException();
Map<MessageId, Metadata> metadata =
db.getMessageMetadata(txn, g);
db.commitTransaction(txn);
@@ -664,7 +665,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
if (!db.containsContact(txn, c))
throw new NoSuchContactException();
if (!db.containsGroup(txn, g))
throw new NoSuchSubscriptionException();
throw new NoSuchGroupException();
Collection<MessageStatus> statuses =
db.getMessageStatus(txn, c, g);
db.commitTransaction(txn);
@@ -763,7 +764,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
T txn = db.startTransaction();
try {
if (!db.containsGroup(txn, g))
throw new NoSuchSubscriptionException();
throw new NoSuchGroupException();
Collection<ContactId> visible = db.getVisibility(txn, g);
db.commitTransaction(txn);
return visible;
@@ -804,7 +805,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
T txn = db.startTransaction();
try {
if (!db.containsGroup(txn, g))
throw new NoSuchSubscriptionException();
throw new NoSuchGroupException();
db.mergeGroupMetadata(txn, g, meta);
db.commitTransaction(txn);
} catch (DbException e) {
@@ -998,7 +999,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
try {
GroupId id = g.getId();
if (!db.containsGroup(txn, id))
throw new NoSuchSubscriptionException();
throw new NoSuchGroupException();
affected = db.getVisibility(txn, id);
db.removeGroup(txn, id);
db.commitTransaction(txn);
@@ -1009,8 +1010,8 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
} finally {
lock.writeLock().unlock();
}
eventBus.broadcast(new SubscriptionRemovedEvent(g));
eventBus.broadcast(new LocalSubscriptionsUpdatedEvent(affected));
eventBus.broadcast(new GroupRemovedEvent(g));
eventBus.broadcast(new GroupVisibilityUpdatedEvent(affected));
}
public void removeLocalAuthor(AuthorId a) throws DbException {
@@ -1157,7 +1158,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
T txn = db.startTransaction();
try {
if (!db.containsGroup(txn, g))
throw new NoSuchSubscriptionException();
throw new NoSuchGroupException();
// Use HashSets for O(1) lookups, O(n) overall running time
HashSet<ContactId> now = new HashSet<ContactId>(visible);
Collection<ContactId> before = db.getVisibility(txn, g);
@@ -1185,7 +1186,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
lock.writeLock().unlock();
}
if (!affected.isEmpty())
eventBus.broadcast(new LocalSubscriptionsUpdatedEvent(affected));
eventBus.broadcast(new GroupVisibilityUpdatedEvent(affected));
}
public void setVisibleToAll(GroupId g, boolean all) throws DbException {
@@ -1195,7 +1196,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
T txn = db.startTransaction();
try {
if (!db.containsGroup(txn, g))
throw new NoSuchSubscriptionException();
throw new NoSuchGroupException();
// Make the group visible or invisible to future contacts
db.setVisibleToAll(txn, g, all);
if (all) {
@@ -1218,7 +1219,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
lock.writeLock().unlock();
}
if (!affected.isEmpty())
eventBus.broadcast(new LocalSubscriptionsUpdatedEvent(affected));
eventBus.broadcast(new GroupVisibilityUpdatedEvent(affected));
}
public void updateTransportKeys(Map<ContactId, TransportKeys> keys)

View File

@@ -50,7 +50,6 @@ import java.util.logging.Logger;
import static java.util.logging.Level.WARNING;
import static org.briarproject.api.db.Metadata.REMOVE;
import static org.briarproject.api.db.StorageStatus.ADDING;
import static org.briarproject.api.sync.SyncConstants.MAX_SUBSCRIPTIONS;
import static org.briarproject.api.sync.ValidationManager.Validity.INVALID;
import static org.briarproject.api.sync.ValidationManager.Validity.UNKNOWN;
import static org.briarproject.api.sync.ValidationManager.Validity.VALID;
@@ -544,21 +543,10 @@ abstract class JdbcDatabase implements Database<Connection> {
}
}
public boolean addGroup(Connection txn, Group g) throws DbException {
public void addGroup(Connection txn, Group g) throws DbException {
PreparedStatement ps = null;
ResultSet rs = null;
try {
String sql = "SELECT COUNT (groupId) FROM groups";
ps = txn.prepareStatement(sql);
rs = ps.executeQuery();
if (!rs.next()) throw new DbStateException();
int count = rs.getInt(1);
if (rs.next()) throw new DbStateException();
rs.close();
ps.close();
if (count > MAX_SUBSCRIPTIONS) throw new DbStateException();
if (count == MAX_SUBSCRIPTIONS) return false;
sql = "INSERT INTO groups"
String sql = "INSERT INTO groups"
+ " (groupId, clientId, descriptor, visibleToAll)"
+ " VALUES (?, ?, ?, FALSE)";
ps = txn.prepareStatement(sql);
@@ -568,9 +556,7 @@ abstract class JdbcDatabase implements Database<Connection> {
int affected = ps.executeUpdate();
if (affected != 1) throw new DbStateException();
ps.close();
return true;
} catch (SQLException e) {
tryToClose(rs);
tryToClose(ps);
throw new DbException(e);
}

View File

@@ -113,8 +113,8 @@ class ForumManagerImpl implements ForumManager {
}
@Override
public boolean addForum(Forum f) throws DbException {
return db.addGroup(f.getGroup());
public void addForum(Forum f) throws DbException {
db.addGroup(f.getGroup());
}
@Override

View File

@@ -73,7 +73,7 @@ class MessagingManagerImpl implements MessagingManager, AddContactHook,
try {
// Create the conversation group
Group g = getConversationGroup(db.getContact(c));
// Subscribe to the group and share it with the contact
// Store the group and share it with the contact
db.addGroup(g);
db.setVisibility(g.getId(), Collections.singletonList(c));
// Attach the contact ID to the group

View File

@@ -19,7 +19,7 @@ import org.briarproject.api.data.MetadataParser;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
import org.briarproject.api.db.Metadata;
import org.briarproject.api.db.NoSuchSubscriptionException;
import org.briarproject.api.db.NoSuchGroupException;
import org.briarproject.api.properties.TransportProperties;
import org.briarproject.api.properties.TransportPropertyManager;
import org.briarproject.api.sync.ClientId;
@@ -96,7 +96,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
try {
// Create a group to share with the contact
Group g = getContactGroup(db.getContact(c));
// Subscribe to the group and share it with the contact
// Store the group and share it with the contact
db.addGroup(g);
db.setVisibility(g.getId(), Collections.singletonList(c));
// Copy the latest local properties into the group
@@ -197,7 +197,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
local.put(e.getKey(), decodeProperties(raw));
}
return Collections.unmodifiableMap(local);
} catch (NoSuchSubscriptionException e) {
} catch (NoSuchGroupException e) {
// Local group doesn't exist - there are no local properties
return Collections.emptyMap();
} catch (IOException e) {
@@ -254,7 +254,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
if (latest == null) return null;
// Retrieve and decode the latest local properties
return decodeProperties(db.getRawMessage(latest.messageId));
} catch (NoSuchSubscriptionException e) {
} catch (NoSuchGroupException e) {
// Local group doesn't exist - there are no local properties
return null;
} catch (IOException e) {

View File

@@ -8,13 +8,12 @@ import org.briarproject.api.event.ContactRemovedEvent;
import org.briarproject.api.event.Event;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.event.EventListener;
import org.briarproject.api.event.LocalSubscriptionsUpdatedEvent;
import org.briarproject.api.event.GroupVisibilityUpdatedEvent;
import org.briarproject.api.event.MessageRequestedEvent;
import org.briarproject.api.event.MessageSharedEvent;
import org.briarproject.api.event.MessageToAckEvent;
import org.briarproject.api.event.MessageToRequestEvent;
import org.briarproject.api.event.MessageValidatedEvent;
import org.briarproject.api.event.RemoteSubscriptionsUpdatedEvent;
import org.briarproject.api.event.ShutdownEvent;
import org.briarproject.api.event.TransportRemovedEvent;
import org.briarproject.api.sync.Ack;
@@ -155,10 +154,9 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
} else if (e instanceof MessageValidatedEvent) {
if (((MessageValidatedEvent) e).isValid())
dbExecutor.execute(new GenerateOffer());
} else if (e instanceof LocalSubscriptionsUpdatedEvent) {
LocalSubscriptionsUpdatedEvent l =
(LocalSubscriptionsUpdatedEvent) e;
if (l.getAffectedContacts().contains(contactId))
} else if (e instanceof GroupVisibilityUpdatedEvent) {
GroupVisibilityUpdatedEvent g = (GroupVisibilityUpdatedEvent) e;
if (g.getAffectedContacts().contains(contactId))
dbExecutor.execute(new GenerateOffer());
} else if (e instanceof MessageRequestedEvent) {
if (((MessageRequestedEvent) e).getContactId().equals(contactId))
@@ -169,11 +167,6 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
} else if (e instanceof MessageToRequestEvent) {
if (((MessageToRequestEvent) e).getContactId().equals(contactId))
dbExecutor.execute(new GenerateRequest());
} else if (e instanceof RemoteSubscriptionsUpdatedEvent) {
RemoteSubscriptionsUpdatedEvent r =
(RemoteSubscriptionsUpdatedEvent) e;
if (r.getContactId().equals(contactId))
dbExecutor.execute(new GenerateOffer());
} else if (e instanceof ShutdownEvent) {
interrupt();
} else if (e instanceof TransportRemovedEvent) {

View File

@@ -8,8 +8,8 @@ import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DatabaseExecutor;
import org.briarproject.api.db.DbException;
import org.briarproject.api.db.Metadata;
import org.briarproject.api.db.NoSuchGroupException;
import org.briarproject.api.db.NoSuchMessageException;
import org.briarproject.api.db.NoSuchSubscriptionException;
import org.briarproject.api.event.Event;
import org.briarproject.api.event.EventListener;
import org.briarproject.api.event.MessageAddedEvent;
@@ -158,7 +158,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
try {
ClientId c = db.getGroup(m.getGroupId()).getClientId();
validateMessage(m, c);
} catch (NoSuchSubscriptionException e) {
} catch (NoSuchGroupException e) {
LOG.info("Group removed before validation");
} catch (DbException e) {
if (LOG.isLoggable(WARNING))