Two step instance creation and refactoring (#20)

This commit is contained in:
Chalith Desaman
2021-06-29 16:09:04 +05:30
committed by GitHub
parent c8df2e75ac
commit 43cb7e8ca1
16 changed files with 712 additions and 286 deletions

View File

@@ -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;

View File

@@ -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

View File

@@ -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";

View File

@@ -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

View File

@@ -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