Improve MeshMS HTTP RESTful interface

Provide "meshms_status_message" in returned JSON status content
This commit is contained in:
Andrew Bettison 2014-07-04 12:08:49 +09:30
parent cf43635789
commit d16be8f42d
5 changed files with 52 additions and 31 deletions

View File

@ -49,7 +49,7 @@ public class MeshMSCommon
JSONTokeniser json = new JSONTokeniser(new InputStreamReader(conn.getErrorStream(), "US-ASCII"));
Status status = decodeRestfulStatus(json);
throwRestfulResponseExceptions(status, conn.getURL());
throw new ServalDInterfaceException("unexpected MeshMS status = " + status.meshms_status + ", \"" + status.message + "\"");
throw new ServalDInterfaceException("unexpected MeshMS status = " + status.meshms_status_code + ", \"" + status.meshms_status_message + "\"");
}
for (int code: expected_response_codes) {
if (conn.getResponseCode() == code) {
@ -61,8 +61,10 @@ public class MeshMSCommon
}
private static class Status {
public MeshMSStatus meshms_status;
public String message;
public int http_status_code;
public String http_status_message;
public MeshMSStatus meshms_status_code;
public String meshms_status_message;
}
protected static Status decodeRestfulStatus(JSONTokeniser json) throws IOException, ServalDInterfaceException
@ -72,15 +74,19 @@ public class MeshMSCommon
json.consume(JSONTokeniser.Token.START_OBJECT);
json.consume("http_status_code");
json.consume(JSONTokeniser.Token.COLON);
json.consume(Integer.class);
status.http_status_code = json.consume(Integer.class);
json.consume(JSONTokeniser.Token.COMMA);
status.message = json.consume("http_status_message");
json.consume("http_status_message");
json.consume(JSONTokeniser.Token.COLON);
String message = json.consume(String.class);
status.http_status_message = json.consume(String.class);
json.consume(JSONTokeniser.Token.COMMA);
json.consume("meshms_status_code");
json.consume(JSONTokeniser.Token.COLON);
status.meshms_status = MeshMSStatus.fromCode(json.consume(Integer.class));
status.meshms_status_code = MeshMSStatus.fromCode(json.consume(Integer.class));
json.consume(JSONTokeniser.Token.COMMA);
json.consume("meshms_status_message");
json.consume(JSONTokeniser.Token.COLON);
status.meshms_status_message = json.consume(String.class);
json.consume(JSONTokeniser.Token.END_OBJECT);
json.consume(JSONTokeniser.Token.EOF);
return status;
@ -92,7 +98,7 @@ public class MeshMSCommon
protected static void throwRestfulResponseExceptions(Status status, URL url) throws MeshMSException, ServalDFailureException
{
switch (status.meshms_status) {
switch (status.meshms_status_code) {
case OK:
case UPDATED:
break;
@ -101,7 +107,7 @@ public class MeshMSCommon
case PROTOCOL_FAULT:
throw new MeshMSProtocolFaultException(url);
case ERROR:
throw new ServalDFailureException("received meshms_status=ERROR(-1) from " + url);
throw new ServalDFailureException("received meshms_status_code=ERROR(-1) from " + url);
}
}
@ -125,7 +131,7 @@ public class MeshMSCommon
JSONTokeniser json = MeshMSCommon.receiveRestfulResponse(conn, HttpURLConnection.HTTP_CREATED);
Status status = decodeRestfulStatus(json);
throwRestfulResponseExceptions(status, conn.getURL());
return status.meshms_status;
return status.meshms_status_code;
}
public static MeshMSStatus markAllConversationsRead(ServalDHttpConnectionFactory connector, SubscriberId sid1) throws IOException, ServalDInterfaceException, MeshMSException
@ -137,7 +143,7 @@ public class MeshMSCommon
JSONTokeniser json = MeshMSCommon.receiveRestfulResponse(conn, expected_response_codes);
Status status = decodeRestfulStatus(json);
throwRestfulResponseExceptions(status, conn.getURL());
return status.meshms_status;
return status.meshms_status_code;
}
public static MeshMSStatus markAllMessagesRead(ServalDHttpConnectionFactory connector, SubscriberId sid1, SubscriberId sid2) throws IOException, ServalDInterfaceException, MeshMSException
@ -149,7 +155,7 @@ public class MeshMSCommon
JSONTokeniser json = MeshMSCommon.receiveRestfulResponse(conn, expected_response_codes);
Status status = decodeRestfulStatus(json);
throwRestfulResponseExceptions(status, conn.getURL());
return status.meshms_status;
return status.meshms_status_code;
}
public static MeshMSStatus advanceReadOffset(ServalDHttpConnectionFactory connector, SubscriberId sid1, SubscriberId sid2, long offset) throws IOException, ServalDInterfaceException, MeshMSException
@ -161,7 +167,7 @@ public class MeshMSCommon
JSONTokeniser json = MeshMSCommon.receiveRestfulResponse(conn, expected_response_codes);
Status status = decodeRestfulStatus(json);
throwRestfulResponseExceptions(status, conn.getURL());
return status.meshms_status;
return status.meshms_status_code;
}
}

