Also use dedicated classes to represent messages instead of BdfDictionary

This commit is contained in:
Torsten Grote
2016-05-12 13:48:32 -03:00
parent 9532a60f43
commit bd01c3732e
5 changed files with 314 additions and 221 deletions

View File

@@ -0,0 +1,166 @@
package org.briarproject.api.forum;
import org.briarproject.api.FormatException;
import org.briarproject.api.clients.SessionId;
import org.briarproject.api.data.BdfDictionary;
import org.briarproject.api.data.BdfEntry;
import org.briarproject.api.data.BdfList;
import org.briarproject.api.sync.GroupId;
import static org.briarproject.api.forum.ForumConstants.FORUM_NAME;
import static org.briarproject.api.forum.ForumConstants.FORUM_SALT;
import static org.briarproject.api.forum.ForumConstants.GROUP_ID;
import static org.briarproject.api.forum.ForumConstants.INVITATION_MSG;
import static org.briarproject.api.forum.ForumConstants.SESSION_ID;
import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_ABORT;
import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_ACCEPT;
import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_DECLINE;
import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_INVITATION;
import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_LEAVE;
import static org.briarproject.api.forum.ForumConstants.TYPE;
public interface ForumSharingMessage {
abstract class BaseMessage {
private final GroupId groupId;
private final SessionId sessionId;
public BaseMessage(GroupId groupId, SessionId sessionId) {
this.groupId = groupId;
this.sessionId = sessionId;
}
public BdfList toBdfList() {
return BdfList.of(getType(), getSessionId());
}
public abstract BdfDictionary toBdfDictionary();
protected BdfDictionary toBdfDictionaryHelper() {
return BdfDictionary.of(
new BdfEntry(TYPE, getType()),
new BdfEntry(GROUP_ID, groupId),
new BdfEntry(SESSION_ID, sessionId)
);
}
public static BaseMessage from(GroupId groupId, BdfDictionary d)
throws FormatException {
long type = d.getLong(TYPE);
if (type == SHARE_MSG_TYPE_INVITATION)
return Invitation.from(groupId, d);
else
return SimpleMessage.from(type, groupId, d);
}
public abstract long getType();
public GroupId getGroupId() {
return groupId;
}
public SessionId getSessionId() {
return sessionId;
}
}
class Invitation extends BaseMessage {
private final String forumName;
private final byte[] forumSalt;
private final String message;
public Invitation(GroupId groupId, SessionId sessionId,
String forumName, byte[] forumSalt, String message) {
super(groupId, sessionId);
this.forumName = forumName;
this.forumSalt = forumSalt;
this.message = message;
}
@Override
public long getType() {
return SHARE_MSG_TYPE_INVITATION;
}
@Override
public BdfList toBdfList() {
BdfList list = super.toBdfList();
list.add(forumName);
list.add(forumSalt);
if (message != null) list.add(message);
return list;
}
@Override
public BdfDictionary toBdfDictionary() {
BdfDictionary d = toBdfDictionaryHelper();
d.put(FORUM_NAME, forumName);
d.put(FORUM_SALT, forumSalt);
if (message != null) d.put(INVITATION_MSG, message);
return d;
}
public static Invitation from(GroupId groupId, BdfDictionary d)
throws FormatException {
SessionId sessionId = new SessionId(d.getRaw(SESSION_ID));
String forumName = d.getString(FORUM_NAME);
byte[] forumSalt = d.getRaw(FORUM_SALT);
String message = d.getOptionalString(INVITATION_MSG);
return new Invitation(groupId, sessionId, forumName, forumSalt,
message);
}
public String getForumName() {
return forumName;
}
public byte[] getForumSalt() {
return forumSalt;
}
public String getMessage() {
return message;
}
}
class SimpleMessage extends BaseMessage {
private final long type;
public SimpleMessage(long type, GroupId groupId, SessionId sessionId) {
super(groupId, sessionId);
this.type = type;
}
@Override
public long getType() {
return type;
}
@Override
public BdfDictionary toBdfDictionary() {
return toBdfDictionaryHelper();
}
public static SimpleMessage from(long type, GroupId groupId,
BdfDictionary d) throws FormatException {
if (type != SHARE_MSG_TYPE_ACCEPT &&
type != SHARE_MSG_TYPE_DECLINE &&
type != SHARE_MSG_TYPE_LEAVE &&
type != SHARE_MSG_TYPE_ABORT) throw new FormatException();
SessionId sessionId = new SessionId(d.getRaw(SESSION_ID));
return new SimpleMessage(type, groupId, sessionId);
}
}
}

View File

