mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-21 22:17:53 +00:00
MeshMS Java API: mark messages as read
This commit is contained in:
parent
7736a4ceb1
commit
c79a382a27
@ -147,13 +147,16 @@ public class JSONTokeniser {
|
||||
if (tok instanceof Token)
|
||||
throw new UnexpectedTokenException(tok, cls);
|
||||
// Convert:
|
||||
// Integer --> Float or Double
|
||||
// Integer --> Long or Float or Double
|
||||
// Long --> Float or Double
|
||||
// Float --> Double
|
||||
// Double --> Float
|
||||
if (cls == Double.class && (tok instanceof Float || tok instanceof Integer))
|
||||
if (cls == Double.class && (tok instanceof Float || tok instanceof Long || tok instanceof Integer))
|
||||
tok = new Double(((Number)tok).doubleValue());
|
||||
else if (cls == Float.class && (tok instanceof Double || tok instanceof Integer))
|
||||
else if (cls == Float.class && (tok instanceof Double || tok instanceof Long || tok instanceof Integer))
|
||||
tok = new Float(((Number)tok).floatValue());
|
||||
else if (cls == Long.class && tok instanceof Integer)
|
||||
tok = new Long(((Number)tok).longValue());
|
||||
if (cls.isInstance(tok))
|
||||
return (T)tok; // unchecked cast
|
||||
throw new UnexpectedTokenException(tok, cls);
|
||||
@ -239,7 +242,12 @@ public class JSONTokeniser {
|
||||
|
||||
public static boolean jsonIsToken(Object tok)
|
||||
{
|
||||
return tok instanceof Token || tok instanceof String || tok instanceof Double || tok instanceof Integer || tok instanceof Boolean;
|
||||
return tok instanceof Token
|
||||
|| tok instanceof String
|
||||
|| tok instanceof Double
|
||||
|| tok instanceof Long
|
||||
|| tok instanceof Integer
|
||||
|| tok instanceof Boolean;
|
||||
}
|
||||
|
||||
public static String jsonTokenDescription(Object tok)
|
||||
@ -247,7 +255,7 @@ public class JSONTokeniser {
|
||||
if (tok == null)
|
||||
return "null";
|
||||
if (tok instanceof String)
|
||||
return "\"" + tok + "\"";
|
||||
return "\"" + ((String)tok).replace("\\", "\\\\").replace("\"", "\\\"") + "\"";
|
||||
if (tok instanceof Number)
|
||||
return "" + tok;
|
||||
if (tok instanceof Boolean)
|
||||
@ -272,6 +280,7 @@ public class JSONTokeniser {
|
||||
|
||||
private int readHex(int digits) throws SyntaxException, IOException
|
||||
{
|
||||
assert digits <= 8;
|
||||
char[] buf = new char[digits];
|
||||
int len = 0;
|
||||
while (len < buf.length) {
|
||||
@ -285,8 +294,8 @@ public class JSONTokeniser {
|
||||
return Integer.valueOf(hex, 16);
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
throw new SyntaxException("expecting " + digits + " hex digits, got \"" + hex + "\"");
|
||||
}
|
||||
throw new SyntaxException("expecting " + digits + " hex digits, got \"" + hex + "\"");
|
||||
}
|
||||
|
||||
public void pushToken(Object tok)
|
||||
@ -438,8 +447,14 @@ public class JSONTokeniser {
|
||||
try {
|
||||
if (isfloat)
|
||||
return Double.parseDouble(number);
|
||||
else
|
||||
return Integer.parseInt(number);
|
||||
else {
|
||||
try {
|
||||
return Integer.parseInt(number);
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
}
|
||||
return Long.parseLong(number);
|
||||
}
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
throw new SyntaxException("malformed JSON number: " + number);
|
||||
|
@ -77,6 +77,21 @@ public class ServalDClient implements ServalDHttpConnectionFactory
|
||||
return MeshMSCommon.sendMessage(this, sid1, sid2, text);
|
||||
}
|
||||
|
||||
public MeshMSStatus meshmsMarkAllConversationsRead(SubscriberId sid1) throws IOException, ServalDInterfaceException, MeshMSException
|
||||
{
|
||||
return MeshMSCommon.markAllConversationsRead(this, sid1);
|
||||
}
|
||||
|
||||
public MeshMSStatus meshmsMarkAllMessagesRead(SubscriberId sid1, SubscriberId sid2) throws IOException, ServalDInterfaceException, MeshMSException
|
||||
{
|
||||
return MeshMSCommon.markAllMessagesRead(this, sid1, sid2);
|
||||
}
|
||||
|
||||
public MeshMSStatus meshmsAdvanceReadOffset(SubscriberId sid1, SubscriberId sid2, long offset) throws IOException, ServalDInterfaceException, MeshMSException
|
||||
{
|
||||
return MeshMSCommon.advanceReadOffset(this, sid1, sid2, offset);
|
||||
}
|
||||
|
||||
// interface ServalDHttpConnectionFactory
|
||||
public HttpURLConnection newServalDHttpConnection(String path) throws ServalDInterfaceException, IOException
|
||||
{
|
||||
|
@ -36,6 +36,12 @@ import org.servalproject.json.JSONInputException;
|
||||
public class MeshMSCommon
|
||||
{
|
||||
protected static JSONTokeniser receiveRestfulResponse(HttpURLConnection conn, int expected_response_code) throws IOException, ServalDInterfaceException, MeshMSException
|
||||
{
|
||||
int[] expected_response_codes = { expected_response_code };
|
||||
return receiveRestfulResponse(conn, expected_response_codes);
|
||||
}
|
||||
|
||||
protected static JSONTokeniser receiveRestfulResponse(HttpURLConnection conn, int[] expected_response_codes) throws IOException, ServalDInterfaceException, MeshMSException
|
||||
{
|
||||
if (!conn.getContentType().equals("application/json"))
|
||||
throw new ServalDInterfaceException("unexpected HTTP Content-Type: " + conn.getContentType());
|
||||
@ -45,10 +51,13 @@ public class MeshMSCommon
|
||||
throwRestfulResponseExceptions(status, conn.getURL());
|
||||
throw new ServalDInterfaceException("unexpected MeshMS status = " + status.meshms_status + ", \"" + status.message + "\"");
|
||||
}
|
||||
if (conn.getResponseCode() != expected_response_code)
|
||||
throw new ServalDInterfaceException("unexpected HTTP response code: " + conn.getResponseCode());
|
||||
JSONTokeniser json = new JSONTokeniser(new InputStreamReader(conn.getInputStream(), "US-ASCII"));
|
||||
return json;
|
||||
for (int code: expected_response_codes) {
|
||||
if (conn.getResponseCode() == code) {
|
||||
JSONTokeniser json = new JSONTokeniser(new InputStreamReader(conn.getInputStream(), "US-ASCII"));
|
||||
return json;
|
||||
}
|
||||
}
|
||||
throw new ServalDInterfaceException("unexpected HTTP response code: " + conn.getResponseCode());
|
||||
}
|
||||
|
||||
private static class Status {
|
||||
@ -119,4 +128,40 @@ public class MeshMSCommon
|
||||
return status.meshms_status;
|
||||
}
|
||||
|
||||
public static MeshMSStatus markAllConversationsRead(ServalDHttpConnectionFactory connector, SubscriberId sid1) throws IOException, ServalDInterfaceException, MeshMSException
|
||||
{
|
||||
HttpURLConnection conn = connector.newServalDHttpConnection("/restful/meshms/" + sid1.toHex() + "/readall");
|
||||
conn.setRequestMethod("POST");
|
||||
conn.connect();
|
||||
int[] expected_response_codes = { HttpURLConnection.HTTP_OK, HttpURLConnection.HTTP_CREATED };
|
||||
JSONTokeniser json = MeshMSCommon.receiveRestfulResponse(conn, expected_response_codes);
|
||||
Status status = decodeRestfulStatus(json);
|
||||
throwRestfulResponseExceptions(status, conn.getURL());
|
||||
return status.meshms_status;
|
||||
}
|
||||
|
||||
public static MeshMSStatus markAllMessagesRead(ServalDHttpConnectionFactory connector, SubscriberId sid1, SubscriberId sid2) throws IOException, ServalDInterfaceException, MeshMSException
|
||||
{
|
||||
HttpURLConnection conn = connector.newServalDHttpConnection("/restful/meshms/" + sid1.toHex() + "/" + sid2.toHex() + "/readall");
|
||||
conn.setRequestMethod("POST");
|
||||
conn.connect();
|
||||
int[] expected_response_codes = { HttpURLConnection.HTTP_OK, HttpURLConnection.HTTP_CREATED };
|
||||
JSONTokeniser json = MeshMSCommon.receiveRestfulResponse(conn, expected_response_codes);
|
||||
Status status = decodeRestfulStatus(json);
|
||||
throwRestfulResponseExceptions(status, conn.getURL());
|
||||
return status.meshms_status;
|
||||
}
|
||||
|
||||
public static MeshMSStatus advanceReadOffset(ServalDHttpConnectionFactory connector, SubscriberId sid1, SubscriberId sid2, long offset) throws IOException, ServalDInterfaceException, MeshMSException
|
||||
{
|
||||
HttpURLConnection conn = connector.newServalDHttpConnection("/restful/meshms/" + sid1.toHex() + "/" + sid2.toHex() + "/recv/" + offset + "/read");
|
||||
conn.setRequestMethod("POST");
|
||||
conn.connect();
|
||||
int[] expected_response_codes = { HttpURLConnection.HTTP_OK, HttpURLConnection.HTTP_CREATED };
|
||||
JSONTokeniser json = MeshMSCommon.receiveRestfulResponse(conn, expected_response_codes);
|
||||
Status status = decodeRestfulStatus(json);
|
||||
throwRestfulResponseExceptions(status, conn.getURL());
|
||||
return status.meshms_status;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -35,23 +35,23 @@ public class MeshMSMessage {
|
||||
public final Type type;
|
||||
public final SubscriberId mySid;
|
||||
public final SubscriberId theirSid;
|
||||
public final int offset;
|
||||
public final long offset;
|
||||
public final String token;
|
||||
public final String text;
|
||||
public final boolean isDelivered;
|
||||
public final boolean isRead;
|
||||
public final Integer ackOffset;
|
||||
public final Long ackOffset;
|
||||
|
||||
protected MeshMSMessage(int rowNumber,
|
||||
Type type,
|
||||
SubscriberId my_sid,
|
||||
SubscriberId their_sid,
|
||||
int offset,
|
||||
long offset,
|
||||
String token,
|
||||
String text,
|
||||
boolean delivered,
|
||||
boolean read,
|
||||
Integer ack_offset) throws ServalDInterfaceException
|
||||
Long ack_offset) throws ServalDInterfaceException
|
||||
{
|
||||
if (my_sid == null)
|
||||
throw new ServalDInterfaceException("my_sid is null");
|
||||
|
@ -38,8 +38,8 @@ public class MeshMSMessageList {
|
||||
private SubscriberId their_sid;
|
||||
private HttpURLConnection httpConnection;
|
||||
private JSONTokeniser json;
|
||||
private int readOffset;
|
||||
private int latestAckOffset;
|
||||
private long readOffset;
|
||||
private long latestAckOffset;
|
||||
private Vector<String> headers;
|
||||
private int columnIndex_type;
|
||||
private int columnIndex_my_sid;
|
||||
@ -84,11 +84,11 @@ public class MeshMSMessageList {
|
||||
json.consume(JSONTokeniser.Token.START_OBJECT);
|
||||
json.consume("read_offset");
|
||||
json.consume(JSONTokeniser.Token.COLON);
|
||||
readOffset = json.consume(Integer.class);
|
||||
readOffset = json.consume(Long.class);
|
||||
json.consume(JSONTokeniser.Token.COMMA);
|
||||
json.consume("latest_ack_offset");
|
||||
json.consume(JSONTokeniser.Token.COLON);
|
||||
latestAckOffset = json.consume(Integer.class);
|
||||
latestAckOffset = json.consume(Long.class);
|
||||
json.consume(JSONTokeniser.Token.COMMA);
|
||||
json.consume("header");
|
||||
json.consume(JSONTokeniser.Token.COLON);
|
||||
@ -145,13 +145,13 @@ public class MeshMSMessageList {
|
||||
}
|
||||
}
|
||||
|
||||
public int getReadOffset()
|
||||
public long getReadOffset()
|
||||
{
|
||||
assert json != null;
|
||||
return readOffset;
|
||||
}
|
||||
|
||||
public int getLatestAckOffset()
|
||||
public long getLatestAckOffset()
|
||||
{
|
||||
assert json != null;
|
||||
return latestAckOffset;
|
||||
@ -188,12 +188,12 @@ public class MeshMSMessageList {
|
||||
catch (SubscriberId.InvalidHexException e) {
|
||||
throw new ServalDInterfaceException("invalid column value: their_sid", e);
|
||||
}
|
||||
int offset = JSONTokeniser.narrow(row[columnIndex_offset], Integer.class);
|
||||
long offset = JSONTokeniser.narrow(row[columnIndex_offset], Long.class);
|
||||
String token = JSONTokeniser.narrow(row[columnIndex_token], String.class);
|
||||
String text = JSONTokeniser.narrow(row[columnIndex_text], String.class, JSONTokeniser.Narrow.ALLOW_NULL);
|
||||
boolean is_delivered = JSONTokeniser.narrow(row[columnIndex_delivered], Boolean.class);
|
||||
boolean is_read = JSONTokeniser.narrow(row[columnIndex_read], Boolean.class);
|
||||
Integer ack_offset = JSONTokeniser.narrow(row[columnIndex_ack_offset], Integer.class, JSONTokeniser.Narrow.ALLOW_NULL);
|
||||
Long ack_offset = JSONTokeniser.narrow(row[columnIndex_ack_offset], Long.class, JSONTokeniser.Narrow.ALLOW_NULL);
|
||||
MeshMSMessage.Type type;
|
||||
if (typesym.equals(">"))
|
||||
type = MeshMSMessage.Type.MESSAGE_SENT;
|
||||
|
@ -107,6 +107,45 @@ public class Meshms {
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
static void meshms_mark_all_conversations_read(SubscriberId sid1) throws ServalDInterfaceException, IOException, InterruptedException
|
||||
{
|
||||
ServalDClient client = new ServerControl().getRestfulClient();
|
||||
try {
|
||||
MeshMSStatus status = client.meshmsMarkAllConversationsRead(sid1);
|
||||
System.out.println("" + status);
|
||||
}
|
||||
catch (MeshMSException e) {
|
||||
System.out.println(e.toString());
|
||||
}
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
static void meshms_mark_all_messages_read(SubscriberId sid1, SubscriberId sid2) throws ServalDInterfaceException, IOException, InterruptedException
|
||||
{
|
||||
ServalDClient client = new ServerControl().getRestfulClient();
|
||||
try {
|
||||
MeshMSStatus status = client.meshmsMarkAllMessagesRead(sid1, sid2);
|
||||
System.out.println("" + status);
|
||||
}
|
||||
catch (MeshMSException e) {
|
||||
System.out.println(e.toString());
|
||||
}
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
static void meshms_advance_read_offset(SubscriberId sid1, SubscriberId sid2, long offset) throws ServalDInterfaceException, IOException, InterruptedException
|
||||
{
|
||||
ServalDClient client = new ServerControl().getRestfulClient();
|
||||
try {
|
||||
MeshMSStatus status = client.meshmsAdvanceReadOffset(sid1, sid2, offset);
|
||||
System.out.println("" + status);
|
||||
}
|
||||
catch (MeshMSException e) {
|
||||
System.out.println(e.toString());
|
||||
}
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
public static void main(String... args)
|
||||
{
|
||||
if (args.length < 1)
|
||||
@ -119,6 +158,12 @@ public class Meshms {
|
||||
meshms_list_messages(new SubscriberId(args[1]), new SubscriberId(args[2]));
|
||||
else if (methodName.equals("meshms-send-message"))
|
||||
meshms_send_message(new SubscriberId(args[1]), new SubscriberId(args[2]), args[3]);
|
||||
else if (methodName.equals("meshms-mark-all-conversations-read"))
|
||||
meshms_mark_all_conversations_read(new SubscriberId(args[1]));
|
||||
else if (methodName.equals("meshms-mark-all-messages-read"))
|
||||
meshms_mark_all_messages_read(new SubscriberId(args[1]), new SubscriberId(args[2]));
|
||||
else if (methodName.equals("meshms-advance-read-offset"))
|
||||
meshms_advance_read_offset(new SubscriberId(args[1]), new SubscriberId(args[2]), Long.parseLong(args[3]));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
|
@ -163,4 +163,70 @@ test_MeshmsSendNoIdentity() {
|
||||
tfw_cat --stdout --stderr
|
||||
}
|
||||
|
||||
doc_MeshmsReadAllConversations="Java API MeshMS mark all conversations read"
|
||||
setup_MeshmsReadAllConversations() {
|
||||
setup
|
||||
# create 3 threads, with all permutations of incoming and outgoing messages
|
||||
executeOk_servald meshms send message $SIDA1 $SIDA2 "Message1"
|
||||
executeOk_servald meshms send message $SIDA3 $SIDA1 "Message2"
|
||||
executeOk_servald meshms send message $SIDA1 $SIDA4 "Message3"
|
||||
executeOk_servald meshms send message $SIDA4 $SIDA1 "Message4"
|
||||
executeOk_servald meshms list conversations $SIDA1
|
||||
assertStdoutGrep --stderr --matches=1 ":$SIDA2::0:0\$"
|
||||
assertStdoutGrep --stderr --matches=1 ":$SIDA3:unread:11:0\$"
|
||||
assertStdoutGrep --stderr --matches=1 ":$SIDA4:unread:14:0\$"
|
||||
}
|
||||
test_MeshmsReadAllConversations() {
|
||||
executeJavaOk org.servalproject.test.Meshms meshms-mark-all-conversations-read $SIDA1
|
||||
assertStdoutIs -e 'UPDATED\n'
|
||||
executeOk_servald meshms list conversations $SIDA1
|
||||
assertStdoutGrep --stderr --matches=1 ":$SIDA2::0:0\$"
|
||||
assertStdoutGrep --stderr --matches=1 ":$SIDA3::11:11\$"
|
||||
assertStdoutGrep --stderr --matches=1 ":$SIDA4::14:14\$"
|
||||
}
|
||||
|
||||
doc_MeshmsReadAllMessages="Java API MeshMS mark all conversations read"
|
||||
setup_MeshmsReadAllMessages() {
|
||||
setup
|
||||
# create 3 threads, with all permutations of incoming and outgoing messages
|
||||
executeOk_servald meshms send message $SIDA1 $SIDA2 "Message1"
|
||||
executeOk_servald meshms send message $SIDA3 $SIDA1 "Message2"
|
||||
executeOk_servald meshms send message $SIDA1 $SIDA2 "Message3"
|
||||
executeOk_servald meshms send message $SIDA1 $SIDA4 "Message4"
|
||||
executeOk_servald meshms send message $SIDA4 $SIDA1 "Message5"
|
||||
executeOk_servald meshms send message $SIDA1 $SIDA2 "Message6"
|
||||
executeOk_servald meshms list conversations $SIDA2
|
||||
assertStdoutGrep --stderr --matches=1 ":$SIDA1:unread:33:0\$"
|
||||
}
|
||||
test_MeshmsReadAllMessages() {
|
||||
executeJavaOk org.servalproject.test.Meshms meshms-mark-all-messages-read $SIDA2 $SIDA1
|
||||
assertStdoutIs -e 'UPDATED\n'
|
||||
executeOk_servald meshms list conversations $SIDA2
|
||||
assertStdoutGrep --stderr --matches=1 ":$SIDA1::33:33\$"
|
||||
}
|
||||
|
||||
doc_MeshmsReadMessage="Java API MeshMS mark a message as read"
|
||||
setup_MeshmsReadMessage() {
|
||||
setup
|
||||
# create 3 threads, with all permutations of incoming and outgoing messages
|
||||
executeOk_servald meshms send message $SIDA1 $SIDA2 "Message1"
|
||||
executeOk_servald meshms send message $SIDA3 $SIDA1 "Message2"
|
||||
executeOk_servald meshms send message $SIDA1 $SIDA2 "Message3"
|
||||
executeOk_servald meshms send message $SIDA1 $SIDA4 "Message4"
|
||||
executeOk_servald meshms send message $SIDA4 $SIDA1 "Message5"
|
||||
executeOk_servald meshms send message $SIDA1 $SIDA2 "Message6"
|
||||
executeOk_servald meshms list conversations $SIDA2
|
||||
assertStdoutGrep --stderr --matches=1 ":$SIDA1:unread:33:0\$"
|
||||
}
|
||||
test_MeshmsReadMessage() {
|
||||
executeJavaOk org.servalproject.test.Meshms meshms-advance-read-offset $SIDA2 $SIDA1 22
|
||||
assertStdoutIs -e 'UPDATED\n'
|
||||
executeOk_servald meshms list conversations $SIDA2
|
||||
assertStdoutGrep --stderr --matches=1 ":$SIDA1:unread:33:22\$"
|
||||
executeJavaOk org.servalproject.test.Meshms meshms-advance-read-offset $SIDA2 $SIDA1 11
|
||||
assertStdoutIs -e 'OK\n'
|
||||
executeOk_servald meshms list conversations $SIDA2
|
||||
assertStdoutGrep --stderr --matches=1 ":$SIDA1:unread:33:22\$"
|
||||
}
|
||||
|
||||
runTests "$@"
|
||||
|
Loading…
Reference in New Issue
Block a user