Rename LMQ -> OMQ in code

(This doesn't rename the `--lmq-...` cli options because that would
break backwards compatibility.)
This commit is contained in:
Jason Rhinelander 2022-12-19 13:11:08 -04:00
parent d3d0a4460d
commit 402aa450c9
No known key found for this signature in database
GPG key ID: C4992CE7A88D4262
12 changed files with 52 additions and 54 deletions

View file

@ -952,7 +952,7 @@ namespace cryptonote
log::info(logcat, fg(fmt::terminal_color::yellow), "- x25519: {}", tools::type_to_hex(keys.pub_x25519)); log::info(logcat, fg(fmt::terminal_color::yellow), "- x25519: {}", tools::type_to_hex(keys.pub_x25519));
} else { } else {
// Only print the x25519 version because it's the only thing useful for a non-SN (for // Only print the x25519 version because it's the only thing useful for a non-SN (for
// encrypted LMQ RPC connections). // encrypted OMQ RPC connections).
log::info(logcat, fg(fmt::terminal_color::yellow), "x25519 public key: {}", tools::type_to_hex(keys.pub_x25519)); log::info(logcat, fg(fmt::terminal_color::yellow), "x25519 public key: {}", tools::type_to_hex(keys.pub_x25519));
} }
@ -2286,7 +2286,7 @@ namespace cryptonote
if (pk != m_service_keys.pub && proof.proof->public_ip == m_sn_public_ip && if (pk != m_service_keys.pub && proof.proof->public_ip == m_sn_public_ip &&
(proof.proof->qnet_port == m_quorumnet_port || ( (proof.proof->qnet_port == m_quorumnet_port || (
m_nettype != network_type::DEVNET && (proof.proof->storage_https_port == storage_https_port() || proof.proof->storage_omq_port == storage_omq_port())))) m_nettype != network_type::DEVNET && (proof.proof->storage_https_port == storage_https_port() || proof.proof->storage_omq_port == storage_omq_port()))))
log::info(logcat, fg(fmt::terminal_color::red), "Another service node ({}) is broadcasting the same public IP and ports as this service node ({}:{}[qnet], :{}[SS-HTTP], :{}[SS-LMQ]). This will lead to deregistration of one or both service nodes if not corrected. (Do both service nodes have the correct IP for the service-node-public-ip setting?)", pk, epee::string_tools::get_ip_string_from_int32(m_sn_public_ip), proof.proof->qnet_port, proof.proof->storage_https_port, proof.proof->storage_omq_port); log::info(logcat, fg(fmt::terminal_color::red), "Another service node ({}) is broadcasting the same public IP and ports as this service node ({}:{}[qnet], :{}[SS-HTTP], :{}[SS-OMQ]). This will lead to deregistration of one or both service nodes if not corrected. (Do both service nodes have the correct IP for the service-node-public-ip setting?)", pk, epee::string_tools::get_ip_string_from_int32(m_sn_public_ip), proof.proof->qnet_port, proof.proof->storage_https_port, proof.proof->storage_omq_port);
}); });
} }

View file

@ -1188,8 +1188,8 @@ namespace cryptonote
// avoid linking issues (protocol does not link against core). // avoid linking issues (protocol does not link against core).
void* m_quorumnet_state = nullptr; void* m_quorumnet_state = nullptr;
/// Stores x25519 -> access level for LMQ authentication. /// Stores x25519 -> access level for OMQ authentication.
/// Not to be modified after the LMQ listener starts. /// Not to be modified after the OMQ listener starts.
std::unordered_map<crypto::x25519_public_key, oxenmq::AuthLevel> m_omq_auth; std::unordered_map<crypto::x25519_public_key, oxenmq::AuthLevel> m_omq_auth;
size_t block_sync_size; size_t block_sync_size;

View file

