8 #define DRIPLINE_API_EXPORTS 21 #include "pybind11/pybind11.h" 22 #include "pybind11/pytypes.h" 25 LOGGER(
dlog,
"endpoint" );
39 f_name( a_orig.f_name ),
40 f_service( a_orig.f_service ),
41 f_lockout_tag( a_orig.f_lockout_tag ),
42 f_lockout_key( a_orig.f_lockout_key )
46 f_name(
std::move(a_orig.f_name) ),
47 f_service(
std::move(a_orig.f_service) ),
48 f_lockout_tag(
std::move(a_orig.f_lockout_tag) ),
49 f_lockout_key(
std::move(a_orig.f_lockout_key) )
57 f_name = a_orig.f_name;
58 f_service = a_orig.f_service;
59 f_lockout_tag = a_orig.f_lockout_tag;
60 f_lockout_key = a_orig.f_lockout_key;
66 f_name = std::move(a_orig.f_name);
67 f_service = std::move(a_orig.f_service);
68 f_lockout_tag = std::move(a_orig.f_lockout_tag);
69 f_lockout_key = std::move(a_orig.f_lockout_key);
94 auto t_replier = [&t_reply, &a_request,
this](){
96 if( a_request->reply_to().empty() )
98 LWARN(
dlog,
"Not sending reply (reply-to empty)\n" <<
99 " Return code: " << t_reply->get_return_code() <<
'\n' <<
100 " Return message: " << t_reply->return_message() <<
'\n' <<
101 " Payload:\n" << t_reply->payload() );
111 if( ! a_request->get_is_valid() )
113 std::string t_message(
"Request message was not valid" );
115 if( a_request->payload().is_node() )
117 const scarab::param_node& t_payload = a_request->payload().as_node();
118 if( t_payload.has(
"error") ) t_message +=
"; " + t_payload[
"error"]().as_string();
124 if( ! a_request->get_lockout_key_valid() )
129 switch( a_request->get_message_operation() )
168 catch(
const pybind11::error_already_set& e )
172 if( std::string(e.what()).substr(0, throw_reply::py_throw_reply_keyword().size()) == throw_reply::py_throw_reply_keyword() )
174 reply_cache* t_reply_cache = reply_cache::get_instance();
191 LERROR(
dlog,
"Caught exception from Python: " << e.what() );
198 catch(
const std::exception& e )
200 LERROR(
dlog,
"Caught exception: " << e.what() );
214 if( a_message->is_request() )
218 else if( a_message->is_alert() )
222 else if( a_message->is_reply() )
236 LWARN(
dlog,
"Cannot send reply because the service pointer is not set" );
240 LDEBUG(
dlog,
"Sending reply message to <" << a_reply->routing_key() <<
">:\n" <<
241 " Return code: " << a_reply->get_return_code() <<
'\n' <<
242 " Return message: " << a_reply->return_message() <<
'\n' <<
243 " Payload:\n" << a_reply->payload() );
248 t_receive_reply = f_service->send( a_reply );
252 LWARN(
dlog,
"Operating in offline mode; message not sent" );
257 LERROR(
dlog,
"Unable to connect to the broker:\n" << e.what() );
262 LERROR(
dlog,
"Dripline error while sending reply:\n" << e.what() );
266 if( ! t_receive_reply->f_successful_send )
268 LERROR(
dlog,
"Failed to send reply:\n" + t_receive_reply->f_send_error_message );
277 throw dripline_error() <<
"Base endpoint does not handle reply messages";
282 throw dripline_error() <<
"Base endpoint does not handle alert messages";
287 LDEBUG(
dlog,
"Run operation request received" );
291 std::stringstream t_conv;
292 t_conv << a_request->lockout_key();
293 std::string t_message(
"Request denied due to lockout (key used: " + t_conv.str() +
")" );
294 LINFO(
dlog, t_message );
303 LDEBUG(
dlog,
"Get operation request received" );
305 std::string t_query_type;
306 if( ! a_request->parsed_specifier().empty() )
308 t_query_type = a_request->parsed_specifier().front();
311 if( t_query_type ==
"is-locked" )
313 a_request->parsed_specifier().pop_front();
322 LDEBUG(
dlog,
"Set request received" );
326 std::stringstream t_conv;
327 t_conv << a_request->lockout_key();
328 std::string t_message(
"Request denied due to lockout (key used: " + t_conv.str() +
")" );
329 LINFO(
dlog, t_message );
338 LDEBUG(
dlog,
"Cmd request received" );
340 std::string t_instruction;
341 if( ! a_request->parsed_specifier().empty() )
343 t_instruction = a_request->parsed_specifier().front();
349 if( !
authenticate( a_request->lockout_key() ) && t_instruction !=
"unlock" && t_instruction !=
"ping" && t_instruction !=
"set_condition" )
351 std::stringstream t_conv;
352 t_conv << a_request->lockout_key();
353 std::string t_message(
"Request denied due to lockout (key used: " + t_conv.str() +
")" );
354 LINFO(
dlog, t_message );
358 if( t_instruction ==
"lock" )
360 a_request->parsed_specifier().pop_front();
363 else if( t_instruction ==
"unlock" )
365 a_request->parsed_specifier().pop_front();
368 else if( t_instruction ==
"ping" )
370 a_request->parsed_specifier().pop_front();
373 else if( t_instruction ==
"set_condition" )
375 a_request->parsed_specifier().pop_front();
386 else f_lockout_key = a_key;
387 f_lockout_tag = a_tag;
388 return f_lockout_key;
394 if( ! a_force && a_key != f_lockout_key )
return false;
396 f_lockout_tag.clear();
402 LDEBUG(
dlog,
"Authenticating with key <" << a_key <<
">" );
410 if( t_new_key.is_nil() )
415 scarab::param_ptr_t t_payload_ptr(
new scarab::param_node() );
416 scarab::param_node& t_payload_node = t_payload_ptr->as_node();
418 return a_request->reply(
dl_success(),
"Server is now locked", std::move(t_payload_ptr) );
428 bool t_force = a_request->payload().get_value(
"force",
false );
432 return a_request->reply(
dl_success(),
"Server unlocked" );
445 scarab::param_ptr_t t_reply_payload(
new scarab::param_node() );
446 scarab::param_node& t_reply_node = t_reply_payload->as_node();
447 t_reply_node.add(
"is_locked", t_is_locked );
448 if( t_is_locked ) t_reply_node.add(
"tag", f_lockout_tag );
449 return a_request->reply(
dl_success(),
"Checked lock status", std::move(t_reply_payload) );
454 return a_request->reply(
dl_success(),
"Hello, " + a_request->sender_exe() );
bool authenticate(const uuid_t &a_key) const
Returns true if the server is unlocked or if it's locked and the key matches the lockout key; returns...
reply_ptr_t __do_cmd_request(const request_ptr_t a_request)
const return_code & ret_code() const noexcept
virtual reply_ptr_t do_run_request(const request_ptr_t a_request)
reply_ptr_t submit_request_message(const request_ptr_t a_request)
Directly submit a request message to this endpoint.
const scarab::param_ptr_t & get_payload_ptr() const noexcept
void sort_message(const message_ptr_t a_request)
reply_ptr_t handle_is_locked_request(const request_ptr_t a_request)
std::shared_ptr< sent_msg_pkg > sent_msg_pkg_ptr
std::shared_ptr< msg_request > request_ptr_t
virtual void on_alert_message(const alert_ptr_t a_alert)
Dripline-specific errors.
std::shared_ptr< msg_alert > alert_ptr_t
virtual unsigned rc_value() const =0
uuid_t enable_lockout(const scarab::param_node &a_tag)
enable lockout with randomly-generated key
A singleton throw_reply object used to transfer throw_reply information to C++ from other implementat...
reply_ptr_t __do_get_request(const request_ptr_t a_request)
static scarab::logger dlog("endpoint")
virtual reply_ptr_t do_get_request(const request_ptr_t a_request)
bool disable_lockout(const uuid_t &a_key, bool a_force=false)
std::string string_from_uuid(const uuid_t &a_id)
Generates a string representation of the provided UUID.
reply_ptr_t __do_run_request(const request_ptr_t a_request)
boost::uuids::uuid uuid_t
Universally-unique-identifier type containing 16 hexadecimal characters.
reply_ptr_t handle_unlock_request(const request_ptr_t a_request)
static scarab::logger dlog("agent")
Error indicating a problem with the connection to the broker.
reply_ptr_t handle_ping_request(const request_ptr_t a_request)
bool check_key(const uuid_t &a_key) const
std::shared_ptr< msg_reply > reply_ptr_t
reply_ptr_t handle_set_condition_request(const request_ptr_t a_request)
uuid_t generate_random_uuid()
Generates a UUID containing random numbers (RNG is a Mersenne Twister)
endpoint(const std::string &a_name)
Object that can be thrown while processing a request to send a reply.
virtual reply_ptr_t do_set_request(const request_ptr_t a_request)
reply_ptr_t __do_set_request(const request_ptr_t a_request)
void submit_reply_message(const reply_ptr_t a_reply)
Directly submit a reply message to this endpoint.
endpoint & operator=(const endpoint &a_orig)
virtual reply_ptr_t do_cmd_request(const request_ptr_t a_request)
uuid_t generate_nil_uuid()
Generates a UUID containing all 0s.
virtual reply_ptr_t on_request_message(const request_ptr_t a_request)
Default request handler; passes request to initial request functions.
const std::string & return_message() const noexcept
std::shared_ptr< message > message_ptr_t
Basic Dripline object capable of receiving and acting on messages.
virtual reply_ptr_t __do_handle_set_condition_request(const request_ptr_t a_request)
Default set-condition: no action taken; override for different behavior.
void set_payload(scarab::param_ptr_t a_payload)
void submit_alert_message(const alert_ptr_t a_alert)
Directly submit an alert message to this endpoint.
virtual void send_reply(reply_ptr_t a_reply) const
virtual void on_reply_message(const reply_ptr_t a_reply)
reply_ptr_t handle_lock_request(const request_ptr_t a_request)