@@ -55,11 +55,7 @@ import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.api.clients.ProtocolEngine.StateUpdate;
import static org.briarproject.api.forum.ForumConstants.CONTACT_ID;
import static org.briarproject.api.forum.ForumConstants.FORUM_NAME;
import static org.briarproject.api.forum.ForumConstants.FORUM_SALT;
import static org.briarproject.api.forum.ForumConstants.FORUM_SALT_LENGTH;
import static org.briarproject.api.forum.ForumConstants.GROUP_ID;
import static org.briarproject.api.forum.ForumConstants.INVITATION_MSG;
import static org.briarproject.api.forum.ForumConstants.IS_SHARER;
import static org.briarproject.api.forum.ForumConstants.LOCAL;
import static org.briarproject.api.forum.ForumConstants.READ;
@@ -83,6 +79,8 @@ import static org.briarproject.api.forum.ForumConstants.TIME;
import static org.briarproject.api.forum.ForumConstants.TO_BE_SHARED_BY_US;
import static org.briarproject.api.forum.ForumConstants.TYPE;
import static org.briarproject.api.forum.ForumManager.RemoveForumHook;
import static org.briarproject.api.forum.ForumSharingMessage.BaseMessage;
import static org.briarproject.api.forum.ForumSharingMessage.Invitation;
import static org.briarproject.forum.ForumSharingSessionState.fromBdfDictionary;
import static org.briarproject.forum.SharerSessionState.Action;
@@ -178,11 +176,12 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook
@Override
protected void incomingMessage(Transaction txn, Message m, BdfList body,
BdfDictionary msg) throws DbException, FormatException {
BdfDictionary d) throws DbException, FormatException {
SessionId sessionId = new SessionId(msg.getRaw(SESSION_ID));
long type = msg.getLong(TYPE);
if (type == SHARE_MSG_TYPE_INVITATION) {
BaseMessage msg = BaseMessage.from(m.getGroupId(), d);
SessionId sessionId = msg.getSessionId();
if (msg.getType() == SHARE_MSG_TYPE_INVITATION) {
// we are an invitee who just received a new invitation
boolean stateExists = true;
try {
@@ -197,8 +196,9 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook
if (stateExists) throw new FormatException();
// check if forum can be shared
Forum f = forumFactory.createForum(msg.getString(FORUM_NAME),
msg.getRaw(FORUM_SALT));
Invitation invitation = (Invitation) msg;
Forum f = forumFactory.createForum(invitation.getForumName(),
invitation.getForumSalt());
ContactId contactId = getContactId(txn, m.getGroupId());
Contact contact = db.getContact(txn, contactId);
if (!canBeShared(txn, f.getId(), contact))
@@ -206,7 +206,7 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook
// initialize state and process invitation
InviteeSessionState state =
initializeInviteeState(txn, contactId, msg);
initializeInviteeState(txn, contactId, invitation);
InviteeEngine engine = new InviteeEngine(forumFactory);
processInviteeStateUpdate(txn, m.getId(),
engine.onMessageReceived(state, msg));
@@ -214,15 +214,15 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
deleteMessage(txn, m.getId());
}
} else if (type == SHARE_MSG_TYPE_ACCEPT ||
type == SHARE_MSG_TYPE_DECLINE) {
} else if (msg.getType() == SHARE_MSG_TYPE_ACCEPT ||
msg.getType() == SHARE_MSG_TYPE_DECLINE) {
// we are a sharer who just received a response
SharerSessionState state = getSessionStateForSharer(txn, sessionId);
SharerEngine engine = new SharerEngine();
processSharerStateUpdate(txn, m.getId(),
engine.onMessageReceived(state, msg));
} else if (type == SHARE_MSG_TYPE_LEAVE ||
type == SHARE_MSG_TYPE_ABORT) {
} else if (msg.getType() == SHARE_MSG_TYPE_LEAVE ||
msg.getType() == SHARE_MSG_TYPE_ABORT) {
// we don't know who we are, so figure it out
ForumSharingSessionState s = getSessionState(txn, sessionId, true);
if (s instanceof SharerSessionState) {
@@ -322,34 +322,33 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook
Map<MessageId, BdfDictionary> map = clientHelper
.getMessageMetadataAsDictionary(txn, group.getId());
for (Map.Entry<MessageId, BdfDictionary> m : map.entrySet()) {
BdfDictionary msg = m.getValue();
BdfDictionary d = m.getValue();
try {
if (msg.getLong(TYPE) != SHARE_MSG_TYPE_INVITATION)
if (d.getLong(TYPE) != SHARE_MSG_TYPE_INVITATION)
continue;
Invitation msg = Invitation.from(group.getId(), d);
MessageStatus status =
db.getMessageStatus(txn, contactId, m.getKey());
SessionId sessionId = new SessionId(msg.getRaw(SESSION_ID));
String name = msg.getString(FORUM_NAME);
String message = msg.getOptionalString(INVITATION_MSG);
long time = msg.getLong(TIME);
boolean local = msg.getBoolean(LOCAL);
boolean read = msg.getBoolean(READ, false);
long time = d.getLong(TIME);
boolean local = d.getBoolean(LOCAL);
boolean read = d.getBoolean(READ, false);
boolean available = false;
if (!local) {
// figure out whether the forum is still available
ForumSharingSessionState s =
getSessionState(txn, sessionId, true);
getSessionState(txn, msg.getSessionId(), true);
if (!(s instanceof InviteeSessionState))
continue;
available = ((InviteeSessionState) s).getState() ==
InviteeSessionState.State.AWAIT_LOCAL_RESPONSE;
}
ForumInvitationMessage im =
new ForumInvitationMessage(m.getKey(), sessionId,
contactId, name, message, available, time,
local, status.isSent(), status.isSeen(),
read);
new ForumInvitationMessage(m.getKey(),
msg.getSessionId(), contactId,
msg.getForumName(), msg.getMessage(),
available, time, local, status.isSent(),
status.isSeen(), read);
list.add(im);
} catch (FormatException e) {
if (LOG.isLoggable(WARNING))
@@ -508,13 +507,13 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook
}
private InviteeSessionState initializeInviteeState(Transaction txn,
ContactId contactId, BdfDictionary msg)
ContactId contactId, Invitation msg)
throws FormatException, DbException {
Contact c = db.getContact(txn, contactId);
Group group = getContactGroup(c);
String name = msg.getString(FORUM_NAME);
byte[] salt = msg.getRaw(FORUM_SALT);
String name = msg.getForumName();
byte[] salt = msg.getForumSalt();
Forum f = forumFactory.createForum(name, salt);
// create local message to keep engine state
@@ -524,11 +523,10 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook
Message m = clientHelper.createMessage(localGroup.getId(), now,
BdfList.of(mSalt));
SessionId sessionId = new SessionId(msg.getRaw(SESSION_ID));
InviteeSessionState s = new InviteeSessionState(sessionId, m.getId(),
group.getId(), InviteeSessionState.State.AWAIT_INVITATION,
contactId, f.getId(), f.getName(), f.getSalt());
InviteeSessionState s = new InviteeSessionState(msg.getSessionId(),
m.getId(), group.getId(),
InviteeSessionState.State.AWAIT_INVITATION, contactId,
f.getId(), f.getName(), f.getSalt());
// save local state to database
BdfDictionary d = s.toBdfDictionary();
@@ -646,7 +644,7 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook
}
private void processStateUpdate(Transaction txn, MessageId messageId,
StateUpdate<ForumSharingSessionState, BdfDictionary> result)
StateUpdate<ForumSharingSessionState, BaseMessage> result)
throws DbException, FormatException {
// perform actions based on new local state
@@ -658,8 +656,8 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook
result.localState.toBdfDictionary());
// send messages
for (BdfDictionary d : result.toSend) {
sendMessage(txn, d);
for (BaseMessage msg : result.toSend) {
sendMessage(txn, msg);
}
// broadcast events
@@ -678,11 +676,11 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook
}
private void processSharerStateUpdate(Transaction txn, MessageId messageId,
StateUpdate<SharerSessionState, BdfDictionary> result)
StateUpdate<SharerSessionState, BaseMessage> result)
throws DbException, FormatException {
StateUpdate<ForumSharingSessionState, BdfDictionary> r =
new StateUpdate<ForumSharingSessionState, BdfDictionary>(
StateUpdate<ForumSharingSessionState, BaseMessage> r =
new StateUpdate<ForumSharingSessionState, BaseMessage>(
result.deleteMessage, result.deleteState,
result.localState, result.toSend, result.toBroadcast);
@@ -690,11 +688,11 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook
}
private void processInviteeStateUpdate(Transaction txn, MessageId messageId,
StateUpdate<InviteeSessionState, BdfDictionary> result)
StateUpdate<InviteeSessionState, BaseMessage> result)
throws DbException, FormatException {
StateUpdate<ForumSharingSessionState, BdfDictionary> r =
new StateUpdate<ForumSharingSessionState, BdfDictionary>(
StateUpdate<ForumSharingSessionState, BaseMessage> r =
new StateUpdate<ForumSharingSessionState, BaseMessage>(
result.deleteMessage, result.deleteState,
result.localState, result.toSend, result.toBroadcast);
@@ -751,50 +749,23 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook
}
}
private void sendMessage(Transaction txn, BdfDictionary m)
private void sendMessage(Transaction txn, BaseMessage m)
throws FormatException, DbException {
BdfList list = encodeMessage(m);
byte[] body = clientHelper.toByteArray(list);
GroupId groupId = new GroupId(m.getRaw(GROUP_ID));
Group group = db.getGroup(txn, groupId);
byte[] body = clientHelper.toByteArray(m.toBdfList());
Group group = db.getGroup(txn, m.getGroupId());
long timestamp = clock.currentTimeMillis();
// add message itself as metadata
m.put(LOCAL, true);
m.put(TIME, timestamp);
Metadata meta = metadataEncoder.encode(m);
BdfDictionary d = m.toBdfDictionary();
d.put(LOCAL, true);
d.put(TIME, timestamp);
Metadata meta = metadataEncoder.encode(d);
messageQueueManager
.sendMessage(txn, group, timestamp, body, meta);
}
private BdfList encodeMessage(BdfDictionary m) throws FormatException {
long type = m.getLong(TYPE);
BdfList list;
if (type == SHARE_MSG_TYPE_INVITATION) {
list = BdfList.of(type,
m.getRaw(SESSION_ID),
m.getString(FORUM_NAME),
m.getRaw(FORUM_SALT)
);
String msg = m.getOptionalString(INVITATION_MSG);
if (msg != null) list.add(msg);
} else if (type == SHARE_MSG_TYPE_ACCEPT) {
list = BdfList.of(type, m.getRaw(SESSION_ID));
} else if (type == SHARE_MSG_TYPE_DECLINE) {
list = BdfList.of(type, m.getRaw(SESSION_ID));
} else if (type == SHARE_MSG_TYPE_LEAVE) {
list = BdfList.of(type, m.getRaw(SESSION_ID));
} else if (type == SHARE_MSG_TYPE_ABORT) {
list = BdfList.of(type, m.getRaw(SESSION_ID));
} else {
throw new FormatException();
}
return list;
}
private Group getContactGroup(Contact c) {
return privateGroupFactory.createPrivateGroup(CLIENT_ID, c);
}

View File

@@ -73,7 +73,6 @@ class ForumSharingValidator extends BdfMessageValidator {
// Return the metadata
d.put(TYPE, type);
d.put(SESSION_ID, id);
d.put(GROUP_ID, m.getGroupId());
d.put(LOCAL, false);
d.put(TIME, m.getTimestamp());
return d;

View File

@@ -3,22 +3,17 @@ package org.briarproject.forum;
import org.briarproject.api.FormatException;
import org.briarproject.api.clients.ProtocolEngine;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.data.BdfDictionary;
import org.briarproject.api.data.BdfEntry;
import org.briarproject.api.event.Event;
import org.briarproject.api.event.ForumInvitationReceivedEvent;
import org.briarproject.api.forum.Forum;
import org.briarproject.api.forum.ForumFactory;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.logging.Logger;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.api.forum.ForumConstants.GROUP_ID;
import static org.briarproject.api.forum.ForumConstants.SESSION_ID;
import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_ABORT;
import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_ACCEPT;
import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_DECLINE;
@@ -28,7 +23,8 @@ import static org.briarproject.api.forum.ForumConstants.TASK_ADD_FORUM_TO_LIST_S
import static org.briarproject.api.forum.ForumConstants.TASK_ADD_SHARED_FORUM;
import static org.briarproject.api.forum.ForumConstants.TASK_REMOVE_FORUM_FROM_LIST_SHARED_WITH_US;
import static org.briarproject.api.forum.ForumConstants.TASK_UNSHARE_FORUM_SHARED_WITH_US;
import static org.briarproject.api.forum.ForumConstants.TYPE;
import static org.briarproject.api.forum.ForumSharingMessage.SimpleMessage;
import static org.briarproject.api.forum.ForumSharingMessage.BaseMessage;
import static org.briarproject.forum.InviteeSessionState.Action;
import static org.briarproject.forum.InviteeSessionState.Action.LOCAL_ABORT;
import static org.briarproject.forum.InviteeSessionState.Action.LOCAL_ACCEPT;
@@ -42,7 +38,7 @@ import static org.briarproject.forum.InviteeSessionState.State.FINISHED;
import static org.briarproject.forum.InviteeSessionState.State.LEFT;
public class InviteeEngine
implements ProtocolEngine<Action, InviteeSessionState, BdfDictionary> {
implements ProtocolEngine<Action, InviteeSessionState, BaseMessage> {
private final ForumFactory forumFactory;
private static final Logger LOG =
@@ -53,7 +49,7 @@ public class InviteeEngine
}
@Override
public StateUpdate<InviteeSessionState, BdfDictionary> onLocalAction(
public StateUpdate<InviteeSessionState, BaseMessage> onLocalAction(
InviteeSessionState localState, Action action) {
try {
@@ -72,37 +68,34 @@ public class InviteeEngine
}
return noUpdate(localState, true);
}
List<BdfDictionary> messages;
List<BaseMessage> messages;
List<Event> events = Collections.emptyList();
if (action == LOCAL_ACCEPT || action == LOCAL_DECLINE) {
BdfDictionary msg = BdfDictionary.of(
new BdfEntry(SESSION_ID, localState.getSessionId()),
new BdfEntry(GROUP_ID, localState.getGroupId())
);
BaseMessage msg;
if (action == LOCAL_ACCEPT) {
localState.setTask(TASK_ADD_SHARED_FORUM);
msg.put(TYPE, SHARE_MSG_TYPE_ACCEPT);
msg = new SimpleMessage(SHARE_MSG_TYPE_ACCEPT,
localState.getGroupId(), localState.getSessionId());
} else {
localState.setTask(
TASK_REMOVE_FORUM_FROM_LIST_SHARED_WITH_US);
msg.put(TYPE, SHARE_MSG_TYPE_DECLINE);
msg = new SimpleMessage(SHARE_MSG_TYPE_DECLINE,
localState.getGroupId(), localState.getSessionId());
}
messages = Collections.singletonList(msg);
logLocalAction(currentState, localState, msg);
}
else if (action == LOCAL_LEAVE) {
BdfDictionary msg = new BdfDictionary();
msg.put(TYPE, SHARE_MSG_TYPE_LEAVE);
msg.put(SESSION_ID, localState.getSessionId());
msg.put(GROUP_ID, localState.getGroupId());
BaseMessage msg = new SimpleMessage(SHARE_MSG_TYPE_LEAVE,
localState.getGroupId(), localState.getSessionId());
messages = Collections.singletonList(msg);
logLocalAction(currentState, localState, msg);
}
else {
throw new IllegalArgumentException("Unknown Local Action");
}
return new StateUpdate<InviteeSessionState, BdfDictionary>(false,
return new StateUpdate<InviteeSessionState, BaseMessage>(false,
false, localState, messages, events);
} catch (FormatException e) {
throw new IllegalArgumentException(e);
@@ -110,17 +103,16 @@ public class InviteeEngine
}
@Override
public StateUpdate<InviteeSessionState, BdfDictionary> onMessageReceived(
InviteeSessionState localState, BdfDictionary msg) {
public StateUpdate<InviteeSessionState, BaseMessage> onMessageReceived(
InviteeSessionState localState, BaseMessage msg) {
try {
State currentState = localState.getState();
long type = msg.getLong(TYPE);
Action action = Action.getRemote(type);
Action action = Action.getRemote(msg.getType());
State nextState = currentState.next(action);
localState.setState(nextState);
logMessageReceived(currentState, nextState, type, msg);
logMessageReceived(currentState, nextState, msg.getType(), msg);
if (nextState == ERROR) {
if (currentState != ERROR) {
@@ -130,7 +122,7 @@ public class InviteeEngine
}
}
List<BdfDictionary> messages = Collections.emptyList();
List<BaseMessage> messages = Collections.emptyList();
List<Event> events = Collections.emptyList();
boolean deleteMsg = false;
@@ -164,7 +156,7 @@ public class InviteeEngine
else {
throw new IllegalArgumentException("Bad state");
}
return new StateUpdate<InviteeSessionState, BdfDictionary>(deleteMsg,
return new StateUpdate<InviteeSessionState, BaseMessage>(deleteMsg,
false, localState, messages, events);
} catch (FormatException e) {
throw new IllegalArgumentException(e);
@@ -172,50 +164,42 @@ public class InviteeEngine
}
private void logLocalAction(State state,
InviteeSessionState localState, BdfDictionary msg) {
InviteeSessionState localState, BaseMessage msg) {
if (!LOG.isLoggable(INFO)) return;
String a = "response";
if (msg.getLong(TYPE, -1L) == SHARE_MSG_TYPE_LEAVE) a = "leave";
if (msg.getType() == SHARE_MSG_TYPE_LEAVE) a = "leave";
try {
LOG.info("Sending " + a + " in state " + state.name() +
" with session ID " +
Arrays.hashCode(msg.getRaw(SESSION_ID)) + " in group " +
Arrays.hashCode(msg.getRaw(GROUP_ID)) + ". " +
"Moving on to state " + localState.getState().name()
);
} catch (FormatException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
}
LOG.info("Sending " + a + " in state " + state.name() +
" with session ID " +
msg.getSessionId().hashCode() + " in group " +
msg.getGroupId().hashCode() + ". " +
"Moving on to state " + localState.getState().name()
);
}
private void logMessageReceived(State currentState, State nextState,
long type, BdfDictionary msg) {
long type, BaseMessage msg) {
if (!LOG.isLoggable(INFO)) return;
try {
String t = "unknown";
if (type == SHARE_MSG_TYPE_INVITATION) t = "INVITE";
else if (type == SHARE_MSG_TYPE_LEAVE) t = "LEAVE";
else if (type == SHARE_MSG_TYPE_ABORT) t = "ABORT";
String t = "unknown";
if (type == SHARE_MSG_TYPE_INVITATION) t = "INVITE";
else if (type == SHARE_MSG_TYPE_LEAVE) t = "LEAVE";
else if (type == SHARE_MSG_TYPE_ABORT) t = "ABORT";
LOG.info("Received " + t + " in state " + currentState.name() +
" with session ID " +
Arrays.hashCode(msg.getRaw(SESSION_ID)) + " in group " +
Arrays.hashCode(msg.getRaw(GROUP_ID)) + ". " +
"Moving on to state " + nextState.name()
);
} catch (FormatException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
}
LOG.info("Received " + t + " in state " + currentState.name() +
" with session ID " +
msg.getSessionId().hashCode() + " in group " +
msg.getGroupId().hashCode() + ". " +
"Moving on to state " + nextState.name()
);
}
@Override
public StateUpdate<InviteeSessionState, BdfDictionary> onMessageDelivered(
InviteeSessionState localState, BdfDictionary delivered) {
public StateUpdate<InviteeSessionState, BaseMessage> onMessageDelivered(
InviteeSessionState localState, BaseMessage delivered) {
try {
return noUpdate(localState, false);
} catch (FormatException e) {
@@ -224,7 +208,7 @@ public class InviteeEngine
}
}
private StateUpdate<InviteeSessionState, BdfDictionary> abortSession(
private StateUpdate<InviteeSessionState, BaseMessage> abortSession(
State currentState, InviteeSessionState localState)
throws FormatException {
@@ -233,25 +217,23 @@ public class InviteeEngine
localState.getSessionId().hashCode() +
" in state " + currentState.name());
}
localState.setState(ERROR);
BdfDictionary msg = new BdfDictionary();
msg.put(TYPE, SHARE_MSG_TYPE_ABORT);
msg.put(SESSION_ID, localState.getSessionId());
msg.put(GROUP_ID, localState.getGroupId());
List<BdfDictionary> messages = Collections.singletonList(msg);
BaseMessage msg =
new SimpleMessage(SHARE_MSG_TYPE_ABORT, localState.getGroupId(),
localState.getSessionId());
List<BaseMessage> messages = Collections.singletonList(msg);
List<Event> events = Collections.emptyList();
return new StateUpdate<InviteeSessionState, BdfDictionary>(false, false,
return new StateUpdate<InviteeSessionState, BaseMessage>(false, false,
localState, messages, events);
}
private StateUpdate<InviteeSessionState, BdfDictionary> noUpdate(
private StateUpdate<InviteeSessionState, BaseMessage> noUpdate(
InviteeSessionState localState, boolean delete) throws FormatException {
return new StateUpdate<InviteeSessionState, BdfDictionary>(delete, false,
localState, Collections.<BdfDictionary>emptyList(),
return new StateUpdate<InviteeSessionState, BaseMessage>(delete, false,
localState, Collections.<BaseMessage>emptyList(),
Collections.<Event>emptyList());
}
}

View File

@@ -3,33 +3,27 @@ package org.briarproject.forum;
import org.briarproject.api.FormatException;
import org.briarproject.api.clients.ProtocolEngine;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.data.BdfDictionary;
import org.briarproject.api.event.Event;
import org.briarproject.api.event.ForumInvitationResponseReceivedEvent;
import static org.briarproject.forum.SharerSessionState.Action;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.logging.Logger;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.api.forum.ForumConstants.FORUM_NAME;
import static org.briarproject.api.forum.ForumConstants.FORUM_SALT;
import static org.briarproject.api.forum.ForumConstants.GROUP_ID;
import static org.briarproject.api.forum.ForumConstants.INVITATION_MSG;
import static org.briarproject.api.forum.ForumConstants.SESSION_ID;
import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_ABORT;
import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_ACCEPT;
import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_DECLINE;
import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_INVITATION;
import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_LEAVE;
import static org.briarproject.api.forum.ForumConstants.TASK_ADD_FORUM_TO_LIST_TO_BE_SHARED_BY_US;
import static org.briarproject.api.forum.ForumConstants.TASK_REMOVE_FORUM_FROM_LIST_TO_BE_SHARED_BY_US;
import static org.briarproject.api.forum.ForumConstants.TASK_SHARE_FORUM;
import static org.briarproject.api.forum.ForumConstants.TASK_UNSHARE_FORUM_SHARED_BY_US;
import static org.briarproject.api.forum.ForumConstants.TYPE;
import static org.briarproject.api.forum.ForumSharingMessage.BaseMessage;
import static org.briarproject.api.forum.ForumSharingMessage.Invitation;
import static org.briarproject.api.forum.ForumSharingMessage.SimpleMessage;
import static org.briarproject.forum.SharerSessionState.Action;
import static org.briarproject.forum.SharerSessionState.Action.LOCAL_ABORT;
import static org.briarproject.forum.SharerSessionState.Action.LOCAL_INVITATION;
import static org.briarproject.forum.SharerSessionState.Action.LOCAL_LEAVE;
@@ -42,13 +36,13 @@ import static org.briarproject.forum.SharerSessionState.State.FINISHED;
import static org.briarproject.forum.SharerSessionState.State.LEFT;
public class SharerEngine
implements ProtocolEngine<Action, SharerSessionState, BdfDictionary> {
implements ProtocolEngine<Action, SharerSessionState, BaseMessage> {
private static final Logger LOG =
Logger.getLogger(SharerEngine.class.getName());
@Override
public StateUpdate<SharerSessionState, BdfDictionary> onLocalAction(
public StateUpdate<SharerSessionState, BaseMessage> onLocalAction(
SharerSessionState localState, Action action) {
try {
@@ -67,19 +61,13 @@ public class SharerEngine
}
return noUpdate(localState, true);
}
List<BdfDictionary> messages;
List<BaseMessage> messages;
List<Event> events = Collections.emptyList();
if (action == LOCAL_INVITATION) {
BdfDictionary msg = new BdfDictionary();
msg.put(TYPE, SHARE_MSG_TYPE_INVITATION);
msg.put(SESSION_ID, localState.getSessionId());
msg.put(GROUP_ID, localState.getGroupId());
msg.put(FORUM_NAME, localState.getForumName());
msg.put(FORUM_SALT, localState.getForumSalt());
if (localState.getMessage() != null) {
msg.put(INVITATION_MSG, localState.getMessage());
}
BaseMessage msg = new Invitation(localState.getGroupId(),
localState.getSessionId(), localState.getForumName(),
localState.getForumSalt(), localState.getMessage());
messages = Collections.singletonList(msg);
logLocalAction(currentState, nextState, msg);
@@ -87,17 +75,15 @@ public class SharerEngine
localState.setTask(TASK_ADD_FORUM_TO_LIST_TO_BE_SHARED_BY_US);
}
else if (action == LOCAL_LEAVE) {
BdfDictionary msg = new BdfDictionary();
msg.put(TYPE, SHARE_MSG_TYPE_LEAVE);
msg.put(SESSION_ID, localState.getSessionId());
msg.put(GROUP_ID, localState.getGroupId());
BaseMessage msg = new SimpleMessage(SHARE_MSG_TYPE_LEAVE,
localState.getGroupId(), localState.getSessionId());
messages = Collections.singletonList(msg);
logLocalAction(currentState, nextState, msg);
}
else {
throw new IllegalArgumentException("Unknown Local Action");
}
return new StateUpdate<SharerSessionState, BdfDictionary>(false,
return new StateUpdate<SharerSessionState, BaseMessage>(false,
false, localState, messages, events);
} catch (FormatException e) {
throw new IllegalArgumentException(e);
@@ -105,17 +91,16 @@ public class SharerEngine
}
@Override
public StateUpdate<SharerSessionState, BdfDictionary> onMessageReceived(
SharerSessionState localState, BdfDictionary msg) {
public StateUpdate<SharerSessionState, BaseMessage> onMessageReceived(
SharerSessionState localState, BaseMessage msg) {
try {
State currentState = localState.getState();
long type = msg.getLong(TYPE);
Action action = Action.getRemote(type);
Action action = Action.getRemote(msg.getType());
State nextState = currentState.next(action);
localState.setState(nextState);
logMessageReceived(currentState, nextState, type, msg);
logMessageReceived(currentState, nextState, msg.getType(), msg);
if (nextState == ERROR) {
if (currentState != ERROR) {
@@ -124,7 +109,7 @@ public class SharerEngine
return noUpdate(localState, true);
}
}
List<BdfDictionary> messages = Collections.emptyList();
List<BaseMessage> messages = Collections.emptyList();
List<Event> events = Collections.emptyList();
boolean deleteMsg = false;
@@ -157,7 +142,7 @@ public class SharerEngine
else {
throw new IllegalArgumentException("Bad state");
}
return new StateUpdate<SharerSessionState, BdfDictionary>(deleteMsg,
return new StateUpdate<SharerSessionState, BaseMessage>(deleteMsg,
false, localState, messages, events);
} catch (FormatException e) {
throw new IllegalArgumentException(e);
@@ -165,51 +150,43 @@ public class SharerEngine
}
private void logLocalAction(State currentState, State nextState,
BdfDictionary msg) {
BaseMessage msg) {
if (!LOG.isLoggable(INFO)) return;
String a = "invitation";
if (msg.getLong(TYPE, -1L) == SHARE_MSG_TYPE_LEAVE) a = "leave";
if (msg.getType() == SHARE_MSG_TYPE_LEAVE) a = "leave";
try {
LOG.info("Sending " + a + " in state " + currentState.name() +
" with session ID " +
Arrays.hashCode(msg.getRaw(SESSION_ID)) + " in group " +
Arrays.hashCode(msg.getRaw(GROUP_ID)) + ". " +
"Moving on to state " + nextState.name()
);
} catch (FormatException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
}
LOG.info("Sending " + a + " in state " + currentState.name() +
" with session ID " +
msg.getSessionId().hashCode() + " in group " +
msg.getGroupId().hashCode() + ". " +
"Moving on to state " + nextState.name()
);
}
private void logMessageReceived(State currentState, State nextState,
long type, BdfDictionary msg) {
long type, BaseMessage msg) {
if (!LOG.isLoggable(INFO)) return;
try {
String t = "unknown";
if (type == SHARE_MSG_TYPE_ACCEPT) t = "ACCEPT";
else if (type == SHARE_MSG_TYPE_DECLINE) t = "DECLINE";
else if (type == SHARE_MSG_TYPE_LEAVE) t = "LEAVE";
else if (type == SHARE_MSG_TYPE_ABORT) t = "ABORT";
String t = "unknown";
if (type == SHARE_MSG_TYPE_ACCEPT) t = "ACCEPT";
else if (type == SHARE_MSG_TYPE_DECLINE) t = "DECLINE";
else if (type == SHARE_MSG_TYPE_LEAVE) t = "LEAVE";
else if (type == SHARE_MSG_TYPE_ABORT) t = "ABORT";
LOG.info("Received " + t + " in state " + currentState.name() +
" with session ID " +
Arrays.hashCode(msg.getRaw(SESSION_ID)) + " in group " +
Arrays.hashCode(msg.getRaw(GROUP_ID)) + ". " +
"Moving on to state " + nextState.name()
);
} catch (FormatException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
}
LOG.info("Received " + t + " in state " + currentState.name() +
" with session ID " +
msg.getSessionId().hashCode() + " in group " +
msg.getGroupId().hashCode() + ". " +
"Moving on to state " + nextState.name()
);
}
@Override
public StateUpdate<SharerSessionState, BdfDictionary> onMessageDelivered(
SharerSessionState localState, BdfDictionary delivered) {
public StateUpdate<SharerSessionState, BaseMessage> onMessageDelivered(
SharerSessionState localState, BaseMessage delivered) {
try {
return noUpdate(localState, false);
} catch (FormatException e) {
@@ -218,7 +195,7 @@ public class SharerEngine
}
}
private StateUpdate<SharerSessionState, BdfDictionary> abortSession(
private StateUpdate<SharerSessionState, BaseMessage> abortSession(
State currentState, SharerSessionState localState)
throws FormatException {
@@ -229,24 +206,22 @@ public class SharerEngine
}
localState.setState(ERROR);
BdfDictionary msg = new BdfDictionary();
msg.put(TYPE, SHARE_MSG_TYPE_ABORT);
msg.put(SESSION_ID, localState.getSessionId());
msg.put(GROUP_ID, localState.getGroupId());
List<BdfDictionary> messages = Collections.singletonList(msg);
BaseMessage msg = new SimpleMessage(SHARE_MSG_TYPE_ABORT,
localState.getGroupId(), localState.getSessionId());
List<BaseMessage> messages = Collections.singletonList(msg);
List<Event> events = Collections.emptyList();
return new StateUpdate<SharerSessionState, BdfDictionary>(false, false,
return new StateUpdate<SharerSessionState, BaseMessage>(false, false,
localState, messages, events);
}
private StateUpdate<SharerSessionState, BdfDictionary> noUpdate(
private StateUpdate<SharerSessionState, BaseMessage> noUpdate(
SharerSessionState localState, boolean delete)
throws FormatException {
return new StateUpdate<SharerSessionState, BdfDictionary>(delete, false,
localState, Collections.<BdfDictionary>emptyList(),
return new StateUpdate<SharerSessionState, BaseMessage>(delete, false,
localState, Collections.<BaseMessage>emptyList(),
Collections.<Event>emptyList());
}