Merge branch 'conversation-manager' into 'master'

Use ConversationManager for private message retrieval

See merge request briar/briar!912
This commit is contained in:
akwizgran
2018-09-20 13:01:53 +00:00
74 changed files with 983 additions and 1497 deletions

View File

@@ -1,6 +1,5 @@
package org.briarproject.briar.blog;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.sync.MessageId;
@@ -63,10 +62,7 @@ public class BlogManagerIntegrationTest
blog1 = blogFactory.createBlog(author1);
rssBlog = blogFactory.createFeedBlog(rssAuthor);
Transaction txn = db0.startTransaction(false);
blogManager0.addBlog(txn, rssBlog);
db0.commitTransaction(txn);
db0.endTransaction(txn);
withinTransaction(db0, txn -> blogManager0.addBlog(txn, rssBlog));
}
@Override

View File

@@ -9,8 +9,8 @@ import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.data.BdfEntry;
import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.event.EventListener;
import org.briarproject.bramble.api.identity.Author;
@@ -25,13 +25,13 @@ import org.briarproject.bramble.test.TestDatabaseModule;
import org.briarproject.briar.api.client.ProtocolStateException;
import org.briarproject.briar.api.client.SessionId;
import org.briarproject.briar.api.introduction.IntroductionManager;
import org.briarproject.briar.api.introduction.IntroductionMessage;
import org.briarproject.briar.api.introduction.IntroductionRequest;
import org.briarproject.briar.api.introduction.IntroductionResponse;
import org.briarproject.briar.api.introduction.event.IntroductionAbortedEvent;
import org.briarproject.briar.api.introduction.event.IntroductionRequestReceivedEvent;
import org.briarproject.briar.api.introduction.event.IntroductionResponseReceivedEvent;
import org.briarproject.briar.api.introduction.event.IntroductionSucceededEvent;
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
import org.briarproject.briar.test.BriarIntegrationTest;
import org.junit.Before;
import org.junit.Test;
@@ -159,7 +159,7 @@ public class IntroductionIntegrationTest
eventWaiter.await(TIMEOUT, 1);
assertTrue(listener0.response1Received);
assertEquals(introducee2.getAuthor().getName(),
listener0.getResponse().getName());
listener0.getResponse().getIntroducedAuthor().getName());
assertGroupCount(messageTracker0, g1.getId(), 2, 1);
// sync second ACCEPT message
@@ -167,7 +167,7 @@ public class IntroductionIntegrationTest
eventWaiter.await(TIMEOUT, 1);
assertTrue(listener0.response2Received);
assertEquals(introducee1.getAuthor().getName(),
listener0.getResponse().getName());
listener0.getResponse().getIntroducedAuthor().getName());
assertGroupCount(messageTracker0, g2.getId(), 2, 1);
// sync forwarded ACCEPT messages to introducees
@@ -265,7 +265,7 @@ public class IntroductionIntegrationTest
// assert that the name on the decline event is correct
assertEquals(introducee2.getAuthor().getName(),
listener0.getResponse().getName());
listener0.getResponse().getIntroducedAuthor().getName());
// sync second response
sync2To0(1, true);
@@ -282,7 +282,7 @@ public class IntroductionIntegrationTest
// assert that the name on the decline event is correct
eventWaiter.await(TIMEOUT, 1);
assertEquals(introducee1.getAuthor().getName(),
listener2.getResponse().getName());
listener2.getResponse().getIntroducedAuthor().getName());
// note how the introducer does not forward the second response,
// because after the first decline the protocol finished
@@ -297,22 +297,23 @@ public class IntroductionIntegrationTest
Group g1 = introductionManager0.getContactGroup(introducee1);
Group g2 = introductionManager0.getContactGroup(introducee2);
assertEquals(2,
introductionManager0.getIntroductionMessages(contactId1From0)
.size());
Collection<PrivateMessageHeader> messages =
withinTransactionReturns(db0, txn -> introductionManager0
.getMessageHeaders(txn, contactId1From0));
assertEquals(2, messages.size());
assertGroupCount(messageTracker0, g1.getId(), 2, 1);
assertEquals(2,
introductionManager0.getIntroductionMessages(contactId2From0)
.size());
messages = withinTransactionReturns(db0,
txn -> introductionManager0.getMessageHeaders(txn, contactId2From0));
assertEquals(2, messages.size());
assertGroupCount(messageTracker0, g2.getId(), 2, 1);
assertEquals(2,
introductionManager1.getIntroductionMessages(contactId0From1)
.size());
messages = withinTransactionReturns(db1,
txn -> introductionManager1.getMessageHeaders(txn, contactId0From1));
assertEquals(2, messages.size());
assertGroupCount(messageTracker1, g1.getId(), 2, 1);
// introducee2 should also have the decline response of introducee1
assertEquals(3,
introductionManager2.getIntroductionMessages(contactId0From2)
.size());
messages = withinTransactionReturns(db2,
txn -> introductionManager2.getMessageHeaders(txn, contactId0From2));
assertEquals(3, messages.size());
assertGroupCount(messageTracker2, g2.getId(), 3, 2);
assertFalse(listener0.aborted);
@@ -355,25 +356,29 @@ public class IntroductionIntegrationTest
// assert that the name on the decline event is correct
eventWaiter.await(TIMEOUT, 1);
assertEquals(contact2From0.getAuthor().getName(),
listener1.getResponse().getName());
listener1.getResponse().getIntroducedAuthor().getName());
assertFalse(contactManager1
.contactExists(author2.getId(), author1.getId()));
assertFalse(contactManager2
.contactExists(author1.getId(), author2.getId()));
assertEquals(2,
introductionManager0.getIntroductionMessages(contactId1From0)
.size());
assertEquals(2,
introductionManager0.getIntroductionMessages(contactId2From0)
.size());
assertEquals(3,
introductionManager1.getIntroductionMessages(contactId0From1)
.size());
assertEquals(3,
introductionManager2.getIntroductionMessages(contactId0From2)
.size());
Collection<PrivateMessageHeader> messages =
withinTransactionReturns(db0, txn -> introductionManager0
.getMessageHeaders(txn, contactId1From0));
assertEquals(2, messages.size());
messages = withinTransactionReturns(db0,
txn -> introductionManager0
.getMessageHeaders(txn, contactId2From0));
assertEquals(2, messages.size());
messages = withinTransactionReturns(db1,
txn -> introductionManager1
.getMessageHeaders(txn, contactId0From1));
assertEquals(3, messages.size());
messages = withinTransactionReturns(db2,
txn -> introductionManager2
.getMessageHeaders(txn, contactId0From2));
assertEquals(3, messages.size());
assertFalse(listener0.aborted);
assertFalse(listener1.aborted);
assertFalse(listener2.aborted);
@@ -482,7 +487,7 @@ public class IntroductionIntegrationTest
// assert that the name on the decline event is correct
eventWaiter.await(TIMEOUT, 1);
assertEquals(introducee1.getAuthor().getName(),
listener2.getResponse().getName());
listener2.getResponse().getIntroducedAuthor().getName());
// assert that introducee2 is in correct state
introduceeSession = getIntroduceeSession(c2);
@@ -519,21 +524,21 @@ public class IntroductionIntegrationTest
Group g1 = introductionManager0.getContactGroup(introducee1);
Group g2 = introductionManager0.getContactGroup(introducee2);
assertEquals(2,
introductionManager0.getIntroductionMessages(contactId1From0)
.size());
assertEquals(2, withinTransactionReturns(db0,
txn -> introductionManager0.getMessageHeaders(txn, contactId1From0))
.size());
assertGroupCount(messageTracker0, g1.getId(), 2, 1);
assertEquals(2,
introductionManager0.getIntroductionMessages(contactId2From0)
.size());
assertEquals(2, withinTransactionReturns(db0,
txn -> introductionManager0.getMessageHeaders(txn, contactId2From0))
.size());
assertGroupCount(messageTracker0, g2.getId(), 2, 1);
assertEquals(3,
introductionManager1.getIntroductionMessages(contactId0From1)
.size());
assertEquals(3, withinTransactionReturns(db1,
txn -> introductionManager1.getMessageHeaders(txn, contactId0From1))
.size());
assertGroupCount(messageTracker1, g1.getId(), 3, 2);
assertEquals(3,
introductionManager2.getIntroductionMessages(contactId0From2)
.size());
assertEquals(3, withinTransactionReturns(db2,
txn -> introductionManager2.getMessageHeaders(txn, contactId0From2))
.size());
assertGroupCount(messageTracker2, g2.getId(), 3, 2);
assertFalse(listener0.aborted);
@@ -557,7 +562,8 @@ public class IntroductionIntegrationTest
assertFalse(listener1.requestReceived);
// make really sure we don't have that request
assertTrue(introductionManager1.getIntroductionMessages(contactId0From1)
assertTrue(withinTransactionReturns(db1,
txn -> introductionManager1.getMessageHeaders(txn, contactId0From1))
.isEmpty());
// The message was invalid, so no abort message was sent
@@ -606,12 +612,12 @@ public class IntroductionIntegrationTest
sync0To2(1, true);
// assert that introducees get notified about the existing contact
IntroductionRequest ir1 =
getIntroductionRequest(introductionManager1, contactId0From1);
assertTrue(ir1.contactExists());
IntroductionRequest ir2 =
getIntroductionRequest(introductionManager2, contactId0From2);
assertTrue(ir2.contactExists());
IntroductionRequest ir1 = getIntroductionRequest(db1,
introductionManager1, contactId0From1);
assertTrue(ir1.isContact());
IntroductionRequest ir2 = getIntroductionRequest(db2,
introductionManager2, contactId0From2);
assertTrue(ir2.isContact());
// sync ACCEPT messages back to introducer
sync1To0(1, true);
@@ -991,8 +997,7 @@ public class IntroductionIntegrationTest
AcceptMessage m = visitor.visit(message);
// replace original response with modified one
Transaction txn = db0.startTransaction(false);
try {
withinTransaction(db0, txn -> {
db0.removeMessage(txn, message.getMessageId());
Message msg = c0.getMessageEncoder()
.encodeAcceptMessage(m.getGroupId(), m.getTimestamp(),
@@ -1012,10 +1017,7 @@ public class IntroductionIntegrationTest
session.getValue(), msg.getId());
c0.getClientHelper().mergeMessageMetadata(txn, session.getKey(),
session.getValue());
db0.commitTransaction(txn);
} finally {
db0.endTransaction(txn);
}
});
// sync second response
sync2To0(1, true);
@@ -1100,30 +1102,31 @@ public class IntroductionIntegrationTest
}
private void assertDefaultUiMessages() throws DbException {
Collection<IntroductionMessage> messages =
introductionManager0.getIntroductionMessages(contactId1From0);
Collection<PrivateMessageHeader> messages =
withinTransactionReturns(db0, txn -> introductionManager0
.getMessageHeaders(txn, contactId1From0));
assertEquals(2, messages.size());
assertMessagesAreAcked(messages);
messages = introductionManager0.getIntroductionMessages(
contactId2From0);
messages = withinTransactionReturns(db0,
txn -> introductionManager0.getMessageHeaders(txn, contactId2From0));
assertEquals(2, messages.size());
assertMessagesAreAcked(messages);
messages = introductionManager1.getIntroductionMessages(
contactId0From1);
messages = withinTransactionReturns(db1,
txn -> introductionManager1.getMessageHeaders(txn, contactId0From1));
assertEquals(2, messages.size());
assertMessagesAreAcked(messages);
messages = introductionManager2.getIntroductionMessages(
contactId0From2);
messages = withinTransactionReturns(db2,
txn -> introductionManager2.getMessageHeaders(txn, contactId0From2));
assertEquals(2, messages.size());
assertMessagesAreAcked(messages);
}
private void assertMessagesAreAcked(
Collection<IntroductionMessage> messages) {
for (IntroductionMessage msg : messages) {
Collection<PrivateMessageHeader> messages) {
for (PrivateMessageHeader msg : messages) {
if (msg.isLocal()) assertTrue(msg.isSeen());
}
}
@@ -1150,7 +1153,7 @@ public class IntroductionIntegrationTest
assertTrue(
latestEvent instanceof IntroductionResponseReceivedEvent);
return ((IntroductionResponseReceivedEvent) latestEvent)
.getIntroductionResponse();
.getMessageHeader();
}
}
@@ -1178,7 +1181,7 @@ public class IntroductionIntegrationTest
IntroductionRequestReceivedEvent introEvent =
((IntroductionRequestReceivedEvent) e);
requestReceived = true;
IntroductionRequest ir = introEvent.getIntroductionRequest();
IntroductionRequest ir = introEvent.getMessageHeader();
ContactId contactId = introEvent.getContactId();
sessionId = ir.getSessionId();
long time = clock.currentTimeMillis();
@@ -1219,7 +1222,7 @@ public class IntroductionIntegrationTest
assertTrue(
latestEvent instanceof IntroductionRequestReceivedEvent);
return ((IntroductionRequestReceivedEvent) latestEvent)
.getIntroductionRequest();
.getMessageHeader();
}
}
@@ -1296,11 +1299,12 @@ public class IntroductionIntegrationTest
} else throw new AssertionError("Not implemented");
}
private IntroductionRequest getIntroductionRequest(
private IntroductionRequest getIntroductionRequest(DatabaseComponent db,
IntroductionManager manager, ContactId contactId)
throws DbException {
for (IntroductionMessage im : manager
.getIntroductionMessages(contactId)) {
Collection<PrivateMessageHeader> messages = withinTransactionReturns(db,
txn -> manager.getMessageHeaders(txn, contactId));
for (PrivateMessageHeader im : messages) {
if (im instanceof IntroductionRequest) {
return (IntroductionRequest) im;
}

View File

@@ -2,7 +2,6 @@ package org.briarproject.briar.privategroup;
import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.test.TestDatabaseModule;
@@ -245,11 +244,8 @@ public class PrivateGroupManagerIntegrationTest
groupManager0.getPreviousMsgId(groupId0));
// share the group with 1
Transaction txn0 = db0.startTransaction(false);
db0.setGroupVisibility(txn0, contactId1From0, privateGroup0.getId(),
SHARED);
db0.commitTransaction(txn0);
db0.endTransaction(txn0);
withinTransaction(db0, txn -> db0.setGroupVisibility(txn,
contactId1From0, privateGroup0.getId(), SHARED));
// author1 joins privateGroup0 with wrong timestamp
joinTime = clock.currentTimeMillis();
@@ -266,11 +262,8 @@ public class PrivateGroupManagerIntegrationTest
groupManager1.getPreviousMsgId(groupId0));
// share the group with 0
Transaction txn1 = db1.startTransaction(false);
db1.setGroupVisibility(txn1, contactId0From1, privateGroup0.getId(),
SHARED);
db1.commitTransaction(txn1);
db1.endTransaction(txn1);
withinTransaction(db1, txn -> db1.setGroupVisibility(txn,
contactId0From1, privateGroup0.getId(), SHARED));
// sync join messages
sync0To1(1, false);
@@ -303,11 +296,8 @@ public class PrivateGroupManagerIntegrationTest
groupManager0.getPreviousMsgId(groupId0));
// share the group with 1
Transaction txn0 = db0.startTransaction(false);
db0.setGroupVisibility(txn0, contactId1From0, privateGroup0.getId(),
SHARED);
db0.commitTransaction(txn0);
db0.endTransaction(txn0);
withinTransaction(db0, txn -> db0.setGroupVisibility(txn,
contactId1From0, privateGroup0.getId(), SHARED));
// author1 joins privateGroup0 with wrong signature in join message
joinTime = clock.currentTimeMillis();
@@ -325,11 +315,8 @@ public class PrivateGroupManagerIntegrationTest
groupManager1.getPreviousMsgId(groupId0));
// share the group with 0
Transaction txn1 = db1.startTransaction(false);
db1.setGroupVisibility(txn1, contactId0From1, privateGroup0.getId(),
SHARED);
db1.commitTransaction(txn1);
db1.endTransaction(txn1);
withinTransaction(db1, txn -> db1.setGroupVisibility(txn,
contactId0From1, privateGroup0.getId(), SHARED));
// sync join messages
sync0To1(1, false);
@@ -404,11 +391,8 @@ public class PrivateGroupManagerIntegrationTest
addGroup();
// share the group with 2
Transaction txn0 = db0.startTransaction(false);
db0.setGroupVisibility(txn0, contactId2From0, privateGroup0.getId(),
SHARED);
db0.commitTransaction(txn0);
db0.endTransaction(txn0);
withinTransaction(db0, txn -> db0.setGroupVisibility(txn,
contactId2From0, privateGroup0.getId(), SHARED));
// author2 joins privateGroup0
long joinTime = clock.currentTimeMillis();
@@ -420,14 +404,12 @@ public class PrivateGroupManagerIntegrationTest
GroupMessage joinMsg2 = groupMessageFactory
.createJoinMessage(privateGroup0.getId(), joinTime, author2,
inviteTime, creatorSignature);
Transaction txn2 = db2.startTransaction(false);
groupManager2.addPrivateGroup(txn2, privateGroup0, joinMsg2, false);
// share the group with 0
db2.setGroupVisibility(txn2, contactId0From1, privateGroup0.getId(),
SHARED);
db2.commitTransaction(txn2);
db2.endTransaction(txn2);
withinTransaction(db2, txn -> {
groupManager2.addPrivateGroup(txn, privateGroup0, joinMsg2, false);
// share the group with 0
db2.setGroupVisibility(txn,
contactId0From2, privateGroup0.getId(), SHARED);
});
// sync join messages
sync2To0(1, true);
@@ -458,16 +440,10 @@ public class PrivateGroupManagerIntegrationTest
}
// reveal contact relationship
Transaction txn1 = db1.startTransaction(false);
groupManager1
.relationshipRevealed(txn1, groupId0, author2.getId(), false);
db1.commitTransaction(txn1);
db1.endTransaction(txn1);
txn2 = db2.startTransaction(false);
groupManager2
.relationshipRevealed(txn2, groupId0, author1.getId(), true);
db2.commitTransaction(txn2);
db2.endTransaction(txn2);
withinTransaction(db1, txn -> groupManager1.relationshipRevealed(txn,
groupId0, author2.getId(), false));
withinTransaction(db2, txn -> groupManager2.relationshipRevealed(txn,
groupId0, author1.getId(), true));
// assert that contact relationship is now revealed properly
members1 = groupManager1.getMembers(groupId0);
@@ -520,10 +496,8 @@ public class PrivateGroupManagerIntegrationTest
assertFalse(groupManager1.isDissolved(groupId0));
// creator dissolves group
Transaction txn1 = db1.startTransaction(false);
groupManager1.markGroupDissolved(txn1, groupId0);
db1.commitTransaction(txn1);
db1.endTransaction(txn1);
withinTransaction(db1,
txn -> groupManager1.markGroupDissolved(txn, groupId0));
// group is dissolved now
assertTrue(groupManager1.isDissolved(groupId0));
@@ -539,11 +513,8 @@ public class PrivateGroupManagerIntegrationTest
groupManager0.getPreviousMsgId(groupId0));
// share the group with 1
Transaction txn0 = db0.startTransaction(false);
db0.setGroupVisibility(txn0, contactId1From0, privateGroup0.getId(),
SHARED);
db0.commitTransaction(txn0);
db0.endTransaction(txn0);
withinTransaction(db0, txn -> db0.setGroupVisibility(txn,
contactId1From0, privateGroup0.getId(), SHARED));
// author1 joins privateGroup0
joinTime = clock.currentTimeMillis();
@@ -558,11 +529,8 @@ public class PrivateGroupManagerIntegrationTest
groupManager1.addPrivateGroup(privateGroup0, joinMsg1, false);
// share the group with 0
Transaction txn1 = db1.startTransaction(false);
db1.setGroupVisibility(txn1, contactId0From1, privateGroup0.getId(),
SHARED);
db1.commitTransaction(txn1);
db1.endTransaction(txn1);
withinTransaction(db1, txn -> db1.setGroupVisibility(txn,
contactId0From1, privateGroup0.getId(), SHARED));
assertEquals(joinMsg1.getMessage().getId(),
groupManager1.getPreviousMsgId(groupId0));

