mirror of
https://github.com/EvernodeXRPL/sashimono.git
synced 2026-04-29 15:38:00 +00:00
Two step instance creation and refactoring (#20)
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
#include "msg_json.hpp"
|
||||
#include "../../util/util.hpp"
|
||||
|
||||
namespace msg::json
|
||||
{
|
||||
@@ -43,11 +44,36 @@ namespace msg::json
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the message 'type' value from the json document.
|
||||
* Extracts the message 'type' and 'id' values from the json document.
|
||||
*/
|
||||
int extract_type(std::string &extracted_type, const jsoncons::json &d)
|
||||
int extract_type_and_id(std::string &extracted_type, std::string &extracted_id, const jsoncons::json &d)
|
||||
{
|
||||
if (!d.contains(msg::FLD_TYPE))
|
||||
{
|
||||
LOG_ERROR << "Field type is missing.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!d[msg::FLD_TYPE].is<std::string>())
|
||||
{
|
||||
LOG_ERROR << "Invalid type value.";
|
||||
return -1;
|
||||
}
|
||||
extracted_type = d[msg::FLD_TYPE].as<std::string>();
|
||||
|
||||
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;
|
||||
}
|
||||
extracted_id = d[msg::FLD_ID].as<std::string>();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -69,21 +95,9 @@ namespace msg::json
|
||||
*/
|
||||
int extract_commons(std::string &type, std::string &id, std::string &pubkey, const jsoncons::json &d)
|
||||
{
|
||||
if (extract_type(type, d) == -1)
|
||||
if (extract_type_and_id(type, id, 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.";
|
||||
@@ -96,7 +110,6 @@ namespace msg::json
|
||||
return -1;
|
||||
}
|
||||
|
||||
id = d[msg::FLD_ID].as<std::string>();
|
||||
pubkey = d[msg::FLD_PUBKEY].as<std::string>();
|
||||
return 0;
|
||||
}
|
||||
@@ -134,6 +147,158 @@ namespace msg::json
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts initiate message from msg.
|
||||
* @param msg Populated msg object.
|
||||
* @param d The json document holding the read request message.
|
||||
* Accepted signed input container format:
|
||||
* {
|
||||
* "type": "initiate",
|
||||
* "owner_pubkey": "<pubkey of the owner>",
|
||||
* "container_name": "<container name>",
|
||||
* "peers": [<'ip:port' peer list>],
|
||||
* "unl": [<hex unl pubkey list>],
|
||||
* "role": <role>,
|
||||
* "history": <history mode>,
|
||||
* "max_primary_shards": <number of max primary shards>,
|
||||
* "max_raw_shards": <number of max raw shards>
|
||||
* }
|
||||
* @return 0 on successful extraction. -1 for failure.
|
||||
*/
|
||||
int extract_initiate_message(initiate_msg &msg, const jsoncons::json &d)
|
||||
{
|
||||
if (extract_commons(msg.type, msg.id, msg.pubkey, d) == -1)
|
||||
return -1;
|
||||
|
||||
if (!d.contains(msg::FLD_CONTAINER_NAME))
|
||||
{
|
||||
LOG_ERROR << "Field contract_name is missing.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!d[msg::FLD_CONTAINER_NAME].is<std::string>())
|
||||
{
|
||||
LOG_ERROR << "Invalid container_name value.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg.container_name = d[msg::FLD_CONTAINER_NAME].as<std::string>();
|
||||
|
||||
if (d.contains(msg::FLD_PEERS))
|
||||
{
|
||||
if (!d[msg::FLD_PEERS].empty() && !d[msg::FLD_PEERS].is_array())
|
||||
{
|
||||
LOG_ERROR << "Invalid peers value.";
|
||||
return -1;
|
||||
}
|
||||
else if (!d[msg::FLD_PEERS].empty() && d[msg::FLD_PEERS].size() > 0)
|
||||
{
|
||||
std::vector<std::string> splitted;
|
||||
for (auto &val : d[msg::FLD_PEERS].array_range())
|
||||
{
|
||||
if (!val.is<std::string>())
|
||||
{
|
||||
LOG_ERROR << "Invalid peer value.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
const std::string peer = val.as<std::string>();
|
||||
util::split_string(splitted, peer, ":");
|
||||
if (splitted.size() != 2)
|
||||
{
|
||||
LOG_ERROR << "Invalid peer value: " << peer;
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint16_t port;
|
||||
if (util::stoul(splitted.back(), port) == -1)
|
||||
{
|
||||
LOG_ERROR << "Invalid peer port value: " << peer;
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg.peers.emplace(conf::host_ip_port{splitted.front(), port});
|
||||
splitted.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (d.contains(msg::FLD_UNL))
|
||||
{
|
||||
if (!d[msg::FLD_UNL].empty() && !d[msg::FLD_UNL].is_array())
|
||||
{
|
||||
LOG_ERROR << "Invalid unl value.";
|
||||
return -1;
|
||||
}
|
||||
else if (!d[msg::FLD_UNL].empty() && d[msg::FLD_UNL].size() > 0)
|
||||
{
|
||||
for (auto &val : d[msg::FLD_UNL].array_range())
|
||||
{
|
||||
if (!val.is<std::string>())
|
||||
{
|
||||
LOG_ERROR << "Invalid unl pubkey value.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
const std::string unl_pubkey = val.as<std::string>();
|
||||
const std::string unl_pubkey_bin = util::to_bin(unl_pubkey);
|
||||
if (unl_pubkey_bin.empty())
|
||||
{
|
||||
LOG_ERROR << "Invalid unl pubkey value: " << unl_pubkey;
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg.unl.emplace(unl_pubkey_bin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (d.contains(msg::FLD_ROLE))
|
||||
{
|
||||
if (!d[msg::FLD_ROLE].is<std::string>())
|
||||
{
|
||||
LOG_ERROR << "Invalid role value.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg.role = d[msg::FLD_ROLE].as<std::string>();
|
||||
}
|
||||
|
||||
if (d.contains(msg::FLD_HISTORY))
|
||||
{
|
||||
if (!d[msg::FLD_HISTORY].is<std::string>())
|
||||
{
|
||||
LOG_ERROR << "Invalid history value.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg.history = d[msg::FLD_HISTORY].as<std::string>();
|
||||
}
|
||||
|
||||
if (d.contains(msg::FLD_MAX_P_SHARDS))
|
||||
{
|
||||
if (!d[msg::FLD_MAX_P_SHARDS].empty() && !d[msg::FLD_MAX_P_SHARDS].is<uint64_t>())
|
||||
{
|
||||
LOG_ERROR << "Invalid max_primary_shards value.";
|
||||
return -1;
|
||||
}
|
||||
else if (!d[msg::FLD_MAX_P_SHARDS].empty())
|
||||
msg.max_primary_shards = d[msg::FLD_MAX_P_SHARDS].as<uint64_t>();
|
||||
}
|
||||
|
||||
if (d.contains(msg::FLD_MAX_R_SHARDS))
|
||||
{
|
||||
if (!d[msg::FLD_MAX_R_SHARDS].empty() && !d[msg::FLD_MAX_R_SHARDS].is<uint64_t>())
|
||||
{
|
||||
LOG_ERROR << "Invalid max_raw_shards value.";
|
||||
return -1;
|
||||
}
|
||||
else if (!d[msg::FLD_MAX_R_SHARDS].empty())
|
||||
msg.max_raw_shards = d[msg::FLD_MAX_R_SHARDS].as<uint64_t>();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts destroy message from msg.
|
||||
* @param msg Populated msg object.
|
||||
@@ -244,8 +409,9 @@ namespace msg::json
|
||||
* }
|
||||
* @param response_type Type of the response.
|
||||
* @param content Content inside the response.
|
||||
* @param json_content Whether content is a json string.
|
||||
*/
|
||||
void build_response(std::string &msg, std::string_view response_type, std::string_view reply_for, std::string_view content)
|
||||
void build_response(std::string &msg, std::string_view response_type, std::string_view reply_for, std::string_view content, const bool json_content)
|
||||
{
|
||||
msg.reserve(1024);
|
||||
msg += "{\"";
|
||||
@@ -258,9 +424,9 @@ namespace msg::json
|
||||
msg += response_type;
|
||||
msg += SEP_COMMA;
|
||||
msg += msg::FLD_CONTENT;
|
||||
msg += SEP_COLON;
|
||||
msg += (json_content ? SEP_COLON_NOQUOTE : SEP_COLON);
|
||||
msg += content;
|
||||
msg += "\"}";
|
||||
msg += (json_content ? "}" : "\"}");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -268,8 +434,6 @@ namespace msg::json
|
||||
* @param msg Buffer to construct the generated json message string into.
|
||||
* Message format:
|
||||
* {
|
||||
* 'reply_for': '<reply_for>'
|
||||
* 'type': '<message type>',
|
||||
* "name": "<container name>"
|
||||
* "username": "<instance user name>""
|
||||
* "ip": "<ip of the container>"
|
||||
@@ -281,18 +445,10 @@ namespace msg::json
|
||||
* @param response_type Type of the response.
|
||||
* @param content Content inside the response.
|
||||
*/
|
||||
void build_create_response(std::string &msg, const hp::instance_info &info, std::string_view reply_for)
|
||||
void build_create_response(std::string &msg, const hp::instance_info &info)
|
||||
{
|
||||
msg.reserve(1024);
|
||||
msg += "{\"";
|
||||
msg += msg::FLD_REPLY_FOR;
|
||||
msg += SEP_COLON;
|
||||
msg += std::string(reply_for);
|
||||
msg += SEP_COMMA;
|
||||
msg += msg::FLD_TYPE;
|
||||
msg += SEP_COLON;
|
||||
msg += msg::MSGTYPE_CREATE_RES;
|
||||
msg += SEP_COMMA;
|
||||
msg += "name";
|
||||
msg += SEP_COLON;
|
||||
msg += info.container_name;
|
||||
|
||||
@@ -12,21 +12,23 @@ 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_type_and_id(std::string &extracted_type, std::string &extracted_id, 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_initiate_message(initiate_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 build_response(std::string &msg, std::string_view response_type, std::string_view reply_for, std::string_view content);
|
||||
void build_response(std::string &msg, std::string_view response_type, std::string_view reply_for, std::string_view content, const bool json_content = false);
|
||||
|
||||
void build_create_response(std::string &msg, const hp::instance_info &info, std::string_view reply_for);
|
||||
void build_create_response(std::string &msg, const hp::instance_info &info);
|
||||
|
||||
} // namespace msg::json
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define _HP_MSG_MSG_COMMON_
|
||||
|
||||
#include "../pchheader.hpp"
|
||||
#include "../conf.hpp"
|
||||
|
||||
namespace msg
|
||||
{
|
||||
@@ -13,6 +14,22 @@ namespace msg
|
||||
std::string contract_id;
|
||||
};
|
||||
|
||||
// Keep numerical config valus as optional so when updating the config if the value is empty
|
||||
// We do nothing otherwise we take the value and update the config.
|
||||
struct initiate_msg
|
||||
{
|
||||
std::string id;
|
||||
std::string type;
|
||||
std::string pubkey;
|
||||
std::string container_name;
|
||||
std::set<conf::host_ip_port> peers;
|
||||
std::set<std::string> unl;
|
||||
std::string role;
|
||||
std::string history;
|
||||
std::optional<uint64_t> max_primary_shards;
|
||||
std::optional<uint64_t> max_raw_shards;
|
||||
};
|
||||
|
||||
struct destroy_msg
|
||||
{
|
||||
std::string id;
|
||||
@@ -45,16 +62,24 @@ namespace msg
|
||||
constexpr const char *FLD_CONTAINER_NAME = "container_name";
|
||||
constexpr const char *FLD_CONTRACT_ID = "contract_id";
|
||||
constexpr const char *FLD_ID = "id";
|
||||
constexpr const char *FLD_PEERS = "peers";
|
||||
constexpr const char *FLD_UNL = "unl";
|
||||
constexpr const char *FLD_ROLE = "role";
|
||||
constexpr const char *FLD_HISTORY = "history";
|
||||
constexpr const char *FLD_MAX_P_SHARDS = "max_primary_shards";
|
||||
constexpr const char *FLD_MAX_R_SHARDS = "max_raw_shards";
|
||||
|
||||
// Message types
|
||||
constexpr const char *MSGTYPE_INIT = "init";
|
||||
constexpr const char *MSGTYPE_CREATE = "create";
|
||||
constexpr const char *MSGTYPE_INITIATE = "initiate";
|
||||
constexpr const char *MSGTYPE_DESTROY = "destroy";
|
||||
constexpr const char *MSGTYPE_START = "start";
|
||||
constexpr const char *MSGTYPE_STOP = "stop";
|
||||
|
||||
// Message res types
|
||||
constexpr const char *MSGTYPE_CREATE_RES = "create_res";
|
||||
constexpr const char *MSGTYPE_INITIATE_RES = "initiate_res";
|
||||
constexpr const char *MSGTYPE_DESTROY_RES = "destroy_res";
|
||||
constexpr const char *MSGTYPE_START_RES = "start_res";
|
||||
constexpr const char *MSGTYPE_STOP_RES = "stop_res";
|
||||
|
||||
@@ -8,15 +8,20 @@ namespace msg
|
||||
return json::parse_message(jdoc, message);
|
||||
}
|
||||
|
||||
int msg_parser::extract_type(std::string &extracted_type) const
|
||||
int msg_parser::extract_type_and_id(std::string &extracted_type, std::string &extracted_id) const
|
||||
{
|
||||
return json::extract_type(extracted_type, jdoc);
|
||||
return json::extract_type_and_id(extracted_type, extracted_id, jdoc);
|
||||
}
|
||||
|
||||
int msg_parser::extract_create_message(create_msg &msg) const
|
||||
{
|
||||
return json::extract_create_message(msg, jdoc);
|
||||
}
|
||||
|
||||
int msg_parser::extract_initiate_message(initiate_msg &msg) const
|
||||
{
|
||||
return json::extract_initiate_message(msg, jdoc);
|
||||
}
|
||||
|
||||
int msg_parser::extract_destroy_message(destroy_msg &msg) const
|
||||
{
|
||||
@@ -33,14 +38,14 @@ namespace msg
|
||||
return json::extract_stop_message(msg, jdoc);
|
||||
}
|
||||
|
||||
void msg_parser::build_response(std::string &msg, std::string_view response_type, std::string_view reply_for, std::string_view content) const
|
||||
void msg_parser::build_response(std::string &msg, std::string_view response_type, std::string_view reply_for, std::string_view content, const bool json_content) const
|
||||
{
|
||||
json::build_response(msg, response_type, reply_for, content);
|
||||
json::build_response(msg, response_type, reply_for, content, json_content);
|
||||
}
|
||||
|
||||
void msg_parser::build_create_response(std::string &msg, const hp::instance_info &info, std::string_view reply_for) const
|
||||
void msg_parser::build_create_response(std::string &msg, const hp::instance_info &info) const
|
||||
{
|
||||
json::build_create_response(msg, info, reply_for);
|
||||
json::build_create_response(msg, info);
|
||||
}
|
||||
|
||||
} // namespace msg
|
||||
@@ -13,13 +13,14 @@ namespace msg
|
||||
|
||||
public:
|
||||
int parse(std::string_view message);
|
||||
int extract_type(std::string &extracted_type) const;
|
||||
int extract_type_and_id(std::string &extracted_type, std::string &extracted_id) const;
|
||||
int extract_create_message(create_msg &msg) const;
|
||||
int extract_initiate_message(initiate_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 build_response(std::string &msg, std::string_view response_type, std::string_view reply_for, std::string_view content) const;
|
||||
void build_create_response(std::string &msg, const hp::instance_info &info, std::string_view reply_for) const;
|
||||
void build_response(std::string &msg, std::string_view response_type, std::string_view reply_for, std::string_view content, const bool json_content = false) const;
|
||||
void build_create_response(std::string &msg, const hp::instance_info &info) const;
|
||||
};
|
||||
|
||||
} // namespace msg
|
||||
|
||||
Reference in New Issue
Block a user