mirror of
https://github.com/EvernodeXRPL/sashimono.git
synced 2026-04-29 15:38:00 +00:00
Introduce message threads and message handling (#4)
This commit is contained in:
252
src/msg/json/msg_json.cpp
Normal file
252
src/msg/json/msg_json.cpp
Normal file
@@ -0,0 +1,252 @@
|
||||
#include "msg_json.hpp"
|
||||
|
||||
namespace msg::json
|
||||
{
|
||||
// JSON separators
|
||||
constexpr const char *SEP_COMMA = "\",\"";
|
||||
constexpr const char *SEP_COLON = "\":\"";
|
||||
constexpr const char *SEP_COMMA_NOQUOTE = ",\"";
|
||||
constexpr const char *SEP_COLON_NOQUOTE = "\":";
|
||||
constexpr const char *DOUBLE_QUOTE = "\"";
|
||||
|
||||
/**
|
||||
* Parses a json message sent by the message board.
|
||||
* @param d Jsoncons document to which the parsed json should be loaded.
|
||||
* @param message The message to parse.
|
||||
* Accepted message format:
|
||||
* {
|
||||
* 'type': '<message type>'
|
||||
* ...
|
||||
* }
|
||||
* @return 0 on successful parsing. -1 for failure.
|
||||
*/
|
||||
int parse_message(jsoncons::json &d, std::string_view message)
|
||||
{
|
||||
try
|
||||
{
|
||||
d = jsoncons::json::parse(message, jsoncons::strict_json_parsing());
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
LOG_ERROR << "JSON message parsing failed. " << e.what();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Check existence of msg type field.
|
||||
if (!d.contains(msg::FLD_TYPE) || !d[msg::FLD_TYPE].is<std::string>())
|
||||
{
|
||||
LOG_ERROR << "JSON message 'type' missing or invalid.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the message 'type' value from the json document.
|
||||
*/
|
||||
int extract_type(std::string &extracted_type, const jsoncons::json &d)
|
||||
{
|
||||
extracted_type = d[msg::FLD_TYPE].as<std::string>();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts type, id and pubkey in the msg.
|
||||
* @param type Type in the message.
|
||||
* @param id id in the message.
|
||||
* @param pubkey Pubkey in the message.
|
||||
* @param d The json document holding the read request message.
|
||||
* Accepted signed input container format:
|
||||
* {
|
||||
* ...
|
||||
* "type": "<message type>",
|
||||
* "id": "<message id>",
|
||||
* "owner_pubkey": "<pubkey of the owner>",
|
||||
* ...
|
||||
* }
|
||||
* @return 0 on successful extraction. -1 for failure.
|
||||
*/
|
||||
int extract_commons(std::string &type, std::string &id, std::string &pubkey, const jsoncons::json &d)
|
||||
{
|
||||
if (extract_type(type, d) == -1)
|
||||
return -1;
|
||||
|
||||
if (!d.contains(msg::FLD_ID))
|
||||
{
|
||||
LOG_ERROR << "Field id is missing.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!d[msg::FLD_ID].is<std::string>())
|
||||
{
|
||||
LOG_ERROR << "Invalid id value.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!d.contains(msg::FLD_PUBKEY))
|
||||
{
|
||||
LOG_ERROR << "Field owner_pubkey is missing.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!d[msg::FLD_PUBKEY].is<std::string>())
|
||||
{
|
||||
LOG_ERROR << "Invalid owner_pubkey value.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
id = d[msg::FLD_ID].as<std::string>();
|
||||
pubkey = d[msg::FLD_PUBKEY].as<std::string>();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts create message from msg.
|
||||
* @param msg Populated msg object.
|
||||
* @param d The json document holding the read request message.
|
||||
* Accepted signed input container format:
|
||||
* {
|
||||
* "type": "create",
|
||||
* "owner_pubkey": "<pubkey of the owner>"
|
||||
* }
|
||||
* @return 0 on successful extraction. -1 for failure.
|
||||
*/
|
||||
int extract_create_message(create_msg &msg, const jsoncons::json &d)
|
||||
{
|
||||
if (extract_commons(msg.type, msg.id, msg.pubkey, d) == -1)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts destroy message from msg.
|
||||
* @param msg Populated msg object.
|
||||
* @param d The json document holding the read request message.
|
||||
* Accepted signed input container format:
|
||||
* {
|
||||
* "type": "destroy",
|
||||
* "owner_pubkey": "<pubkey of the owner>",
|
||||
* "contract_id": "<contract id>",
|
||||
* }
|
||||
* @return 0 on successful extraction. -1 for failure.
|
||||
*/
|
||||
int extract_destroy_message(destroy_msg &msg, const jsoncons::json &d)
|
||||
{
|
||||
if (extract_commons(msg.type, msg.id, msg.pubkey, d) == -1)
|
||||
return -1;
|
||||
|
||||
if (!d.contains(msg::FLD_CONTRACT_ID))
|
||||
{
|
||||
LOG_ERROR << "Field contract_id is missing.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!d[msg::FLD_CONTRACT_ID].is<std::string>())
|
||||
{
|
||||
LOG_ERROR << "Invalid contract_id value.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg.contract_id = d[msg::FLD_CONTRACT_ID].as<std::string>();
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts start message from msg.
|
||||
* @param msg Populated msg object.
|
||||
* @param d The json document holding the read request message.
|
||||
* Accepted signed input container format:
|
||||
* {
|
||||
* "type": "start",
|
||||
* "owner_pubkey": "<pubkey of the owner>",
|
||||
* "contract_id": "<contract id>",
|
||||
* }
|
||||
* @return 0 on successful extraction. -1 for failure.
|
||||
*/
|
||||
int extract_start_message(start_msg &msg, const jsoncons::json &d)
|
||||
{
|
||||
if (extract_commons(msg.type, msg.id, msg.pubkey, d) == -1)
|
||||
return -1;
|
||||
|
||||
if (!d.contains(msg::FLD_CONTRACT_ID))
|
||||
{
|
||||
LOG_ERROR << "Field contract_id is missing.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!d[msg::FLD_CONTRACT_ID].is<std::string>())
|
||||
{
|
||||
LOG_ERROR << "Invalid contract_id value.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg.contract_id = d[msg::FLD_CONTRACT_ID].as<std::string>();
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts stop message from msg.
|
||||
* @param msg Populated msg object.
|
||||
* @param d The json document holding the read request message.
|
||||
* Accepted signed input container format:
|
||||
* {
|
||||
* "type": "stop",
|
||||
* "owner_pubkey": "<pubkey of the owner>",
|
||||
* "contract_id": "<contract id>",
|
||||
* }
|
||||
* @return 0 on successful extraction. -1 for failure.
|
||||
*/
|
||||
int extract_stop_message(stop_msg &msg, const jsoncons::json &d)
|
||||
{
|
||||
if (extract_commons(msg.type, msg.id, msg.pubkey, d) == -1)
|
||||
return -1;
|
||||
|
||||
if (!d.contains(msg::FLD_CONTRACT_ID))
|
||||
{
|
||||
LOG_ERROR << "Field contract_id is missing.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!d[msg::FLD_CONTRACT_ID].is<std::string>())
|
||||
{
|
||||
LOG_ERROR << "Invalid contract_id value.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg.contract_id = d[msg::FLD_CONTRACT_ID].as<std::string>();
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a response json.
|
||||
* @param msg Buffer to construct the generated json message string into.
|
||||
* Message format:
|
||||
* {
|
||||
* 'type': '<message type>',
|
||||
* "content": "<any string>"
|
||||
* }
|
||||
* @param response_type Type of the response.
|
||||
* @param content Content inside the response.
|
||||
*/
|
||||
void create_response(std::string &msg, std::string_view response_type, std::string_view content)
|
||||
{
|
||||
msg.reserve(1024);
|
||||
msg += "{\"";
|
||||
msg += msg::FLD_TYPE;
|
||||
msg += SEP_COLON;
|
||||
msg += response_type;
|
||||
msg += SEP_COMMA;
|
||||
msg += msg::FLD_CONTENT;
|
||||
msg += SEP_COLON;
|
||||
msg += content;
|
||||
msg += "\"}";
|
||||
}
|
||||
|
||||
} // namespace msg::json
|
||||
30
src/msg/json/msg_json.hpp
Normal file
30
src/msg/json/msg_json.hpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef _HP_MSG_MSG_JSON_
|
||||
#define _HP_MSG_MSG_JSON_
|
||||
|
||||
#include "../../pchheader.hpp"
|
||||
#include "../msg_common.hpp"
|
||||
|
||||
/**
|
||||
* Parser helpers for json messages.
|
||||
*/
|
||||
namespace msg::json
|
||||
{
|
||||
int parse_message(jsoncons::json &d, std::string_view message);
|
||||
|
||||
int extract_type(std::string &extracted_type, const jsoncons::json &d);
|
||||
|
||||
int extract_commons(std::string &type, std::string &id, std::string &pubkey, const jsoncons::json &d);
|
||||
|
||||
int extract_create_message(create_msg &msg, const jsoncons::json &d);
|
||||
|
||||
int extract_destroy_message(destroy_msg &msg, const jsoncons::json &d);
|
||||
|
||||
int extract_start_message(start_msg &msg, const jsoncons::json &d);
|
||||
|
||||
int extract_stop_message(stop_msg &msg, const jsoncons::json &d);
|
||||
|
||||
void create_response(std::string &msg, std::string_view response_type, std::string_view content);
|
||||
|
||||
} // namespace msg::json
|
||||
|
||||
#endif
|
||||
55
src/msg/msg_common.hpp
Normal file
55
src/msg/msg_common.hpp
Normal file
@@ -0,0 +1,55 @@
|
||||
#ifndef _HP_MSG_MSG_COMMON_
|
||||
#define _HP_MSG_MSG_COMMON_
|
||||
|
||||
#include "../pchheader.hpp"
|
||||
|
||||
namespace msg
|
||||
{
|
||||
struct create_msg
|
||||
{
|
||||
std::string id;
|
||||
std::string type;
|
||||
std::string pubkey;
|
||||
};
|
||||
|
||||
struct destroy_msg
|
||||
{
|
||||
std::string id;
|
||||
std::string type;
|
||||
std::string pubkey;
|
||||
std::string contract_id;
|
||||
};
|
||||
|
||||
struct start_msg
|
||||
{
|
||||
std::string id;
|
||||
std::string type;
|
||||
std::string pubkey;
|
||||
std::string contract_id;
|
||||
};
|
||||
|
||||
struct stop_msg
|
||||
{
|
||||
std::string id;
|
||||
std::string type;
|
||||
std::string pubkey;
|
||||
std::string contract_id;
|
||||
};
|
||||
|
||||
// Message field names
|
||||
constexpr const char *FLD_TYPE = "type";
|
||||
constexpr const char *FLD_CONTENT = "content";
|
||||
constexpr const char *FLD_PUBKEY = "owner_pubkey";
|
||||
constexpr const char *FLD_CONTRACT_ID = "contract_id";
|
||||
constexpr const char *FLD_ID = "id";
|
||||
|
||||
// Message types
|
||||
constexpr const char *MSGTYPE_INIT = "init";
|
||||
constexpr const char *MSGTYPE_CREATE = "create";
|
||||
constexpr const char *MSGTYPE_DESTROY = "destroy";
|
||||
constexpr const char *MSGTYPE_START = "start";
|
||||
constexpr const char *MSGTYPE_STOP = "stop";
|
||||
|
||||
} // namespace msg
|
||||
|
||||
#endif
|
||||
41
src/msg/msg_parser.cpp
Normal file
41
src/msg/msg_parser.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
#include "msg_parser.hpp"
|
||||
#include "json/msg_json.hpp"
|
||||
|
||||
namespace msg
|
||||
{
|
||||
int msg_parser::parse(std::string_view message)
|
||||
{
|
||||
return json::parse_message(jdoc, message);
|
||||
}
|
||||
|
||||
int msg_parser::extract_type(std::string &extracted_type) const
|
||||
{
|
||||
return json::extract_type(extracted_type, jdoc);
|
||||
}
|
||||
|
||||
int msg_parser::extract_create_message(create_msg &msg) const
|
||||
{
|
||||
return json::extract_create_message(msg, jdoc);
|
||||
}
|
||||
|
||||
int msg_parser::extract_destroy_message(destroy_msg &msg) const
|
||||
{
|
||||
return json::extract_destroy_message(msg, jdoc);
|
||||
}
|
||||
|
||||
int msg_parser::extract_start_message(start_msg &msg) const
|
||||
{
|
||||
return json::extract_start_message(msg, jdoc);
|
||||
}
|
||||
|
||||
int msg_parser::extract_stop_message(stop_msg &msg) const
|
||||
{
|
||||
return json::extract_stop_message(msg, jdoc);
|
||||
}
|
||||
|
||||
void msg_parser::create_response(std::string &msg, std::string_view response_type, std::string_view content) const
|
||||
{
|
||||
json::create_response(msg, response_type, content);
|
||||
}
|
||||
|
||||
} // namespace msg
|
||||
25
src/msg/msg_parser.hpp
Normal file
25
src/msg/msg_parser.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef _SA_MSG_MSG_PARSER_
|
||||
#define _SA_MSG_MSG_PARSER_
|
||||
|
||||
#include "../pchheader.hpp"
|
||||
#include "msg_common.hpp"
|
||||
|
||||
namespace msg
|
||||
{
|
||||
class msg_parser
|
||||
{
|
||||
jsoncons::json jdoc;
|
||||
|
||||
public:
|
||||
int parse(std::string_view message);
|
||||
int extract_type(std::string &extracted_type) const;
|
||||
int extract_create_message(create_msg &msg) const;
|
||||
int extract_destroy_message(destroy_msg &msg) const;
|
||||
int extract_start_message(start_msg &msg) const;
|
||||
int extract_stop_message(stop_msg &msg) const;
|
||||
void create_response(std::string &msg, std::string_view response_type, std::string_view content) const;
|
||||
};
|
||||
|
||||
} // namespace msg
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user