RTC Toolkit 6.0.0
Loading...
Searching...
No Matches
stdComponent.hpp
Go to the documentation of this file.
1
11
12#ifndef RTCTK_COMPONENTFRAMEWORK_STDCOMPONENT_HPP
13#define RTCTK_COMPONENTFRAMEWORK_STDCOMPONENT_HPP
14
16#include <rtctk/componentFramework/events.rad.hpp>
26
27#include <mal/Cii.hpp>
28
29#include <memory>
30#include <string>
31
33
37class LogInfo : public stdif::LogInfo {
38public:
39 LogInfo() = default;
40
41 explicit LogInfo(const std::string& level, const std::string& logger = "")
42 : m_logger(logger), m_level(level) {
43 }
44
45 std::string getLogger() const override {
46 return m_logger;
47 }
48
49 void setLogger(const std::string& logger) override {
50 m_logger = logger;
51 }
52
53 std::string getLevel() const override {
54 return m_level;
55 }
56
57 void setLevel(const std::string& level) override {
58 m_level = level;
59 }
60
61 bool hasKey() const override {
62 return false;
63 }
64
65 bool keyEquals(const stdif::LogInfo& other) const override {
66 return false;
67 }
68
69 std::unique_ptr<stdif::LogInfo> clone() const override {
70 return std::make_unique<LogInfo>(m_logger, m_level);
71 }
72
73 std::unique_ptr<stdif::LogInfo> cloneKey() const override {
74 return std::make_unique<LogInfo>(m_logger, m_level);
75 }
76
77private:
78 std::string m_logger;
79 std::string m_level;
80};
81
83
84// this we reply over MAL for commands that succeeds
85inline const std::string STD_OK_REPLY = "OK";
86
88
89// High level exception types returned via MAL
90
95class StdIfRequestAborted : public stdif::ExceptionErr {
96public:
97 static constexpr int32_t ERROR_CODE = 11;
98 StdIfRequestAborted() : stdif::ExceptionErr("Request aborted.", ERROR_CODE) {
99 }
100};
101
106class StdIfRequestRejected : public stdif::ExceptionErr {
107public:
111 static constexpr int32_t ERROR_CODE = 10;
112 StdIfRequestRejected(const std::string& request_id, const std::string& state_id)
113 : stdif::ExceptionErr("Request " + request_id + " rejected in state " + state_id,
114 ERROR_CODE) {
115 }
116};
117
122class StdIfRequestFailed : public stdif::ExceptionErr {
123public:
127 static constexpr int32_t ERROR_CODE = 501;
128 explicit StdIfRequestFailed(const std::string& message)
129 : stdif::ExceptionErr(message, ERROR_CODE) {
130 }
131};
132
148 public:
149 virtual void ActivityStarting(StopToken st) {};
153 };
154
159 public:
161 : m_replier(replier), m_engine(engine) {
162 }
163
164 virtual ~InputStage() = default;
165
166 virtual void Start() {
167 // exit event is used by SIGTERM, SIGINT and SIGHUP
168 m_engine.RegisterExitEvent(std::make_unique<events::Exit>());
169 // stdif MAL commands
172 }
173
174 protected:
177 };
178
183 public:
185 // Handlers ###################################################################
186
187 engine.RegisterRejectHandler<events::Init, StdIfRequestRejected>();
188 engine.RegisterRejectHandler<events::Stop, StdIfRequestRejected>();
189 engine.RegisterRejectHandler<events::Reset, StdIfRequestRejected>();
190 engine.RegisterRejectHandler<events::Enable, StdIfRequestRejected>();
191 engine.RegisterRejectHandler<events::Disable, StdIfRequestRejected>();
192 engine.RegisterRejectHandler<events::GetState, StdIfRequestRejected>();
193 engine.RegisterRejectHandler<events::Exit, StdIfRequestRejected>();
194
195 m_success_handler = [this] { m_engine.PostEvent(std::make_unique<events::Done>()); };
196
197 m_error_handler = [this](std::exception_ptr eptr) {
198 m_engine.PostEvent(std::make_unique<events::Error>(std::move(eptr)));
199 };
200
201 // Reset ######################################################################
202
203 engine.RegisterAction("ActionStartingEntry", [this](auto c) {
205 });
206
207 engine.RegisterAction("ActionStartingDone", [this](auto c) {
208 if (m_tmp_request) {
209 m_tmp_request->SetReplyValue(STD_OK_REPLY);
210 m_tmp_request = nullptr;
211 }
212 });
213
214 // Init ######################################################################
215
216 engine.RegisterAction("ActionInitialisingEntry", [this](auto c) {
218 });
219
220 engine.RegisterAction("ActionInitialisingDone", [this](auto c) {
221 if (m_tmp_request) {
222 m_tmp_request->SetReplyValue(STD_OK_REPLY);
223 m_tmp_request = nullptr;
224 }
225 });
226
227 engine.RegisterAction("ActionInitialisingFailed", [this](auto c) {
228 if (auto eptr = GetPayloadNothrow<events::Error>(c); eptr) {
229 if (m_tmp_request) {
230 m_tmp_request->SetException(
232 m_tmp_request = nullptr;
233 }
234 }
235 });
236
237 engine.RegisterAction("ActionInitialisingStopped", [this](auto c) {
239 if (req == nullptr) {
240 // no event or request
241 return;
242 }
243 if (m_tmp_request) {
244 m_tmp_request->SetException(StdIfRequestAborted());
245 m_tmp_request = nullptr;
246 }
247 req->SetReplyValue(STD_OK_REPLY);
248 });
249
250 engine.RegisterAction("ActionInitialisingRestarted", [this](auto c) {
252 if (req == nullptr) {
253 // no event or request
254 return;
255 }
256 if (m_tmp_request) {
257 m_tmp_request->SetException(StdIfRequestAborted());
258 m_tmp_request = nullptr;
259 }
260 m_tmp_request = req;
261 });
262
263 // Enable ######################################################################
264
265 engine.RegisterAction("ActionEnablingEntry", [this](auto c) {
267 });
268
269 engine.RegisterAction("ActionEnablingDone", [this](auto c) {
270 if (m_tmp_request) {
271 m_tmp_request->SetReplyValue(STD_OK_REPLY);
272 m_tmp_request = nullptr;
273 }
274 });
275
276 engine.RegisterAction("ActionEnablingFailed", [this](auto c) {
277 if (auto eptr = GetPayloadNothrow<events::Error>(c); eptr) {
278 if (m_tmp_request) {
279 m_tmp_request->SetException(
281 m_tmp_request = nullptr;
282 }
283 }
284 });
285
286 // Disable #####################################################################
287
288 engine.RegisterAction("ActionDisablingEntry", [this](auto c) {
290 });
291
292 engine.RegisterAction("ActionDisablingDone", [this](auto c) {
293 if (m_tmp_request) {
294 m_tmp_request->SetReplyValue(STD_OK_REPLY);
295 m_tmp_request = nullptr;
296 }
297 });
298
299 engine.RegisterAction("ActionDisablingFailed", [this](auto c) {
300 if (auto eptr = GetPayloadNothrow<events::Error>(c); eptr) {
301 if (m_tmp_request) {
302 m_tmp_request->SetException(
304 m_tmp_request = nullptr;
305 }
306 }
307 });
308
309 // Exit #####################################################################
310
311 engine.RegisterAction("ActionExit", [this](auto c) {
313 if (req == nullptr) {
314 // no event or request
315 return;
316 }
317 req->SetReplyValue(STD_OK_REPLY);
318 m_engine.Stop();
319 });
320
321 // GetState #####################################################################
322
323 engine.RegisterAction("ActionGetState", [this](auto c) {
325 if (req == nullptr) {
326 // no event or request
327 return;
328 }
329 req->SetReplyValue(m_engine.GetState());
330 });
331
332 // GetStatus #####################################################################
333
334 engine.RegisterAction("ActionGetStatus", [this](auto c) {
336 if (req == nullptr) {
337 // no event or request
338 return;
339 }
340 req->SetReplyValue(m_engine.GetState());
341 });
342
343 // GetVersion #####################################################################
345 engine.RegisterAction("ActionGetVersion", [this](auto c) {
347 if (req == nullptr) {
348 // no event or request
349 return;
350 }
351 // cppcheck-suppress syntaxError
352 req->SetReplyValue(VERSION);
353 });
354
355 // SetLogLevel #####################################################################
356
357 engine.RegisterAction("ActionSetLogLevel", [this](auto c) {
359 if (req == nullptr) {
360 // no event or request
361 return;
362 }
363 auto loginfo = req->GetRequestPayload();
364 auto selected_logger = loginfo->getLogger();
365 auto& logger = GetLogger(selected_logger);
366 log4cplus::LogLevelManager llm;
367 auto selected_ll = llm.fromString(loginfo->getLevel());
368 if (selected_ll == log4cplus::NOT_SET_LOG_LEVEL) {
369 req->SetException(StdIfRequestFailed("Invalid LogLevel specified"));
370 } else {
371 logger.setLogLevel(selected_ll);
372 LOG4CPLUS_INFO(GetLogger("rtctk"),
373 "Log Level of logger '" << loginfo->getLogger() << "' set to '"
374 << llm.toString(logger.getLogLevel())
375 << "'");
376 req->SetReplyValue(STD_OK_REPLY);
377 }
378 });
379
380 // Activities #####################################################################
381
382 m_engine.RegisterActivity(
383 "ActivityStarting",
384 [this](StopToken stop_token) { m_logic.ActivityStarting(stop_token); },
387
388 m_engine.RegisterActivity(
389 "ActivityInitialising",
390 [this](StopToken stop_token) { m_logic.ActivityInitialising(stop_token); },
393
394 m_engine.RegisterActivity(
395 "ActivityEnabling",
396 [this](StopToken stop_token) { m_logic.ActivityEnabling(stop_token); },
399
400 m_engine.RegisterActivity(
401 "ActivityDisabling",
402 [this](StopToken stop_token) { m_logic.ActivityDisabling(stop_token); },
405 }
406
407 virtual ~OutputStage() = default;
408
409 protected:
412 std::shared_ptr<rad::cii::Request<std::string, void>> m_tmp_request;
413 std::function<void()> m_success_handler;
414 std::function<void(std::exception_ptr)> m_error_handler;
415 };
416
421 public:
423 // clang-format off
424 mm.AddState(Initial, "Initial");
425 mm.AddState(Parallel, "On");
426 mm.AddState(Final, "Off");
427
428 mm.AddState(Composite, "On:", "On");
429 mm.AddState(Initial, "On::Initial", "On:");
430 mm.AddState(Composite, "On::NotOperational", "On:");
431 mm.AddState(Simple, "On::Operational", "On:");
432
433 mm.AddState(Initial, "On::NotOperational::Initial", "On::NotOperational");
434 mm.AddState(Simple, "On::NotOperational::NotReady", "On::NotOperational");
435 mm.AddState(Simple, "On::NotOperational::Ready", "On::NotOperational");
436
437 mm.AddTrans("Initial" , "On");
438 mm.AddTrans("On" , "Off" , "events.Exit", "" ,"ActionExit");
439 mm.AddTrans("On" , "" , "events.GetState", "" ,"ActionGetState");
440 mm.AddTrans("On" , "" , "events.GetStatus", "" ,"ActionGetStatus");
441 mm.AddTrans("On" , "" , "events.GetVersion", "" ,"ActionGetVersion");
442 mm.AddTrans("On" , "" , "events.SetLogLevel","" ,"ActionSetLogLevel");
443 mm.AddTrans("On" , "On" , "events.Reset");
444 mm.AddTrans("On::Initial" , "On::NotOperational");
445
446 mm.AddState(Simple, "On::NotOperational::Starting", "On::NotOperational", "ActivityStarting" ,"ActionStartingEntry");
447
448 mm.AddTrans("On::NotOperational::Initial" , "On::NotOperational::Starting");
449 mm.AddTrans("On::NotOperational::Starting" , "On::NotOperational::NotReady" , "events.Done", "" ,"ActionStartingDone");
450
451 mm.AddState(Simple, "On::NotOperational::Initialising", "On::NotOperational", "ActivityInitialising" ,"ActionInitialisingEntry");
452
453 mm.AddTrans("On::NotOperational::NotReady" , "On::NotOperational::Initialising" , "events.Init");
454 mm.AddTrans("On::NotOperational::Initialising" , "On::NotOperational::Ready" , "events.Done", "" ,"ActionInitialisingDone");
455 mm.AddTrans("On::NotOperational::Initialising" , "On::NotOperational::NotReady" , "events.Error", "" ,"ActionInitialisingFailed");
456 mm.AddTrans("On::NotOperational::Initialising" , "On::NotOperational::NotReady" , "events.Stop", "" ,"ActionInitialisingStopped");
457 mm.AddTrans("On::NotOperational::Initialising" , "On::NotOperational::Initialising" , "events.Init", "" ,"ActionInitialisingRestarted");
458 mm.AddTrans("On::NotOperational::Ready" , "On::NotOperational::Initialising" , "events.Init");
459
460 mm.AddState(Simple, "On::NotOperational::Enabling", "On::NotOperational", "ActivityEnabling" ,"ActionEnablingEntry");
461
462 mm.AddTrans("On::NotOperational::Ready" , "On::NotOperational::Enabling" , "events.Enable");
463 mm.AddTrans("On::NotOperational::Enabling" , "On::Operational" , "events.Done", "" ,"ActionEnablingDone");
464 mm.AddTrans("On::NotOperational::Enabling" , "On::NotOperational::Ready" , "events.Error", "" ,"ActionEnablingFailed");
465 // TODO, do we want enabling to be stopable?
466 //mm.AddTrans("On::NotOperational::Enabling" , "On::NotOperational::Ready" , "events.Stop" );
467
468 mm.AddState(Simple, "On::NotOperational::Disabling", "On::NotOperational", "ActivityDisabling" ,"ActionDisablingEntry");
469 mm.AddTrans("On::Operational" , "On::NotOperational::Disabling" , "events.Disable");
470 mm.AddTrans("On::NotOperational::Disabling" , "On::NotOperational::Ready" , "events.Done", "" ,"ActionDisablingDone");
471 mm.AddTrans("On::NotOperational::Disabling" , "On::NotOperational::Ready" , "events.Error", "" ,"ActionDisablingFailed");
472 // clang-format on
473 }
474 };
475};
476
477} // namespace rtctk::componentFramework
478
479#endif // RTCTK_COMPONENTFRAMEWORK_STDCOMPONENT_HPP
Class that handles reception of commands using MAL.
Definition commandReplier.hpp:29
static void Register(CommandReplier &replier, StateMachineEngine &engine)
Definition introspectionImpl.hpp:38
std::string getLevel() const override
Definition stdComponent.hpp:53
std::unique_ptr< stdif::LogInfo > cloneKey() const override
Definition stdComponent.hpp:73
std::string getLogger() const override
Definition stdComponent.hpp:45
bool hasKey() const override
Definition stdComponent.hpp:61
std::unique_ptr< stdif::LogInfo > clone() const override
Definition stdComponent.hpp:69
void setLevel(const std::string &level) override
Definition stdComponent.hpp:57
LogInfo(const std::string &level, const std::string &logger="")
Definition stdComponent.hpp:41
bool keyEquals(const stdif::LogInfo &other) const override
Definition stdComponent.hpp:65
void setLogger(const std::string &logger) override
Definition stdComponent.hpp:49
ModelBuilderBase(StateMachineEngine &engine)
Definition modelBuilderBase.hpp:36
ModelManipulator mm
Definition modelBuilderBase.hpp:78
Adapter object intended to be used in contexts without direct access to the output-stream object.
Definition exceptions.hpp:168
std::string Str() const
Convenience function for constructing a std::string from the exception.
Definition exceptions.hpp:186
Definition stateMachineEngine.hpp:34
void RegisterAction(const std::string &id, ActionMethod action)
Register action.
Definition stateMachineEngine.cpp:85
void RegisterRejectHandler(const std::string &id, RejectMethod reject)
Register reject handler.
Definition stateMachineEngine.cpp:128
static void Register(CommandReplier &replier, StateMachineEngine &engine)
Definition stdCmdsImpl.hpp:36
virtual void ActivityInitialising(StopToken)
Definition stdComponent.hpp:150
virtual void ActivityEnabling(StopToken)
Definition stdComponent.hpp:151
virtual void ActivityStarting(StopToken st)
Definition stdComponent.hpp:149
virtual void ActivityDisabling(StopToken)
Definition stdComponent.hpp:152
CommandReplier & m_replier
Definition stdComponent.hpp:175
virtual void Start()
Definition stdComponent.hpp:166
StateMachineEngine & m_engine
Definition stdComponent.hpp:176
InputStage(CommandReplier &replier, StateMachineEngine &engine)
Definition stdComponent.hpp:160
ModelBuilder(StateMachineEngine &engine)
Definition stdComponent.hpp:422
std::function< void()> m_success_handler
Definition stdComponent.hpp:413
OutputStage(StateMachineEngine &engine, BizLogicIf &bl)
Definition stdComponent.hpp:184
StateMachineEngine & m_engine
Definition stdComponent.hpp:410
std::function< void(std::exception_ptr)> m_error_handler
Definition stdComponent.hpp:414
BizLogicIf & m_logic
Definition stdComponent.hpp:411
std::shared_ptr< rad::cii::Request< std::string, void > > m_tmp_request
Definition stdComponent.hpp:412
Thrown if somebody sent a stop or abort command.
Definition stdComponent.hpp:95
static constexpr int32_t ERROR_CODE
Definition stdComponent.hpp:97
StdIfRequestAborted()
Definition stdComponent.hpp:98
Thrown if the command was accepted but the task to run failed.
Definition stdComponent.hpp:122
static constexpr int32_t ERROR_CODE
Definition stdComponent.hpp:127
StdIfRequestFailed(const std::string &message)
Definition stdComponent.hpp:128
Thrown if the command is not allowed in current state or guard.
Definition stdComponent.hpp:106
StdIfRequestRejected(const std::string &request_id, const std::string &state_id)
Definition stdComponent.hpp:112
static constexpr int32_t ERROR_CODE
Definition stdComponent.hpp:111
Receive commands via MAL.
Provides macros and utilities for exception handling.
log4cplus::Logger & GetLogger(const std::string &name="app")
Get handle to a specific logger.
Definition logger.cpp:191
Implementation of MAL commands for layer 'IntrospectionIf'.
Logging Support Library based on log4cplus.
Base class of the ModelBuilder.
Definition commandReplier.cpp:21
@ Simple
Definition model.hpp:22
@ Composite
Definition model.hpp:22
@ Parallel
Definition model.hpp:22
@ Final
Definition model.hpp:22
@ Initial
Definition model.hpp:22
rad::StopToken StopToken
Definition stopToken.hpp:19
std::shared_ptr< typename EVENT::payload_t > GetPayloadNothrow(scxml4cpp::Context *c)
Definition stateMachineEngine.hpp:255
const std::string STD_OK_REPLY
Definition stdComponent.hpp:85
Definition statePublisher.hpp:24
A container that can hold any type of service.
Wrapper around the SCXML State Machine Engine.
Implementation of MAL commands for layer 'StdComponent'.
A simple Stop Token.
Basic life cycle for StdComponent.
Definition stdComponent.hpp:143
Various utilities for Life Cycle Extension.