rad  5.1.0
request.hpp
Go to the documentation of this file.
1 
14 #ifndef RAD_MAL_REQUEST_HPP
15 #define RAD_MAL_REQUEST_HPP
16 
17 #include <rad/assert.hpp>
18 #include <rad/logger.hpp>
19 #include <rad/exceptions.hpp>
20 
21 #include <mal/rr/ServerContextProvider.hpp>
22 #include <mal/utility/future.hpp>
23 #include <mal/MalException.hpp>
24 
25 #include <type_traits>
26 #include <string>
27 
28 namespace rad {
29 namespace cii {
30 
38 template <typename REP_TYPE, typename REQ_TYPE = void>
39 class Request {
40  public:
48  explicit Request(const REQ_TYPE& req_payload)
49  : m_req_payload(req_payload),
50  m_rep_promise(std::make_shared<elt::mal::promise<REP_TYPE>>()) {
52  }
53 
58  Request(const Request&) = default;
59  Request(Request&&) noexcept(std::is_nothrow_move_constructible<REQ_TYPE>()) = default;
61 
66  Request& operator=(const Request&) = default;
67  Request& operator=(Request&&) noexcept(std::is_nothrow_move_assignable_v<REQ_TYPE>) = default;
69 
76  const REQ_TYPE& GetRequestPayload() const {
78  return m_req_payload;
79  }
80 
87  elt::mal::future<REP_TYPE> GetReplyFuture() const {
89  RAD_ASSERTPTR(m_rep_promise);
90  return m_rep_promise->get_future();
91  }
92 
99  void SetReplyValue(const REP_TYPE& reply) const {
100  RAD_TRACE(GetLogger());
101  RAD_ASSERTPTR(m_rep_promise);
102  try {
103  m_rep_promise->set_value(reply);
104  } catch(boost::wrapexcept<boost::promise_already_satisfied>& e) {
105  RAD_LOG_THROW(rad::Exception, GetLogger(), "Reply or Exception was already sent.");
106  }
107  }
108 
117  template <class T>
118  void SetException(const T& e) const {
119  // EICSSW-1303 Exception type T must derive from elt::mal::MalException
120  static_assert(std::is_base_of_v<elt::mal::MalException, T>,
121  "T must derive from MalException");
122  RAD_TRACE(GetLogger());
123  RAD_ASSERTPTR(m_rep_promise);
124  try {
125  m_rep_promise->set_exception(boost::copy_exception(e));
126  } catch(boost::wrapexcept<boost::promise_already_satisfied>& e1) {
127  RAD_LOG_THROW(rad::Exception, GetLogger(), "Reply or Exception was already sent.");
128  }
129  }
130 
131  private:
132  REQ_TYPE m_req_payload; // Payload associated to the request.
133  /*
134  * We need a shared pointer to make Request copyable so
135  * it can be used as payload for the rad::Event class.
136  */
137  std::shared_ptr<elt::mal::promise<REP_TYPE>>
138  m_rep_promise; // Pointer to the promise associated to the reply.
139 };
140 
147 template <class REP_TYPE>
148 class Request<REP_TYPE, void> {
149  public:
154  Request() : m_rep_promise(std::make_shared<elt::mal::promise<REP_TYPE>>()) {
155  RAD_TRACE(GetLogger());
156  }
157 
162  Request(const Request&) = default;
163  Request(Request&&) noexcept = default;
165 
170  Request& operator=(const Request&) = default;
171  Request& operator=(Request&&) noexcept = default;
173 
180  elt::mal::future<REP_TYPE> GetReplyFuture() const {
181  RAD_TRACE(GetLogger());
182  RAD_ASSERTPTR(m_rep_promise);
183  return m_rep_promise->get_future();
184  }
185 
192  void SetReplyValue(const REP_TYPE& reply) const {
193  RAD_TRACE(GetLogger());
194  RAD_ASSERTPTR(m_rep_promise);
195  try {
196  m_rep_promise->set_value(reply);
197  } catch(boost::wrapexcept<boost::promise_already_satisfied>& e) {
198  RAD_LOG_THROW(rad::Exception, GetLogger(), "Reply or Exception was already sent.");
199  }
200  }
201 
209  template <class T>
210  void SetException(const T& e) const {
211  // EICSSW-1303 Exception type T must derive from elt::mal::MalException
212  static_assert(std::is_base_of_v<elt::mal::MalException, T>,
213  "T must derive from MalException");
214  RAD_TRACE(GetLogger());
215  RAD_ASSERTPTR(m_rep_promise);
216  try {
217  m_rep_promise->set_exception(boost::copy_exception(e));
218  } catch(boost::wrapexcept<boost::promise_already_satisfied>& e1) {
219  RAD_LOG_THROW(rad::Exception, GetLogger(), "Reply or Exception was already sent.");
220  }
221  }
222 
223  private:
224  /*
225  * We need a shared pointer to make Request copyable so
226  * it can be used as payload for the rad::Event class.
227  */
228  std::shared_ptr<elt::mal::promise<REP_TYPE>>
229  m_rep_promise; // Pointer to the promise associated to the reply.
230 };
231 
239 template <typename REP_TYPE, typename REQ_TYPE = void>
240 class RequestAmi {
241  public:
249  explicit RequestAmi(const REQ_TYPE& req_payload) {
250  RAD_TRACE(GetLogger());
251  m_server_ami = elt::mal::rr::ServerContextProvider::getInstance<
252  elt::mal::rr::ServerContext<REP_TYPE>>()
253  .createAmi();
254  }
258  // @{
259  RequestAmi(const RequestAmi&) = default;
260  RequestAmi(RequestAmi&&) noexcept(std::is_nothrow_move_constructible<REQ_TYPE>()) = default;
261  // @}
262 
266  // @{
267  RequestAmi& operator=(const RequestAmi&) = default;
268  RequestAmi&
269  operator=(RequestAmi&&) noexcept(std::is_nothrow_move_assignable_v<REQ_TYPE>) = default;
270  // @}
271 
272  const REQ_TYPE& GetRequestPayload() const {
273  RAD_TRACE(GetLogger());
274  return m_req_payload;
275  }
276 
284  bool SetPartialReplyValue(const REP_TYPE& reply) const {
285  RAD_TRACE(GetLogger());
286  return m_server_ami->complete(reply);
287  }
288 
296  bool SetFinalReplyValue(const REP_TYPE& reply) const {
297  RAD_TRACE(GetLogger());
298  return m_server_ami->completed(reply);
299  }
300 
306  std::shared_ptr<::elt::mal::rr::Ami<REP_TYPE>> GetAmiServer() {
307  RAD_TRACE(GetLogger());
308  return m_server_ami;
309  }
310 
311  private:
312  REQ_TYPE m_req_payload; // Payload associated to the request.
313  std::shared_ptr<::elt::mal::rr::Ami<REP_TYPE>>
314  m_server_ami; // Pointer to the AMI object dealing with multiple replies.
315 };
316 
323 template <class REP_TYPE>
324 class RequestAmi<REP_TYPE, void> {
325  public:
331  RAD_TRACE(GetLogger());
332  m_server_ami = elt::mal::rr::ServerContextProvider::getInstance<
333  elt::mal::rr::ServerContext<REP_TYPE>>()
334  .createAmi();
335  }
336 
340  // @{
341  RequestAmi(const RequestAmi&) = default;
342  RequestAmi(RequestAmi&&) noexcept = default;
343  // @}
344 
348  // @{
349  RequestAmi& operator=(const RequestAmi&) = default;
350  RequestAmi& operator=(RequestAmi&&) noexcept = default;
351  // @}
352 
360  bool SetPartialReplyValue(const REP_TYPE& reply) const {
361  RAD_TRACE(GetLogger());
362  return m_server_ami->complete(reply);
363  }
364 
372  bool SetFinalReplyValue(const REP_TYPE& reply) const {
373  RAD_TRACE(GetLogger());
374  return m_server_ami->completed(reply);
375  }
376 
382  std::shared_ptr<::elt::mal::rr::Ami<REP_TYPE>> GetAmiServer() {
383  RAD_TRACE(GetLogger());
384  return m_server_ami;
385  }
386 
387  private:
388  std::shared_ptr<::elt::mal::rr::ServerAmi<REP_TYPE>>
389  m_server_ami; // Pointer to the AMI object dealing with multiple replies.
390 };
391 
392 } // namespace cii
393 } // namespace rad
394 
395 #endif // RAD_MAL_REQUEST_HPP
Assert header file.
#define RAD_ASSERTPTR(a)
Definition: assert.hpp:19
Base class for the exceptions thrown by RAD and its users.
Definition: exceptions.hpp:53
RequestAmi(const RequestAmi &)=default
RequestAmi()
Definition: request.hpp:330
bool SetFinalReplyValue(const REP_TYPE &reply) const
Definition: request.hpp:372
std::shared_ptr<::elt::mal::rr::Ami< REP_TYPE > > GetAmiServer()
Definition: request.hpp:382
RequestAmi(RequestAmi &&) noexcept=default
Definition: request.hpp:240
bool SetPartialReplyValue(const REP_TYPE &reply) const
Definition: request.hpp:284
RequestAmi(const REQ_TYPE &req_payload)
Definition: request.hpp:249
RequestAmi(RequestAmi &&) noexcept(std::is_nothrow_move_constructible< REQ_TYPE >())=default
bool SetFinalReplyValue(const REP_TYPE &reply) const
Definition: request.hpp:296
RequestAmi(const RequestAmi &)=default
const REQ_TYPE & GetRequestPayload() const
Definition: request.hpp:272
std::shared_ptr<::elt::mal::rr::Ami< REP_TYPE > > GetAmiServer()
Definition: request.hpp:306
void SetException(const T &e) const
Definition: request.hpp:210
Request(const Request &)=default
Request(Request &&) noexcept=default
Request()
Definition: request.hpp:154
void SetReplyValue(const REP_TYPE &reply) const
Definition: request.hpp:192
Definition: request.hpp:39
elt::mal::future< REP_TYPE > GetReplyFuture() const
Definition: request.hpp:87
void SetException(const T &e) const
Definition: request.hpp:118
Request(const Request &)=default
Request(Request &&) noexcept(std::is_nothrow_move_constructible< REQ_TYPE >())=default
void SetReplyValue(const REP_TYPE &reply) const
Definition: request.hpp:99
const REQ_TYPE & GetRequestPayload() const
Definition: request.hpp:76
Request(const REQ_TYPE &req_payload)
Definition: request.hpp:48
Logger class.
#define RAD_TRACE(logger)
Definition: logger.hpp:24
Exception classes header file.
#define RAD_LOG_THROW(exceptionType_t, logger, msg)
Throw exception with information about the throw location.
Definition: exceptions.hpp:356
Definition: actionsApp.cpp:20
log4cplus::Logger & GetLogger()
Definition: logger.cpp:70
Definition: errors.hpp:58