@ -741,13 +741,13 @@ namespace {
/* /*
Pulse progresses via a state-machine that is iterated through job submissions Pulse progresses via a state-machine that is iterated through job submissions
to 1 dedicated Pulse thread, started by LMQ. to 1 dedicated Pulse thread, started by OMQ.
Iterating the state-machine is done by a periodic invocation of Iterating the state-machine is done by a periodic invocation of
pulse::main(...) and messages received via Quorumnet for Pulse, which are pulse::main(...) and messages received via Quorumnet for Pulse, which are
queued in the thread's job queue. queued in the thread's job queue.
Using 1 dedicated thread via LMQ avoids any synchronization required in the Using 1 dedicated thread via OMQ avoids any synchronization required in the
user code when implementing Pulse. user code when implementing Pulse.
Skip control flow graph for textual description of stages. Skip control flow graph for textual description of stages.

View file

@ -44,7 +44,7 @@
#endif #endif
#include "rpc/common/rpc_args.h" #include "rpc/common/rpc_args.h"
#include "rpc/http_server.h" #include "rpc/http_server.h"
#include "rpc/lmq_server.h" #include "rpc/omq_server.h"
#include "cryptonote_protocol/quorumnet.h" #include "cryptonote_protocol/quorumnet.h"
#include "cryptonote_core/uptime_proof.h" #include "cryptonote_core/uptime_proof.h"

View file

@ -34,7 +34,7 @@
#include "p2p/net_node.h" #include "p2p/net_node.h"
#include "rpc/core_rpc_server.h" #include "rpc/core_rpc_server.h"
#include "rpc/http_server.h" #include "rpc/http_server.h"
#include "rpc/lmq_server.h" #include "rpc/omq_server.h"
#include "blocks/blocks.h" #include "blocks/blocks.h"
#include "rpc/core_rpc_server.h" #include "rpc/core_rpc_server.h"

View file

@ -41,7 +41,7 @@ add_library(rpc
add_library(daemon_rpc_server add_library(daemon_rpc_server
http_server.cpp http_server.cpp
lmq_server.cpp omq_server.cpp
) )
add_library(rpc_http_client add_library(rpc_http_client

View file

@ -17,7 +17,7 @@ namespace cryptonote::rpc {
/// Base class that all RPC commands must inherit from (either directly or via one or more of the /// Base class that all RPC commands must inherit from (either directly or via one or more of the
/// below tags). Inheriting from this (and no others) gives you a private, json, non-legacy RPC /// below tags). Inheriting from this (and no others) gives you a private, json, non-legacy RPC
/// command. For LMQ RPC the command will be available at `admin.whatever`; for HTTP RPC it'll be /// command. For OMQ RPC the command will be available at `admin.whatever`; for HTTP RPC it'll be
/// at `whatever`. This base class is also where response objects are stored. /// at `whatever`. This base class is also where response objects are stored.
struct RPC_COMMAND { struct RPC_COMMAND {
private: private:
@ -72,7 +72,7 @@ namespace cryptonote::rpc {
/// Tag types that are used (via inheritance) to set rpc endpoint properties /// Tag types that are used (via inheritance) to set rpc endpoint properties
/// Specifies that the RPC call is public (i.e. available through restricted rpc). If this is /// Specifies that the RPC call is public (i.e. available through restricted rpc). If this is
/// *not* inherited from then the command is restricted (i.e. only available to admins). For LMQ, /// *not* inherited from then the command is restricted (i.e. only available to admins). For OMQ,
/// PUBLIC commands are available at `rpc.command` (versus non-PUBLIC ones at `admin.command`). /// PUBLIC commands are available at `rpc.command` (versus non-PUBLIC ones at `admin.command`).
struct PUBLIC : virtual RPC_COMMAND {}; struct PUBLIC : virtual RPC_COMMAND {};

View file

@ -241,8 +241,8 @@ namespace cryptonote::rpc {
struct request struct request
{ {
bool blinked_txs_only; // Optional: If true only transactions that were sent via blink and approved are queried. bool blinked_txs_only; // Optional: If true only transactions that were sent via blink and approved are queried.
bool long_poll; // Optional: If true, this call is blocking until timeout OR tx pool has changed since the last query. TX pool change is detected by comparing the hash of all the hashes in the tx pool. Ignored when using LMQ RPC. bool long_poll; // Optional: If true, this call is blocking until timeout OR tx pool has changed since the last query. TX pool change is detected by comparing the hash of all the hashes in the tx pool. Ignored when using OMQ RPC.
crypto::hash tx_pool_checksum; // Optional: If `long_poll` is true the caller must pass the hashes of all their known tx pool hashes, XOR'ed together. Ignored when using LMQ RPC. crypto::hash tx_pool_checksum; // Optional: If `long_poll` is true the caller must pass the hashes of all their known tx pool hashes, XOR'ed together. Ignored when using OMQ RPC.
KV_MAP_SERIALIZABLE KV_MAP_SERIALIZABLE
}; };

View file

@ -87,7 +87,7 @@ namespace cryptonote::rpc {
: m_server{server}, m_restricted{restricted} : m_server{server}, m_restricted{restricted}
{ {
// uWS is designed to work from a single thread, which is good (we pull off the requests and // uWS is designed to work from a single thread, which is good (we pull off the requests and
// then stick them into the LMQ job queue to be scheduled along with other jobs). But as a // then stick them into the OMQ job queue to be scheduled along with other jobs). But as a
// consequence, we need to create everything inside that thread. We *also* need to get the // consequence, we need to create everything inside that thread. We *also* need to get the
// (thread local) event loop pointer back from the thread so that we can shut it down later // (thread local) event loop pointer back from the thread so that we can shut it down later
// (injecting a callback into it is one of the few thread-safe things we can do across threads). // (injecting a callback into it is one of the few thread-safe things we can do across threads).
@ -268,7 +268,7 @@ namespace cryptonote::rpc {
void invoke_txpool_hashes_bin(std::shared_ptr<call_data> data); void invoke_txpool_hashes_bin(std::shared_ptr<call_data> data);
// Invokes the actual RPC request; this is called (via oxenmq) from some random LMQ worker thread, // Invokes the actual RPC request; this is called (via oxenmq) from some random OMQ worker thread,
// which means we can't just write our reply; instead we have to post it to the uWS loop. // which means we can't just write our reply; instead we have to post it to the uWS loop.
void invoke_rpc(std::shared_ptr<call_data> dataptr) void invoke_rpc(std::shared_ptr<call_data> dataptr)
{ {
@ -472,7 +472,7 @@ namespace cryptonote::rpc {
auto& omq = data->core_rpc.get_core().get_omq(); auto& omq = data->core_rpc.get_core().get_omq();
std::string cat{data->call->is_public ? "rpc" : "admin"}; std::string cat{data->call->is_public ? "rpc" : "admin"};
std::string cmd{"http:" + data->uri}; // Used for LMQ job logging; prefixed with http: so we can distinguish it std::string cmd{"http:" + data->uri}; // Used for OMQ job logging; prefixed with http: so we can distinguish it
std::string remote{data->request.context.remote}; std::string remote{data->request.context.remote};
omq.inject_task(std::move(cat), std::move(cmd), std::move(remote), [data=std::move(data)] { invoke_rpc(std::move(data)); }); omq.inject_task(std::move(cat), std::move(cmd), std::move(remote), [data=std::move(data)] { invoke_rpc(std::move(data)); });
}); });
@ -538,7 +538,7 @@ namespace cryptonote::rpc {
auto& omq = data->core_rpc.get_core().get_omq(); auto& omq = data->core_rpc.get_core().get_omq();
std::string cat{data->call->is_public ? "rpc" : "admin"}; std::string cat{data->call->is_public ? "rpc" : "admin"};
std::string cmd{"jsonrpc:" + *method}; // Used for LMQ job logging; prefixed with jsonrpc: so we can distinguish it std::string cmd{"jsonrpc:" + *method}; // Used for OMQ job logging; prefixed with jsonrpc: so we can distinguish it
std::string remote{data->request.context.remote}; std::string remote{data->request.context.remote};
omq.inject_task(std::move(cat), std::move(cmd), std::move(remote), [data=std::move(data)] { invoke_rpc(std::move(data)); }); omq.inject_task(std::move(cat), std::move(cmd), std::move(remote), [data=std::move(data)] { invoke_rpc(std::move(data)); });
}); });

View file

@ -1,5 +1,5 @@
#include "lmq_server.h" #include "omq_server.h"
#include "rpc/common/param_parser.hpp" #include "rpc/common/param_parser.hpp"
#include "cryptonote_config.h" #include "cryptonote_config.h"
#include <oxenc/bt.h> #include <oxenc/bt.h>
@ -7,8 +7,6 @@
#include <oxenmq/fmt.h> #include <oxenmq/fmt.h>
#include <fmt/core.h> #include <fmt/core.h>
// FIXME: Rename this to omq_server.{h,cpp}
namespace cryptonote { namespace rpc { namespace cryptonote { namespace rpc {
using oxenmq::AuthLevel; using oxenmq::AuthLevel;
@ -53,7 +51,7 @@ const command_line::arg_descriptor<std::vector<std::string>> arg_omq_local_contr
#ifndef _WIN32 #ifndef _WIN32
const command_line::arg_descriptor<std::string> arg_omq_umask{ const command_line::arg_descriptor<std::string> arg_omq_umask{
"lmq-umask", "lmq-umask",
"Sets the umask to apply to any listening ipc:///path/to/sock LMQ sockets, in octal.", "Sets the umask to apply to any listening ipc:///path/to/sock OMQ sockets, in octal.",
"0007"}; "0007"};
#endif #endif
@ -71,20 +69,20 @@ auto as_x_pubkeys(const std::vector<std::string>& pk_strings) {
pks.reserve(pk_strings.size()); pks.reserve(pk_strings.size());
for (const auto& pkstr : pk_strings) { for (const auto& pkstr : pk_strings) {
if (pkstr.size() != 64 || !oxenc::is_hex(pkstr)) if (pkstr.size() != 64 || !oxenc::is_hex(pkstr))
throw std::runtime_error("Invalid LMQ login pubkey: '" + pkstr + "'; expected 64-char hex pubkey"); throw std::runtime_error("Invalid OMQ login pubkey: '" + pkstr + "'; expected 64-char hex pubkey");
pks.emplace_back(); pks.emplace_back();
oxenc::to_hex(pkstr.begin(), pkstr.end(), reinterpret_cast<char *>(&pks.back())); oxenc::to_hex(pkstr.begin(), pkstr.end(), reinterpret_cast<char *>(&pks.back()));
} }
return pks; return pks;
} }
// LMQ RPC responses consist of [CODE, DATA] for code we (partially) mimic HTTP error codes: 200 // OMQ RPC responses consist of [CODE, DATA] for code we (partially) mimic HTTP error codes: 200
// means success, anything else means failure. (We don't have codes for Forbidden or Not Found // means success, anything else means failure. (We don't have codes for Forbidden or Not Found
// because those happen at the LMQ protocol layer). // because those happen at the OMQ protocol layer).
constexpr std::string_view constexpr std::string_view
LMQ_OK{"200"sv}, OMQ_OK{"200"sv},
LMQ_BAD_REQUEST{"400"sv}, OMQ_BAD_REQUEST{"400"sv},
LMQ_ERROR{"500"sv}; OMQ_ERROR{"500"sv};
} // end anonymous namespace } // end anonymous namespace
@ -112,21 +110,21 @@ omq_rpc::omq_rpc(cryptonote::core& core, core_rpc_server& rpc, const boost::prog
// the quorumnet listener set up in cryptonote_core). // the quorumnet listener set up in cryptonote_core).
for (const auto &addr : command_line::get_arg(vm, arg_omq_public)) { for (const auto &addr : command_line::get_arg(vm, arg_omq_public)) {
check_omq_listen_addr(addr); check_omq_listen_addr(addr);
log::info(logcat, "LMQ listening on {} (public unencrypted)", addr); log::info(logcat, "OMQ listening on {} (public unencrypted)", addr);
omq.listen_plain(addr, omq.listen_plain(addr,
[&core](std::string_view ip, std::string_view pk, bool /*sn*/) { return core.omq_allow(ip, pk, AuthLevel::basic); }); [&core](std::string_view ip, std::string_view pk, bool /*sn*/) { return core.omq_allow(ip, pk, AuthLevel::basic); });
} }
for (const auto &addr : command_line::get_arg(vm, arg_omq_curve_public)) { for (const auto &addr : command_line::get_arg(vm, arg_omq_curve_public)) {
check_omq_listen_addr(addr); check_omq_listen_addr(addr);
log::info(logcat, "LMQ listening on {} (public curve)", addr); log::info(logcat, "OMQ listening on {} (public curve)", addr);
omq.listen_curve(addr, omq.listen_curve(addr,
[&core](std::string_view ip, std::string_view pk, bool /*sn*/) { return core.omq_allow(ip, pk, AuthLevel::basic); }); [&core](std::string_view ip, std::string_view pk, bool /*sn*/) { return core.omq_allow(ip, pk, AuthLevel::basic); });
} }
for (const auto &addr : command_line::get_arg(vm, arg_omq_curve)) { for (const auto &addr : command_line::get_arg(vm, arg_omq_curve)) {
check_omq_listen_addr(addr); check_omq_listen_addr(addr);
log::info(logcat, "LMQ listening on {} (curve restricted)", addr); log::info(logcat, "OMQ listening on {} (curve restricted)", addr);
omq.listen_curve(addr, omq.listen_curve(addr,
[&core](std::string_view ip, std::string_view pk, bool /*sn*/) { return core.omq_allow(ip, pk, AuthLevel::denied); }); [&core](std::string_view ip, std::string_view pk, bool /*sn*/) { return core.omq_allow(ip, pk, AuthLevel::denied); });
} }
@ -196,7 +194,7 @@ omq_rpc::omq_rpc(cryptonote::core& core, core_rpc_server& rpc, const boost::prog
omq.add_request_command(cmd.second->is_public ? "rpc" : "admin", cmd.first, omq.add_request_command(cmd.second->is_public ? "rpc" : "admin", cmd.first,
[name=std::string_view{cmd.first}, &call=*cmd.second, this](oxenmq::Message& m) { [name=std::string_view{cmd.first}, &call=*cmd.second, this](oxenmq::Message& m) {
if (m.data.size() > 1) if (m.data.size() > 1)
m.send_reply(LMQ_BAD_REQUEST, "Bad request: RPC commands must have at most one data part " m.send_reply(OMQ_BAD_REQUEST, "Bad request: RPC commands must have at most one data part "
"(received " + std::to_string(m.data.size()) + ")"); "(received " + std::to_string(m.data.size()) + ")");
rpc_request request{}; rpc_request request{};
@ -218,7 +216,7 @@ omq_rpc::omq_rpc(cryptonote::core& core, core_rpc_server& rpc, const boost::prog
return std::move(v); return std::move(v);
} }
}, call.invoke(std::move(request), rpc_)); }, call.invoke(std::move(request), rpc_));
m.send_reply(LMQ_OK, std::move(result)); m.send_reply(OMQ_OK, std::move(result));
return; return;
} catch (const parse_error& e) { } catch (const parse_error& e) {
// This isn't really WARNable as it's the client fault; log at info level instead. // This isn't really WARNable as it's the client fault; log at info level instead.
@ -227,22 +225,22 @@ omq_rpc::omq_rpc(cryptonote::core& core, core_rpc_server& rpc, const boost::prog
// warnings that get generated deep inside epee, for example when passing a string or // warnings that get generated deep inside epee, for example when passing a string or
// number instead of a JSON object. If you want to find some, `grep number2 epee` (for // number instead of a JSON object. If you want to find some, `grep number2 epee` (for
// real). // real).
log::info(logcat, "LMQ RPC request '{}{}' called with invalid/unparseable data: {}", (call.is_public ? "rpc." : "admin."), name, e.what()); log::info(logcat, "OMQ RPC request '{}{}' called with invalid/unparseable data: {}", (call.is_public ? "rpc." : "admin."), name, e.what());
m.send_reply(LMQ_BAD_REQUEST, "Unable to parse request: "s + e.what()); m.send_reply(OMQ_BAD_REQUEST, "Unable to parse request: "s + e.what());
return; return;
} catch (const rpc_error& e) { } catch (const rpc_error& e) {
log::warning(logcat, "LMQ RPC request '{}{}' failed with: {}", (call.is_public ? "rpc." : "admin."), name, e.what()); log::warning(logcat, "OMQ RPC request '{}{}' failed with: {}", (call.is_public ? "rpc." : "admin."), name, e.what());
m.send_reply(LMQ_ERROR, e.what()); m.send_reply(OMQ_ERROR, e.what());
return; return;
} catch (const std::exception& e) { } catch (const std::exception& e) {
log::warning(logcat, "LMQ RPC request '{}{}' raised an exception: {}", (call.is_public ? "rpc." : "admin."), name, e.what()); log::warning(logcat, "OMQ RPC request '{}{}' raised an exception: {}", (call.is_public ? "rpc." : "admin."), name, e.what());
} catch (...) { } catch (...) {
log::warning(logcat, "LMQ RPC request '{}{}' raised an unknown exception", (call.is_public ? "rpc." : "admin."), name); log::warning(logcat, "OMQ RPC request '{}{}' raised an unknown exception", (call.is_public ? "rpc." : "admin."), name);
} }
// Don't include the exception message in case it contains something that we don't want go // Don't include the exception message in case it contains something that we don't want go
// back to the user. If we want to support it eventually we could add some sort of // back to the user. If we want to support it eventually we could add some sort of
// `rpc::user_visible_exception` that carries a message to send back to the user. // `rpc::user_visible_exception` that carries a message to send back to the user.
m.send_reply(LMQ_ERROR, "An exception occured while processing your request"); m.send_reply(OMQ_ERROR, "An exception occured while processing your request");
}); });
} }

