kea-custom-hooks
FeM custom hooks libraries for Kea DHCP
XmlRpcServer.cpp
Go to the documentation of this file.
1#include <cassert>
2#include <thread>
3#include <vector>
4
5#include <xmlrpc-c/registry.hpp>
6#include <xmlrpc-c/server_abyss.hpp>
7
8#include "XmlRpcServer.hpp"
9
10namespace
11{
15class RpcMethodHdlSs : public xmlrpc_c::method
16{
17public:
18 explicit RpcMethodHdlSs(std::function<std::optional<std::string>(const std::string&)>& handler)
19 : handler(handler)
20 {
21 _signature = "s:s";
22 }
23
24 void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* const retval) override
25 {
26 // We have one parameter in our RPC method signature
27 assert(params.size() == 1);
28 const std::string arg{params.getString(0)};
29
30 const std::optional<std::string> res = handler(arg);
31
32 if (res.has_value()) {
33 *retval = xmlrpc_c::value_string(res.value());
34 } else {
35 *retval = xmlrpc_c::value_nil();
36 }
37 }
38
39private:
40 std::function<std::optional<std::string>(const std::string&)> handler;
41};
42} // namespace
43
44namespace aai
45{
48{
57 explicit XmlRpcServerPrivate(uint16_t listen_port)
58 : rpc_server(xmlrpc_c::serverAbyss::constrOpt()
59 .registryP(&rpc_registry)
60 .portNumber(listen_port)
61 .serverOwnsSignals(false))
62 {}
66 XmlRpcServerPrivate(const struct sockaddr* sa, socklen_t sa_len)
67 : rpc_server(xmlrpc_c::serverAbyss::constrOpt()
68 .registryP(&rpc_registry)
69 .sockAddrP(sa)
70 .sockAddrLen(sa_len))
71 {}
74 {
75 if (rpc_server_thread && rpc_server_thread->joinable()) {
76 rpc_server_thread->join();
77 }
78 }
79
80 xmlrpc_c::registry rpc_registry{};
81 xmlrpc_c::serverAbyss rpc_server;
82 std::unique_ptr<std::thread> rpc_server_thread{nullptr};
83 bool has_started{false};
84};
85
86XmlRpcServer::XmlRpcServer(uint16_t listen_port)
87 : priv(std::make_unique<XmlRpcServerPrivate>(listen_port))
88{}
89
90XmlRpcServer::XmlRpcServer(const struct sockaddr* sa, socklen_t sa_len)
91 : priv(std::make_unique<XmlRpcServerPrivate>(sa, sa_len))
92{}
93
95{
96 stop();
97 priv.reset(nullptr);
98}
99
101{
102 if (priv->has_started) {
103 return;
104 }
105
106 assert(!priv->rpc_server_thread);
107 priv->rpc_server_thread = std::make_unique<std::thread>([this]() { priv->rpc_server.run(); });
108 priv->has_started = true;
109}
110
112{
113 if (!priv->has_started || !priv->rpc_server_thread) {
114 return;
115 }
116
117 priv->rpc_server.terminate();
118}
119
121 std::string_view name,
122 std::function<std::optional<std::string>(const std::string&)>
123 handler)
124{
125 priv->rpc_registry.addMethod(std::string{name},
126 static_cast<xmlrpc_c::method*>(new RpcMethodHdlSs{handler}));
127}
128} // namespace aai
XmlRpcServer(uint16_t listen_port)
Create an XML-RPC server which listens on all interfaces on the given port.
void register_method_handler(std::string_view name, std::function< std::optional< std::string >(const std::string &)> handler)
Register a method handler.
void stop()
Stop the XML-RPC server.
void start()
Start the XML-RPC server.
Private implementation of XmlRpcServer.
XmlRpcServerPrivate(uint16_t listen_port)
Constructor for private XmlRpcServer implementation.
XmlRpcServerPrivate(const struct sockaddr *sa, socklen_t sa_len)
Cosntructor for private XmlRpcServer implementation.
xmlrpc_c::serverAbyss rpc_server
std::unique_ptr< std::thread > rpc_server_thread
xmlrpc_c::registry rpc_registry
XmlRpcServerPrivate(const XmlRpcServerPrivate &)=delete