View File

@@ -4,6 +4,7 @@ import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.sync.Group;
import org.briarproject.bramble.test.TestDatabaseModule;
import org.briarproject.briar.api.client.ProtocolStateException;
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
import org.briarproject.briar.api.privategroup.GroupMessage;
import org.briarproject.briar.api.privategroup.PrivateGroup;
import org.briarproject.briar.api.privategroup.PrivateGroupManager;
@@ -11,8 +12,6 @@ import org.briarproject.briar.api.privategroup.invitation.GroupInvitationItem;
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationManager;
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationRequest;
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationResponse;
import org.briarproject.briar.api.sharing.InvitationMessage;
import org.briarproject.briar.api.sharing.InvitationResponse;
import org.briarproject.briar.test.BriarIntegrationTest;
import org.briarproject.briar.test.BriarIntegrationTestComponent;
import org.briarproject.briar.test.DaggerBriarIntegrationTestComponent;
@@ -92,19 +91,20 @@ public class GroupInvitationIntegrationTest
assertEquals(privateGroup0.getName(), item.getName());
assertFalse(item.isSubscribed());
Collection<InvitationMessage> messages =
groupInvitationManager1.getInvitationMessages(contactId0From1);
Collection<PrivateMessageHeader> messages =
withinTransactionReturns(db1, txn -> groupInvitationManager1
.getMessageHeaders(txn, contactId0From1));
assertEquals(1, messages.size());
GroupInvitationRequest request =
(GroupInvitationRequest) messages.iterator().next();
assertEquals(msg, request.getMessage());
assertEquals(author0, request.getShareable().getCreator());
assertEquals(author0, request.getNameable().getCreator());
assertEquals(timestamp, request.getTimestamp());
assertEquals(contactId0From1, request.getContactId());
assertEquals(privateGroup0.getName(), request.getShareable().getName());
assertEquals(privateGroup0.getName(), request.getNameable().getName());
assertFalse(request.isLocal());
assertFalse(request.isRead());
assertFalse(request.canBeOpened());
assertFalse(request.wasAnswered());
}
@Test
@@ -118,15 +118,16 @@ public class GroupInvitationIntegrationTest
groupInvitationManager1
.respondToInvitation(contactId0From1, privateGroup0, false);
Collection<InvitationMessage> messages =
groupInvitationManager1.getInvitationMessages(contactId0From1);
Collection<PrivateMessageHeader> messages =
withinTransactionReturns(db1, txn -> groupInvitationManager1
.getMessageHeaders(txn, contactId0From1));
assertEquals(2, messages.size());
boolean foundResponse = false;
for (InvitationMessage m : messages) {
for (PrivateMessageHeader m : messages) {
if (m instanceof GroupInvitationResponse) {
foundResponse = true;
InvitationResponse response = (GroupInvitationResponse) m;
assertEquals(contactId0From1, response.getContactId());
GroupInvitationResponse response = (GroupInvitationResponse) m;
assertEquals(privateGroup0.getId(), response.getShareableId());
assertTrue(response.isLocal());
assertFalse(response.wasAccepted());
}
@@ -135,15 +136,15 @@ public class GroupInvitationIntegrationTest
sync1To0(1, true);
messages =
groupInvitationManager0.getInvitationMessages(contactId1From0);
messages = withinTransactionReturns(db0, txn -> groupInvitationManager0
.getMessageHeaders(txn, contactId1From0));
assertEquals(2, messages.size());
foundResponse = false;
for (InvitationMessage m : messages) {
for (PrivateMessageHeader m : messages) {
if (m instanceof GroupInvitationResponse) {
foundResponse = true;
InvitationResponse response = (GroupInvitationResponse) m;
assertEquals(contactId0From1, response.getContactId());
GroupInvitationResponse response = (GroupInvitationResponse) m;
assertEquals(privateGroup0.getId(), response.getShareableId());
assertFalse(response.isLocal());
assertFalse(response.wasAccepted());
}
@@ -167,31 +168,37 @@ public class GroupInvitationIntegrationTest
groupInvitationManager1
.respondToInvitation(contactId0From1, privateGroup0, true);
Collection<InvitationMessage> messages =
groupInvitationManager1.getInvitationMessages(contactId0From1);
Collection<PrivateMessageHeader> messages =
withinTransactionReturns(db1, txn -> groupInvitationManager1
.getMessageHeaders(txn, contactId0From1));
assertEquals(2, messages.size());
boolean foundResponse = false;
for (InvitationMessage m : messages) {
for (PrivateMessageHeader m : messages) {
if (m instanceof GroupInvitationResponse) {
foundResponse = true;
InvitationResponse response = (GroupInvitationResponse) m;
GroupInvitationResponse response = (GroupInvitationResponse) m;
assertEquals(privateGroup0.getId(), response.getShareableId());
assertTrue(response.wasAccepted());
} else {
assertTrue(((GroupInvitationRequest) m).canBeOpened());
GroupInvitationRequest request = (GroupInvitationRequest) m;
assertEquals(privateGroup0, request.getNameable());
assertTrue(request.wasAnswered());
assertTrue(request.canBeOpened());
}
}
assertTrue(foundResponse);
sync1To0(1, true);
messages =
groupInvitationManager0.getInvitationMessages(contactId1From0);
messages = withinTransactionReturns(db1, txn -> groupInvitationManager0
.getMessageHeaders(txn, contactId1From0));
assertEquals(2, messages.size());
foundResponse = false;
for (InvitationMessage m : messages) {
for (PrivateMessageHeader m : messages) {
if (m instanceof GroupInvitationResponse) {
foundResponse = true;
InvitationResponse response = (GroupInvitationResponse) m;
GroupInvitationResponse response = (GroupInvitationResponse) m;
assertEquals(privateGroup0.getId(), response.getShareableId());
assertTrue(response.wasAccepted());
}
}
@@ -219,9 +226,9 @@ public class GroupInvitationIntegrationTest
// 1 has one unread message
Group g0 = groupInvitationManager1.getContactGroup(contact0From1);
assertGroupCount(messageTracker1, g0.getId(), 1, 1, timestamp);
InvitationMessage m =
groupInvitationManager1.getInvitationMessages(contactId0From1)
.iterator().next();
PrivateMessageHeader m = withinTransactionReturns(db1,
txn -> groupInvitationManager1.getMessageHeaders(txn, contactId0From1)
.iterator().next());
groupInvitationManager1
.respondToInvitation(contactId0From1, privateGroup0, true);

View File

@@ -24,13 +24,13 @@ import org.briarproject.bramble.test.BrambleMockTestCase;
import org.briarproject.bramble.test.TestUtils;
import org.briarproject.briar.api.client.MessageTracker;
import org.briarproject.briar.api.client.SessionId;
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
import org.briarproject.briar.api.privategroup.PrivateGroup;
import org.briarproject.briar.api.privategroup.PrivateGroupFactory;
import org.briarproject.briar.api.privategroup.PrivateGroupManager;
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationItem;
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationRequest;
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationResponse;
import org.briarproject.briar.api.sharing.InvitationMessage;
import org.jmock.AbstractExpectations;
import org.jmock.Expectations;
import org.jmock.lib.legacy.ClassImposteriser;
@@ -669,8 +669,6 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
invite.getCreator(), invite.getSalt());
context.checking(new Expectations() {{
oneOf(db).startTransaction(true);
will(returnValue(txn));
oneOf(db).getContact(txn, contactId);
will(returnValue(contact));
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
@@ -696,23 +694,22 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
oneOf(messageParser).parseMetadata(meta2);
will(returnValue(messageMetadata2));
oneOf(db).getMessageStatus(txn, contactId, messageId2);
// end transaction
oneOf(db).commitTransaction(txn);
oneOf(db).endTransaction(txn);
}});
Collection<InvitationMessage> messages =
groupInvitationManager.getInvitationMessages(contactId);
Collection<PrivateMessageHeader> messages =
groupInvitationManager.getMessageHeaders(txn, contactId);
assertEquals(2, messages.size());
for (InvitationMessage m : messages) {
for (PrivateMessageHeader m : messages) {
assertEquals(contactGroup.getId(), m.getGroupId());
assertEquals(contactId, m.getContactId());
if (m.getId().equals(message.getId())) {
assertTrue(m instanceof GroupInvitationRequest);
assertEquals(time1, m.getTimestamp());
assertEquals(pg, ((GroupInvitationRequest) m).getNameable());
} else if (m.getId().equals(messageId2)) {
assertTrue(m instanceof GroupInvitationResponse);
assertEquals(time2, m.getTimestamp());
assertEquals(pg.getId(),
((GroupInvitationResponse) m).getShareableId());
} else {
throw new AssertionError();
}

View File

@@ -18,7 +18,7 @@ import org.briarproject.briar.api.blog.BlogManager;
import org.briarproject.briar.api.blog.BlogSharingManager;
import org.briarproject.briar.api.blog.event.BlogInvitationRequestReceivedEvent;
import org.briarproject.briar.api.blog.event.BlogInvitationResponseReceivedEvent;
import org.briarproject.briar.api.sharing.InvitationMessage;
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
import org.briarproject.briar.test.BriarIntegrationTest;
import org.briarproject.briar.test.BriarIntegrationTestComponent;
import org.briarproject.briar.test.DaggerBriarIntegrationTestComponent;
@@ -27,9 +27,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import static org.briarproject.briar.api.blog.BlogSharingManager.CLIENT_ID;
import static org.briarproject.briar.api.blog.BlogSharingManager.MAJOR_VERSION;
@@ -147,32 +145,30 @@ public class BlogSharingIntegrationTest
assertTrue(blogManager1.getBlogs().contains(blog2));
// invitee has one invitation message from sharer
List<InvitationMessage> list = new ArrayList<>(
blogSharingManager1.getInvitationMessages(contactId0From1));
Collection<PrivateMessageHeader> list = withinTransactionReturns(db1,
txn -> blogSharingManager1.getMessageHeaders(txn, contactId0From1));
assertEquals(2, list.size());
// check other things are alright with the message
for (InvitationMessage m : list) {
for (PrivateMessageHeader m : list) {
if (m instanceof BlogInvitationRequest) {
BlogInvitationRequest invitation =
(BlogInvitationRequest) m;
assertFalse(invitation.isAvailable());
BlogInvitationRequest invitation = (BlogInvitationRequest) m;
assertEquals(blog2, invitation.getNameable());
assertTrue(invitation.wasAnswered());
assertEquals(blog2.getAuthor().getName(),
invitation.getBlogAuthorName());
assertFalse(invitation.getShareable().isRssFeed());
assertEquals(contactId1From0, invitation.getContactId());
invitation.getName());
assertFalse(invitation.getNameable().isRssFeed());
assertEquals("Hi!", invitation.getMessage());
} else {
BlogInvitationResponse response =
(BlogInvitationResponse) m;
assertEquals(contactId0From1, response.getContactId());
BlogInvitationResponse response = (BlogInvitationResponse) m;
assertEquals(blog2.getId(), response.getShareableId());
assertTrue(response.wasAccepted());
assertTrue(response.isLocal());
}
}
// sharer has own invitation message and response
assertEquals(2,
blogSharingManager0.getInvitationMessages(contactId1From0)
.size());
assertEquals(2, withinTransactionReturns(db0,
txn -> blogSharingManager0.getMessageHeaders(txn, contactId1From0))
.size());
// blog can not be shared again
assertFalse(blogSharingManager0.canBeShared(blog2.getId(),
contact1From0));
@@ -222,31 +218,30 @@ public class BlogSharingIntegrationTest
assertTrue(blogManager1.getBlogs().contains(rssBlog));
// invitee has one invitation message from sharer
List<InvitationMessage> list = new ArrayList<>(
blogSharingManager1.getInvitationMessages(contactId0From1));
Collection<PrivateMessageHeader> list = withinTransactionReturns(db1,
txn -> blogSharingManager1.getMessageHeaders(txn, contactId0From1));
assertEquals(2, list.size());
// check other things are alright with the message
for (InvitationMessage m : list) {
for (PrivateMessageHeader m : list) {
if (m instanceof BlogInvitationRequest) {
BlogInvitationRequest invitation =
(BlogInvitationRequest) m;
assertFalse(invitation.isAvailable());
BlogInvitationRequest invitation = (BlogInvitationRequest) m;
assertEquals(rssBlog, invitation.getNameable());
assertTrue(invitation.wasAnswered());
assertEquals(rssBlog.getAuthor().getName(),
invitation.getBlogAuthorName());
assertTrue(invitation.getShareable().isRssFeed());
assertEquals(contactId1From0, invitation.getContactId());
invitation.getName());
assertTrue(invitation.getNameable().isRssFeed());
assertEquals("Hi!", invitation.getMessage());
} else {
BlogInvitationResponse response =
(BlogInvitationResponse) m;
assertEquals(contactId0From1, response.getContactId());
BlogInvitationResponse response = (BlogInvitationResponse) m;
assertEquals(rssBlog.getId(), response.getShareableId());
assertTrue(response.wasAccepted());
assertTrue(response.isLocal());
}
}
// sharer has own invitation message and response
assertEquals(2, blogSharingManager0.getInvitationMessages(
contactId1From0).size());
assertEquals(2, withinTransactionReturns(db0,
txn -> blogSharingManager0.getMessageHeaders(txn, contactId1From0))
.size());
// blog can not be shared again
assertFalse(blogSharingManager0.canBeShared(rssBlog.getId(),
contact1From0));
@@ -285,31 +280,29 @@ public class BlogSharingIntegrationTest
assertEquals(0, blogSharingManager1.getInvitations().size());
// invitee has one invitation message from sharer and one response
List<InvitationMessage> list = new ArrayList<>(
blogSharingManager1.getInvitationMessages(contactId0From1));
Collection<PrivateMessageHeader> list = withinTransactionReturns(db1,
txn -> blogSharingManager1.getMessageHeaders(txn, contactId0From1));
assertEquals(2, list.size());
// check things are alright with the message
for (InvitationMessage m : list) {
for (PrivateMessageHeader m : list) {
if (m instanceof BlogInvitationRequest) {
BlogInvitationRequest invitation =
(BlogInvitationRequest) m;
assertFalse(invitation.isAvailable());
BlogInvitationRequest invitation = (BlogInvitationRequest) m;
assertEquals(blog2, invitation.getNameable());
assertTrue(invitation.wasAnswered());
assertEquals(blog2.getAuthor().getName(),
invitation.getBlogAuthorName());
assertEquals(contactId1From0, invitation.getContactId());
invitation.getName());
assertEquals(null, invitation.getMessage());
} else {
BlogInvitationResponse response =
(BlogInvitationResponse) m;
assertEquals(contactId0From1, response.getContactId());
BlogInvitationResponse response = (BlogInvitationResponse) m;
assertEquals(blog2.getId(), response.getShareableId());
assertFalse(response.wasAccepted());
assertTrue(response.isLocal());
}
}
// sharer has own invitation message and response
assertEquals(2,
blogSharingManager0.getInvitationMessages(contactId1From0)
.size());
assertEquals(2, withinTransactionReturns(db0,
txn -> blogSharingManager0.getMessageHeaders(txn, contactId1From0))
.size());
// blog can be shared again
assertTrue(
blogSharingManager0.canBeShared(blog2.getId(), contact1From0));
@@ -394,8 +387,9 @@ public class BlogSharingIntegrationTest
assertTrue(contacts.contains(contact0From1));
// make sure 1 knows that they have blog2 already
Collection<InvitationMessage> messages =
blogSharingManager1.getInvitationMessages(contactId0From1);
Collection<PrivateMessageHeader> messages =
withinTransactionReturns(db1, txn -> blogSharingManager1
.getMessageHeaders(txn, contactId0From1));
assertEquals(2, messages.size());
assertEquals(blog2, blogManager1.getBlog(blog2.getId()));
@@ -565,7 +559,7 @@ public class BlogSharingIntegrationTest
BlogInvitationRequestReceivedEvent event =
(BlogInvitationRequestReceivedEvent) e;
eventWaiter.assertEquals(contactId1From0, event.getContactId());
Blog b = event.getShareable();
Blog b = event.getMessageHeader().getNameable();
try {
Contact c = contactManager0.getContact(contactId1From0);
blogSharingManager0.respondToInvitation(b, c, true);
@@ -601,7 +595,7 @@ public class BlogSharingIntegrationTest
(BlogInvitationRequestReceivedEvent) e;
requestReceived = true;
if (!answer) return;
Blog b = event.getShareable();
Blog b = event.getMessageHeader().getNameable();
try {
eventWaiter.assertEquals(1,
blogSharingManager1.getInvitations().size());
@@ -624,7 +618,7 @@ public class BlogSharingIntegrationTest
}
}
private void listenToEvents(boolean accept) throws DbException {
private void listenToEvents(boolean accept) {
listener0 = new SharerListener();
c0.getEventBus().addListener(listener0);
listener1 = new InviteeListener(accept);

View File

@@ -5,7 +5,6 @@ import net.jodah.concurrentunit.Waiter;
import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.event.EventListener;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@@ -22,7 +21,7 @@ import org.briarproject.briar.api.forum.ForumPostHeader;
import org.briarproject.briar.api.forum.ForumSharingManager;
import org.briarproject.briar.api.forum.event.ForumInvitationRequestReceivedEvent;
import org.briarproject.briar.api.forum.event.ForumInvitationResponseReceivedEvent;
import org.briarproject.briar.api.sharing.InvitationMessage;
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
import org.briarproject.briar.api.sharing.SharingInvitationItem;
import org.briarproject.briar.test.BriarIntegrationTest;
import org.briarproject.briar.test.BriarIntegrationTestComponent;
@@ -32,9 +31,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import static junit.framework.Assert.assertNotNull;
import static org.briarproject.bramble.util.StringUtils.getRandomString;
@@ -131,31 +128,28 @@ public class ForumSharingIntegrationTest
assertEquals(1, forumManager1.getForums().size());
// invitee has one invitation message from sharer
List<InvitationMessage> list = new ArrayList<>(
forumSharingManager1.getInvitationMessages(contactId0From1));
Collection<PrivateMessageHeader> list = withinTransactionReturns(db1,
txn -> forumSharingManager1.getMessageHeaders(txn, contactId0From1));
assertEquals(2, list.size());
// check other things are alright with the forum message
for (InvitationMessage m : list) {
for (PrivateMessageHeader m : list) {
if (m instanceof ForumInvitationRequest) {
ForumInvitationRequest invitation =
(ForumInvitationRequest) m;
assertFalse(invitation.isAvailable());
assertEquals(forum0.getName(), invitation.getForumName());
assertEquals(contactId1From0, invitation.getContactId());
ForumInvitationRequest invitation = (ForumInvitationRequest) m;
assertTrue(invitation.wasAnswered());
assertEquals(forum0.getName(), invitation.getName());
assertEquals(forum0, invitation.getNameable());
assertEquals("Hi!", invitation.getMessage());
assertTrue(invitation.canBeOpened());
} else {
ForumInvitationResponse response =
(ForumInvitationResponse) m;
assertEquals(contactId0From1, response.getContactId());
ForumInvitationResponse response = (ForumInvitationResponse) m;
assertEquals(forum0.getId(), response.getShareableId());
assertTrue(response.wasAccepted());
assertTrue(response.isLocal());
}
}
// sharer has own invitation message and response
assertEquals(2,
forumSharingManager0.getInvitationMessages(contactId1From0)
.size());
assertEquals(2, withinTransactionReturns(db0, txn ->
forumSharingManager0.getMessageHeaders(txn, contactId1From0)).size());
// forum can not be shared again
Contact c1 = contactManager0.getContact(contactId1From0);
assertFalse(forumSharingManager0.canBeShared(forum0.getId(), c1));
@@ -190,31 +184,28 @@ public class ForumSharingIntegrationTest
assertEquals(0, forumSharingManager1.getInvitations().size());
// invitee has one invitation message from sharer and one response
List<InvitationMessage> list = new ArrayList<>(
forumSharingManager1.getInvitationMessages(contactId0From1));
Collection<PrivateMessageHeader> list = withinTransactionReturns(db1,
txn -> forumSharingManager1.getMessageHeaders(txn, contactId0From1));
assertEquals(2, list.size());
// check things are alright with the forum message
for (InvitationMessage m : list) {
for (PrivateMessageHeader m : list) {
if (m instanceof ForumInvitationRequest) {
ForumInvitationRequest invitation =
(ForumInvitationRequest) m;
assertFalse(invitation.isAvailable());
assertEquals(forum0.getName(), invitation.getForumName());
assertEquals(contactId1From0, invitation.getContactId());
ForumInvitationRequest invitation = (ForumInvitationRequest) m;
assertEquals(forum0, invitation.getNameable());
assertTrue(invitation.wasAnswered());
assertEquals(forum0.getName(), invitation.getName());
assertEquals(null, invitation.getMessage());
assertFalse(invitation.canBeOpened());
} else {
ForumInvitationResponse response =
(ForumInvitationResponse) m;
assertEquals(contactId0From1, response.getContactId());
ForumInvitationResponse response = (ForumInvitationResponse) m;
assertEquals(forum0.getId(), response.getShareableId());
assertFalse(response.wasAccepted());
assertTrue(response.isLocal());
}
}
// sharer has own invitation message and response
assertEquals(2,
forumSharingManager0.getInvitationMessages(contactId1From0)
.size());
assertEquals(2, withinTransactionReturns(db0, txn ->
forumSharingManager0.getMessageHeaders(txn, contactId1From0)).size());
// forum can be shared again
Contact c1 = contactManager0.getContact(contactId1From0);
assertTrue(forumSharingManager0.canBeShared(forum0.getId(), c1));
@@ -455,10 +446,7 @@ public class ForumSharingIntegrationTest
listenToEvents(true);
// invitee adds the same forum
Transaction txn = db1.startTransaction(false);
forumManager1.addForum(txn, forum0);
db1.commitTransaction(txn);
db1.endTransaction(txn);
withinTransaction(db1, txn -> forumManager1.addForum(txn, forum0));
// send invitation
forumSharingManager0
@@ -490,10 +478,12 @@ public class ForumSharingIntegrationTest
.contains(contact0From1));
// and both have each other's invitations (and no response)
assertEquals(2, forumSharingManager0
.getInvitationMessages(contactId1From0).size());
assertEquals(2, forumSharingManager1
.getInvitationMessages(contactId0From1).size());
assertEquals(2, withinTransactionReturns(db0, txn ->
forumSharingManager0.getMessageHeaders(txn, contactId1From0))
.size());
assertEquals(2, withinTransactionReturns(db1, txn ->
forumSharingManager1.getMessageHeaders(txn, contactId0From1))
.size());
// there are no more open invitations
assertTrue(forumSharingManager0.getInvitations().isEmpty());
@@ -568,17 +558,14 @@ public class ForumSharingIntegrationTest
@Test
public void testTwoContactsShareSameForum() throws Exception {
// second sharer adds the same forum
Transaction txn = db2.startTransaction(false);
db2.addGroup(txn, forum0.getGroup());
db2.commitTransaction(txn);
db2.endTransaction(txn);
withinTransaction(db2, txn -> db2.addGroup(txn, forum0.getGroup()));
// add listeners
listener0 = new SharerListener();
listener0 = new SharerListener(true);
c0.getEventBus().addListener(listener0);
listener1 = new InviteeListener(true, false);
c1.getEventBus().addListener(listener1);
listener2 = new SharerListener();
listener2 = new SharerListener(true);
c2.getEventBus().addListener(listener2);
// send invitation
@@ -748,8 +735,9 @@ public class ForumSharingIntegrationTest
// get invitation MessageId for later
MessageId invitationId = null;
for (InvitationMessage m : forumSharingManager1
.getInvitationMessages(contactId0From1)) {
Collection<PrivateMessageHeader> list = withinTransactionReturns(db1,
txn -> forumSharingManager1.getMessageHeaders(txn, contactId0From1));
for (PrivateMessageHeader m : list) {
if (m instanceof ForumInvitationRequest) {
invitationId = m.getId();
}
@@ -802,13 +790,22 @@ public class ForumSharingIntegrationTest
@NotNullByDefault
private class SharerListener implements EventListener {
private final boolean accept;
private volatile boolean requestReceived = false;
private volatile boolean responseReceived = false;
private SharerListener(boolean accept) {
this.accept = accept;
}
@Override
public void eventOccurred(Event e) {
if (e instanceof ForumInvitationResponseReceivedEvent) {
ForumInvitationResponseReceivedEvent event =
(ForumInvitationResponseReceivedEvent) e;
responseReceived = true;
eventWaiter.assertEquals(accept,
event.getMessageHeader().wasAccepted());
eventWaiter.resume();
}
// this is only needed for tests where a forum is re-shared
@@ -817,7 +814,7 @@ public class ForumSharingIntegrationTest
(ForumInvitationRequestReceivedEvent) e;
eventWaiter.assertEquals(contactId1From0, event.getContactId());
requestReceived = true;
Forum f = event.getShareable();
Forum f = event.getMessageHeader().getNameable();
try {
if (respond) {
Contact c = contactManager0.getContact(contactId1From0);
@@ -855,7 +852,7 @@ public class ForumSharingIntegrationTest
(ForumInvitationRequestReceivedEvent) e;
requestReceived = true;
if (!answer) return;
Forum f = event.getShareable();
Forum f = event.getMessageHeader().getNameable();
try {
if (respond) {
eventWaiter.assertEquals(1,
@@ -880,17 +877,19 @@ public class ForumSharingIntegrationTest
ForumInvitationResponseReceivedEvent event =
(ForumInvitationResponseReceivedEvent) e;
eventWaiter.assertEquals(contactId0From1, event.getContactId());
eventWaiter.assertEquals(accept,
event.getMessageHeader().wasAccepted());
eventWaiter.resume();
}
}
}
private void listenToEvents(boolean accept) throws DbException {
listener0 = new SharerListener();
private void listenToEvents(boolean accept) {
listener0 = new SharerListener(accept);
c0.getEventBus().addListener(listener0);
listener1 = new InviteeListener(accept);
c1.getEventBus().addListener(listener1);
listener2 = new SharerListener();
listener2 = new SharerListener(accept);
c2.getEventBus().addListener(listener2);
}

View File

@@ -2,6 +2,7 @@ package org.briarproject.briar.test;
import net.jodah.concurrentunit.Waiter;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.client.ContactGroupFactory;
import org.briarproject.bramble.api.contact.Contact;
@@ -10,6 +11,7 @@ import org.briarproject.bramble.api.contact.ContactManager;
import org.briarproject.bramble.api.crypto.CryptoComponent;
import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.event.EventListener;
import org.briarproject.bramble.api.identity.AuthorFactory;
@@ -376,4 +378,41 @@ public abstract class BriarIntegrationTest<C extends BriarIntegrationTestCompone
assertNotNull(contactId1From2);
contactManager2.removeContact(contactId1From2);
}
@FunctionalInterface
protected interface TransactionScope {
void execute(Transaction txn) throws DbException, FormatException;
}
protected void withinTransaction(DatabaseComponent db,
TransactionScope scope) throws DbException {
Transaction txn = db.startTransaction(false);
try {
scope.execute(txn);
db.commitTransaction(txn);
} catch (FormatException e) {
throw new DbException(e);
} finally {
db.endTransaction(txn);
}
}
@FunctionalInterface
protected interface TransactionResultScope<R> {
R execute(Transaction txn) throws DbException;
}
protected <R> R withinTransactionReturns(DatabaseComponent db,
TransactionResultScope<R> scope) throws DbException {
Transaction txn = db.startTransaction(false);
R r;
try {
r = scope.execute(txn);
db.commitTransaction(txn);
} finally {
db.endTransaction(txn);
}
return r;
}
}