View file

@ -40,7 +40,7 @@ namespace cryptonote::rpc {
void init_omq_options(boost::program_options::options_description& desc); void init_omq_options(boost::program_options::options_description& desc);
/** /**
* LMQ RPC server class. This doesn't actually hold the OxenMQ instance--that's in * OMQ RPC server class. This doesn't actually hold the OxenMQ instance--that's in
* cryptonote_core--but it works with it to add RPC endpoints, make it listen on RPC ports, and * cryptonote_core--but it works with it to add RPC endpoints, make it listen on RPC ports, and
* handles RPC requests. * handles RPC requests.
*/ */

View file

@ -13,13 +13,13 @@
namespace { namespace {
// LMQ RPC responses consist of [CODE, DATA] for code we (partially) mimic HTTP error codes: 200 // OMQ RPC responses consist of [CODE, DATA] for code we (partially) mimic HTTP error codes: 200
// means success, anything else means failure. (We don't have codes for Forbidden or Not Found // means success, anything else means failure. (We don't have codes for Forbidden or Not Found
// because those happen at the LMQ protocol layer). // because those happen at the OMQ protocol layer).
constexpr std::string_view constexpr std::string_view
LMQ_OK{"200"sv}, OMQ_OK{"200"sv},
LMQ_BAD_REQUEST{"400"sv}, OMQ_BAD_REQUEST{"400"sv},
LMQ_ERROR{"500"sv}; OMQ_ERROR{"500"sv};
} // anonymous namespace } // anonymous namespace
@ -46,7 +46,7 @@ OmqServer::set_omq(std::shared_ptr<oxenmq::OxenMQ> omq_in, wallet::rpc::Config c
omq->add_request_command(cmd.second->is_restricted ? "restricted" : "rpc", cmd.first, omq->add_request_command(cmd.second->is_restricted ? "restricted" : "rpc", cmd.first,
[name=std::string_view{cmd.first}, &call=*cmd.second, this](oxenmq::Message& m) { [name=std::string_view{cmd.first}, &call=*cmd.second, this](oxenmq::Message& m) {
if (m.data.size() > 1) if (m.data.size() > 1)
m.send_reply(LMQ_BAD_REQUEST, "Bad request: RPC commands must have at most one data part " m.send_reply(OMQ_BAD_REQUEST, "Bad request: RPC commands must have at most one data part "
"(received " + std::to_string(m.data.size()) + ")"); "(received " + std::to_string(m.data.size()) + ")");
rpc_request request{}; rpc_request request{};
@ -68,7 +68,7 @@ OmqServer::set_omq(std::shared_ptr<oxenmq::OxenMQ> omq_in, wallet::rpc::Config c
return std::move(v); return std::move(v);
} }
}, call.invoke(std::move(request), request_handler)); }, call.invoke(std::move(request), request_handler));
m.send_reply(LMQ_OK, std::move(result)); m.send_reply(OMQ_OK, std::move(result));
return; return;
} catch (const parse_error& e) { } catch (const parse_error& e) {
// This isn't really WARNable as it's the client fault; log at info level instead. // This isn't really WARNable as it's the client fault; log at info level instead.
@ -77,24 +77,24 @@ OmqServer::set_omq(std::shared_ptr<oxenmq::OxenMQ> omq_in, wallet::rpc::Config c
// warnings that get generated deep inside epee, for example when passing a string or // warnings that get generated deep inside epee, for example when passing a string or
// number instead of a JSON object. If you want to find some, `grep number2 epee` (for // number instead of a JSON object. If you want to find some, `grep number2 epee` (for
// real). // real).
std::cout << "LMQ RPC request '" << (call.is_restricted ? "restricted." : "rpc.") << name << "' called with invalid/unparseable data: " << e.what() << "\n"; std::cout << "OMQ RPC request '" << (call.is_restricted ? "restricted." : "rpc.") << name << "' called with invalid/unparseable data: " << e.what() << "\n";
m.send_reply(LMQ_BAD_REQUEST, "Unable to parse request: "s + e.what()); m.send_reply(OMQ_BAD_REQUEST, "Unable to parse request: "s + e.what());
return; return;
} catch (const rpc_error& e) { } catch (const rpc_error& e) {
std::cout << "LMQ RPC request '" << (call.is_restricted ? "restricted." : "rpc.") << name << "' failed with: " << e.what() << "\n"; std::cout << "OMQ RPC request '" << (call.is_restricted ? "restricted." : "rpc.") << name << "' failed with: " << e.what() << "\n";
m.send_reply(LMQ_ERROR, e.what()); m.send_reply(OMQ_ERROR, e.what());
return; return;
} catch (const std::exception& e) { } catch (const std::exception& e) {
std::cout << "LMQ RPC request '" << (call.is_restricted ? "restricted." : "rpc.") << name << "' " std::cout << "OMQ RPC request '" << (call.is_restricted ? "restricted." : "rpc.") << name << "' "
"raised an exception: " << e.what() << "\n"; "raised an exception: " << e.what() << "\n";
} catch (...) { } catch (...) {
std::cout << "LMQ RPC request '" << (call.is_restricted ? "restricted." : "rpc.") << name << "' " std::cout << "OMQ RPC request '" << (call.is_restricted ? "restricted." : "rpc.") << name << "' "
"raised an unknown exception" << "\n"; "raised an unknown exception" << "\n";
} }
// Don't include the exception message in case it contains something that we don't want go // Don't include the exception message in case it contains something that we don't want go
// back to the user. If we want to support it eventually we could add some sort of // back to the user. If we want to support it eventually we could add some sort of
// `rpc::user_visible_exception` that carries a message to send back to the user. // `rpc::user_visible_exception` that carries a message to send back to the user.
m.send_reply(LMQ_ERROR, "An exception occured while processing your request"); m.send_reply(OMQ_ERROR, "An exception occured while processing your request");
}); });
} }
} }