View File

@ -1244,3 +1244,15 @@ done:
keyring = NULL;
return ret;
}
const char *meshms_status_message(enum meshms_status status)
{
switch (status) {
case MESHMS_STATUS_OK: return "OK";
case MESHMS_STATUS_UPDATED: return "Updated";
case MESHMS_STATUS_SID_LOCKED: return "Identity unknown";
case MESHMS_STATUS_PROTOCOL_FAULT: return "MeshMS protocol fault";
case MESHMS_STATUS_ERROR: return "Internal error";
}
return NULL;
}

View File

@ -47,6 +47,8 @@ __MESHMS_INLINE int meshms_failed(enum meshms_status status) {
return status != MESHMS_STATUS_OK && status != MESHMS_STATUS_UPDATED;
}
const char *meshms_status_message(enum meshms_status);
// the manifest details for one half of a conversation
struct meshms_ply {
rhizome_bid_t bundle_id;

View File

@ -66,42 +66,41 @@ static int strn_to_meshms_token(const char *str, rhizome_bid_t *bidp, uint64_t *
static int http_request_meshms_response(struct httpd_request *r, uint16_t result, const char *message, enum meshms_status status)
{
r->http.response.result_extra[0].label = "meshms_status_code";
r->http.response.result_extra[0].value.type = JSON_INTEGER;
r->http.response.result_extra[0].value.u.integer = status;
uint16_t meshms_result = 0;
const char *meshms_message = NULL;
switch (status) {
case MESHMS_STATUS_OK:
meshms_result = 200;
meshms_message = "OK";
break;
case MESHMS_STATUS_UPDATED:
meshms_result = 201;
meshms_message = "Updated";
break;
case MESHMS_STATUS_SID_LOCKED:
meshms_result = 403;
meshms_message = "Identity unknown";
break;
case MESHMS_STATUS_PROTOCOL_FAULT:
meshms_result = 403;
meshms_message = "MeshMS protocol fault";
break;
case MESHMS_STATUS_ERROR:
meshms_result = 500;
break;
}
if (!meshms_result) {
if (meshms_result == 0) {
WHYF("Invalid MeshMS status code %d", status);
result = 500;
} else if (!result) {
meshms_result = 500;
}
r->http.response.result_extra[0].label = "meshms_status_code";
r->http.response.result_extra[0].value.type = JSON_INTEGER;
r->http.response.result_extra[0].value.u.integer = status;
const char *status_message = meshms_status_message(status);
if (status_message) {
r->http.response.result_extra[1].label = "meshms_status_message";
r->http.response.result_extra[1].value.type = JSON_STRING_NULTERM;
r->http.response.result_extra[1].value.u.string.content = status_message;
}
if (meshms_result > result) {
result = meshms_result;
if (message == NULL)
message = meshms_message;
message = NULL;
}
assert(result != 0);
http_request_simple_response(&r->http, result, message);
http_request_simple_response(&r->http, result, message ? message : result == 403 ? "MeshMS operation failed" : NULL);
return result;
}

View File

@ -280,8 +280,9 @@ test_MeshmsListMessagesNoIdentity() {
assertExitStatus == 0
assertStdoutIs 403
assertJq http.body 'contains({"http_status_code": 403})'
assertJqGrep --ignore-case http.body '.http_status_message' 'meshms operation failed'
assertJq http.body 'contains({"meshms_status_code": 2})'
assertJqGrep --ignore-case http.body '.http_status_message' 'identity.*unknown'
assertJqGrep --ignore-case http.body '.meshms_status_message' 'identity.*unknown'
}
doc_MeshmsListMessagesNewSince="HTTP RESTful list MeshMS messages in one conversation since token as JSON"
@ -555,8 +556,9 @@ test_MeshmsSendNoIdentity() {
assertExitStatus == 0
assertStdoutIs 403
assertJq http.body 'contains({"http_status_code": 403})'
assertJqGrep --ignore-case http.body '.http_status_message' 'meshms operation failed'
assertJq http.body 'contains({"meshms_status_code": 2})'
assertJqGrep --ignore-case http.body '.http_status_message' 'identity.*unknown'
assertJqGrep --ignore-case http.body '.meshms_status_message' 'identity.*unknown'
}
doc_MeshmsReadAllConversations="HTTP RESTful MeshMS mark all conversations read"