state_model.h 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671
  1. // Copyright (C) 2013-2015 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this
  5. // file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6. #ifndef STATE_MODEL_H
  7. #define STATE_MODEL_H
  8. /// @file state_model.h This file defines the class StateModel.
  9. #include <exceptions/exceptions.h>
  10. #include <d2/d2_config.h>
  11. #include <d2/dns_client.h>
  12. #include <d2/labeled_value.h>
  13. #include <dhcp_ddns/ncr_msg.h>
  14. #include <boost/shared_ptr.hpp>
  15. #include <map>
  16. #include <string>
  17. namespace isc {
  18. namespace d2 {
  19. /// @brief Thrown if the state machine encounters a general error.
  20. class StateModelError : public isc::Exception {
  21. public:
  22. StateModelError(const char* file, size_t line, const char* what) :
  23. isc::Exception(file, line, what) { };
  24. };
  25. /// @brief Define an Event.
  26. typedef LabeledValue Event;
  27. /// @brief Define Event pointer.
  28. typedef LabeledValuePtr EventPtr;
  29. /// @brief Defines a pointer to an instance method for handling a state.
  30. typedef boost::function<void()> StateHandler;
  31. /// @brief Defines a State within the State Model.
  32. ///
  33. /// This class provides the means to define a state within a set or dictionary
  34. /// of states, and assign the state an handler method to execute the state's
  35. /// actions. It derives from LabeledValue which allows a set of states to be
  36. /// keyed by integer constants.
  37. class State : public LabeledValue {
  38. public:
  39. /// @brief Constructor
  40. ///
  41. /// @param value is the numeric value of the state
  42. /// @param label is the text label to assign to the state
  43. /// @param handler is the bound instance method which handles the state's
  44. /// action.
  45. ///
  46. /// A typical invocation might look this:
  47. ///
  48. /// @code
  49. /// State(SOME_INT_VAL, "SOME_INT_VAL",
  50. /// boost::bind(&StateModelDerivation::someHandler, this));
  51. /// @endcode
  52. ///
  53. /// @throw StateModelError if label is null or blank.
  54. State(const int value, const std::string& label, StateHandler handler);
  55. /// @brief Destructor
  56. virtual ~State();
  57. /// @brief Invokes the State's handler.
  58. void run();
  59. private:
  60. /// @brief Bound instance method pointer to the state's handler method.
  61. StateHandler handler_;
  62. };
  63. /// @brief Defines a shared pointer to a State.
  64. typedef boost::shared_ptr<State> StatePtr;
  65. /// @brief Implements a unique set or dictionary of states.
  66. ///
  67. /// This class provides the means to construct and access a unique set of
  68. /// states. This provide the ability to validate state values, look up their
  69. /// text labels, and their handlers.
  70. class StateSet : public LabeledValueSet {
  71. public:
  72. /// @brief Constructor
  73. StateSet();
  74. /// @brief Destructor
  75. virtual ~StateSet();
  76. /// @brief Adds a state definition to the set of states.
  77. ///
  78. /// @param value is the numeric value of the state
  79. /// @param label is the text label to assig to the state
  80. /// @param handler is the bound instance method which handles the state's
  81. ///
  82. /// @throw StateModelError if the value is already defined in the set, or
  83. /// if the label is null or blank.
  84. void add(const int value, const std::string& label, StateHandler handler);
  85. /// @brief Fetches a state for the given value.
  86. ///
  87. /// @param value the numeric value of the state desired
  88. ///
  89. /// @return A constant pointer the State found.
  90. /// Note, this relies on dynamic cast and cannot return a pointer reference.
  91. ///
  92. /// @throw StateModelError if the value is undefined.
  93. const StatePtr getState(int value);
  94. };
  95. /// @brief Implements a finite state machine.
  96. ///
  97. /// StateModel is an abstract class that provides the structure and mechanics
  98. /// of a basic finite state machine.
  99. ///
  100. /// The state model implementation used is a very basic approach. The model
  101. /// uses numeric constants to identify events and states, and maintains
  102. /// dictionaries of defined events and states. Event and state definitions
  103. /// include a text label for logging purposes. Additionally, each state
  104. /// definition includes a state handler. State handlers are methods which
  105. /// implement the actions that need to occur when the model is "in" a given
  106. /// state. The implementation provides methods to add entries to and verify
  107. /// the contents of both dictionaries.
  108. ///
  109. /// During model execution, the following context is tracked:
  110. ///
  111. /// * current state - The current state of the model
  112. /// * previous state - The state the model was in prior to the current state
  113. /// * next event - The next event to be consumed
  114. /// * last event - The event most recently consumed
  115. ///
  116. /// When invoked, a state handler determines what it should do based upon the
  117. /// next event including what the next state and event should be. In other
  118. /// words the state transition knowledge is distributed among the state
  119. /// handlers rather than encapsulated in some form of state transition table.
  120. ///
  121. /// Events "posted" from within the state handlers are "internally" triggered
  122. /// events. Events "posted" from outside the state model, such as through
  123. /// the invocation of a callback are "externally" triggered.
  124. ///
  125. /// StateModel defines two states:
  126. ///
  127. /// * NEW_ST - State that a model is in following instantiation. It remains in
  128. /// this state until model execution has begun.
  129. /// * END_ST - State that a model is in once it has reached its conclusion.
  130. ///
  131. /// and the following events:
  132. ///
  133. /// * START_EVT - Event used to start model execution.
  134. /// * NOP_EVT - Event used to signify that the model stop and wait for an
  135. /// external event, such as the completion of an asynchronous IO operation.
  136. /// * END_EVT - Event used to trigger a normal conclusion of the model. This
  137. /// means only that the model was traversed from start to finish, without any
  138. /// model violations (i.e. invalid state, event, or transition) or uncaught
  139. /// exceptions.
  140. /// * FAIL_EVT - Event to trigger an abnormal conclusion of the model. This
  141. /// event is posted internally when model execution fails due to a model
  142. /// violation or uncaught exception. It signifies that the model has reached
  143. /// an inoperable condition.
  144. ///
  145. /// Derivations add their own states and events appropriate for their state
  146. /// model. Note that NEW_ST and END_ST do not support handlers. No work can
  147. /// be done (events consumed) prior to starting the model nor can work be done
  148. /// once the model has ended.
  149. ///
  150. /// Model execution consists of iteratively invoking the state handler
  151. /// indicated by the current state which should consume the next event. As the
  152. /// handlers post events and/or change the state, the model is traversed. The
  153. /// loop stops whenever the model cannot continue without an externally
  154. /// triggered event or when it has reached its final state. In the case of
  155. /// the former, the loop may be re-entered upon arrival of the external event.
  156. ///
  157. /// This loop is implemented in the runModel method. This method accepts an
  158. /// event as argument which it "posts" as the next event. It then retrieves the
  159. /// handler for the current state from the handler map and invokes it. runModel
  160. /// repeats this process until either a NOP_EVT posts or the state changes
  161. /// to END_ST. In other words each invocation of runModel causes the model to
  162. /// be traversed from the current state until it must wait or ends.
  163. ///
  164. /// Re-entering the "loop" upon the occurrence of an external event is done by
  165. /// invoking runModel with the appropriate event. As before, runModel will
  166. /// loop until either the NOP_EVT occurs or until the model reaches its end.
  167. ///
  168. /// A StateModel (derivation) is in the NEW_ST when constructed and remains
  169. /// there until it has been "started". Starting the model is done by invoking
  170. /// the startModel method which accepts a state as a parameter. This parameter
  171. /// specifies the "start" state and it becomes the current state.
  172. /// The first task undertaken by startModel is to initialize and verify the
  173. /// the event and state dictionaries. The following virtual methods are
  174. /// provided for this:
  175. ///
  176. /// * defineEvents - define events
  177. /// * verifyEvents - verifies that the expected events are defined
  178. /// * defineStates - defines states
  179. /// * verifyStates - verifies that the expected states are defined
  180. ///
  181. /// The concept behind the verify methods is to provide an initial sanity
  182. /// check of the dictionaries. This should help avoid using undefined event
  183. /// or state values accidentally.
  184. ///
  185. /// These methods are intended to be implemented by each "layer" in a StateModel
  186. /// derivation hierarchy. This allows each layer to define additional events
  187. /// and states.
  188. ///
  189. /// Once the dictionaries have been properly initialized, the startModel method
  190. /// invokes runModel with an event of START_EVT. From this point forward and
  191. /// until the model reaches the END_ST or fails, it is considered to be
  192. /// "running". If the model encounters a NOP_EVT then it is "running" and
  193. /// "waiting". If the model reaches END_ST with an END_EVT it is considered
  194. /// "done". If the model fails (END_ST with a FAILED_EVT) it is considered
  195. /// "done" and "failed". There are several boolean status methods which may
  196. /// be used to check these conditions.
  197. ///
  198. /// To progress from one state to the another, state handlers invoke use
  199. /// the method, transition. This method accepts a state and an event as
  200. /// parameters. These values become the current state and the next event
  201. /// respectively. This has the effect of entering the given state having posted
  202. /// the given event. The postEvent method may be used to post a new event
  203. /// to the current state.
  204. ///
  205. /// Bringing the model to a normal end is done by invoking the endModel method
  206. /// which transitions the model to END_ST with END_EVT. Bringing the model to
  207. /// an abnormal end is done via the abortModel method, which transitions the
  208. /// model to END_ST with FAILED_EVT.
  209. class StateModel {
  210. public:
  211. //@{ States common to all models.
  212. /// @brief State that a state model is in immediately after construction.
  213. static const int NEW_ST = 0;
  214. /// @brief Final state, all the state model has reached its conclusion.
  215. static const int END_ST = 1;
  216. /// @brief Value at which custom states in a derived class should begin.
  217. static const int SM_DERIVED_STATE_MIN = 11;
  218. //@}
  219. //@{ Events common to all state models.
  220. /// @brief Signifies that no event has occurred.
  221. /// This is event used to interrupt the event loop to allow waiting for
  222. /// an IO event or when there is no more work to be done.
  223. static const int NOP_EVT = 0;
  224. /// @brief Event issued to start the model execution.
  225. static const int START_EVT = 1;
  226. /// @brief Event issued to end the model execution.
  227. static const int END_EVT = 2;
  228. /// @brief Event issued to abort the model execution.
  229. static const int FAIL_EVT = 3;
  230. /// @brief Value at which custom events in a derived class should begin.
  231. static const int SM_DERIVED_EVENT_MIN = 11;
  232. //@}
  233. /// @brief Constructor
  234. StateModel();
  235. /// @brief Destructor
  236. virtual ~StateModel();
  237. /// @brief Begins execution of the model.
  238. ///
  239. /// This method invokes initDictionaries method to initialize the event
  240. /// and state dictionaries and then starts the model execution setting
  241. /// the current state to the given start state, and the event to START_EVT.
  242. ///
  243. /// @param start_state is the state in which to begin execution.
  244. ///
  245. /// @throw StateModelError or others indirectly, as this method calls
  246. /// dictionary define and verify methods.
  247. void startModel(const int start_state);
  248. /// @brief Processes events through the state model
  249. ///
  250. /// This method implements the state model "execution loop". It uses
  251. /// the given event as the next event to process and begins invoking
  252. /// the state handler for the current state. As described above, the
  253. /// invoked state handler consumes the next event and then determines the
  254. /// next event and the current state as required to implement the business
  255. /// logic. The method continues to loop until the next event posted is
  256. /// NOP_EVT or the model ends.
  257. ///
  258. /// Any exception thrown during the loop is caught, logged, and the
  259. /// model is aborted with a FAIL_EVT. The derivation's state
  260. /// model is expected to account for any possible errors so any that
  261. /// escape are treated as unrecoverable.
  262. ///
  263. /// @param event is the next event to process
  264. ///
  265. /// This method is guaranteed not to throw.
  266. void runModel(unsigned int event);
  267. /// @brief Conducts a normal transition to the end of the model.
  268. ///
  269. /// This method posts an END_EVT and sets the current state to END_ST.
  270. /// It should be called by any state handler in the model from which
  271. /// an exit leads to the model end. In other words, if the transition
  272. /// out of a particular state is to the end of the model, that state's
  273. /// handler should call endModel.
  274. void endModel();
  275. /// @brief An empty state handler.
  276. ///
  277. /// This method is primarily used to permit special states, NEW_ST and
  278. /// END_ST to be included in the state dictionary. Currently it is an
  279. /// empty method.
  280. void nopStateHandler();
  281. protected:
  282. /// @brief Initializes the event and state dictionaries.
  283. ///
  284. /// This method invokes the define and verify methods for both events and
  285. /// states to initialize their respective dictionaries.
  286. ///
  287. /// @throw StateModelError or others indirectly, as this method calls
  288. /// dictionary define and verify methods.
  289. void initDictionaries();
  290. /// @brief Populates the set of events.
  291. ///
  292. /// This method is used to construct the set of valid events. Each class
  293. /// within a StateModel derivation hierarchy uses this method to add any
  294. /// events it defines to the set. Each derivation's implementation must
  295. /// also call it's superclass's implementation. This allows each class
  296. /// within the hierarchy to make contributions to the set of defined
  297. /// events. Implementations use the method, defineEvent(), to add event
  298. /// definitions. An example of the derivation's implementation follows:
  299. ///
  300. /// @code
  301. /// void StateModelDerivation::defineEvents() {
  302. /// // Call the superclass implementation.
  303. /// StateModelDerivation::defineEvents();
  304. ///
  305. /// // Add the events defined by the derivation.
  306. /// defineEvent(SOME_CUSTOM_EVT_1, "CUSTOM_EVT_1");
  307. /// defineEvent(SOME_CUSTOM_EVT_2, "CUSTOM_EVT_2");
  308. /// :
  309. /// }
  310. /// @endcode
  311. virtual void defineEvents();
  312. /// @brief Adds an event value and associated label to the set of events.
  313. ///
  314. /// @param value is the numeric value of the event
  315. /// @param label is the text label of the event used in log messages and
  316. /// exceptions.
  317. ///
  318. /// @throw StateModelError if the model has already been started, if
  319. /// the value is already defined, or if the label is empty.
  320. void defineEvent(unsigned int value, const std::string& label);
  321. /// @brief Fetches the event referred to by value.
  322. ///
  323. /// @param value is the numeric value of the event desired.
  324. ///
  325. /// @return returns a constant pointer reference to the event if found
  326. ///
  327. /// @throw StateModelError if the event is not defined.
  328. const EventPtr& getEvent(unsigned int value);
  329. /// @brief Validates the contents of the set of events.
  330. ///
  331. /// This method is invoked immediately after the defineEvents method and
  332. /// is used to verify that all the required events are defined. If the
  333. /// event set is determined to be invalid this method should throw a
  334. /// StateModelError. As with the defineEvents method, each class within
  335. /// a StateModel derivation hierarchy must supply an implementation
  336. /// which calls it's superclass's implementation as well as verifying any
  337. /// events added by the derivation. Validating an event is accomplished
  338. /// by simply attempting to fetch an event by its value from the event set.
  339. /// An example of the derivation's implementation follows:
  340. ///
  341. /// @code
  342. /// void StateModelDerivation::verifyEvents() {
  343. /// // Call the superclass implementation.
  344. /// StateModelDerivation::verifyEvents();
  345. ///
  346. /// // Verify the events defined by the derivation.
  347. /// getEvent(SOME_CUSTOM_EVT_1, "CUSTOM_EVT_1");
  348. /// getEvent(SOME_CUSTOM_EVT_2, "CUSTOM_EVT_2");
  349. /// :
  350. /// }
  351. /// @endcode
  352. virtual void verifyEvents();
  353. /// @brief Populates the set of states.
  354. ///
  355. /// This method is used to construct the set of valid states. Each class
  356. /// within a StateModel derivation hierarchy uses this method to add any
  357. /// states it defines to the set. Each derivation's implementation must
  358. /// also call it's superclass's implementation. This allows each class
  359. /// within the hierarchy to make contributions to the set of defined
  360. /// states. Implementations use the method, defineState(), to add state
  361. /// definitions. An example of the derivation's implementation follows:
  362. ///
  363. /// @code
  364. /// void StateModelDerivation::defineStates() {
  365. /// // Call the superclass implementation.
  366. /// StateModelDerivation::defineStates();
  367. ///
  368. /// // Add the states defined by the derivation.
  369. /// defineState(SOME_ST, "SOME_ST",
  370. /// boost::bind(&StateModelDerivation::someHandler, this));
  371. /// :
  372. /// }
  373. /// @endcode
  374. virtual void defineStates();
  375. /// @brief Adds an state value and associated label to the set of states.
  376. ///
  377. /// @param value is the numeric value of the state
  378. /// @param label is the text label of the state used in log messages and
  379. /// exceptions.
  380. /// @param handler is the bound instance method which implements the state's
  381. /// actions.
  382. ///
  383. /// @throw StateModelError if the model has already been started, if
  384. /// the value is already defined, or if the label is empty.
  385. void defineState(unsigned int value, const std::string& label,
  386. StateHandler handler);
  387. /// @brief Fetches the state referred to by value.
  388. ///
  389. /// @param value is the numeric value of the state desired.
  390. ///
  391. /// @return returns a constant pointer to the state if found
  392. ///
  393. /// @throw StateModelError if the state is not defined.
  394. const StatePtr getState(unsigned int value);
  395. /// @brief Validates the contents of the set of states.
  396. ///
  397. /// This method is invoked immediately after the defineStates method and
  398. /// is used to verify that all the required states are defined. If the
  399. /// state set is determined to be invalid this method should throw a
  400. /// StateModelError. As with the defineStates method, each class within
  401. /// a StateModel derivation hierarchy must supply an implementation
  402. /// which calls it's superclass's implementation as well as verifying any
  403. /// states added by the derivation. Validating an state is accomplished
  404. /// by simply attempting to fetch the state by its value from the state set.
  405. /// An example of the derivation's implementation follows:
  406. ///
  407. /// @code
  408. /// void StateModelDerivation::verifyStates() {
  409. /// // Call the superclass implementation.
  410. /// StateModelDerivation::verifyStates();
  411. ///
  412. /// // Verify the states defined by the derivation.
  413. /// getState(SOME_CUSTOM_EVT_2);
  414. /// :
  415. /// }
  416. /// @endcode
  417. virtual void verifyStates();
  418. /// @brief Handler for fatal model execution errors.
  419. ///
  420. /// This method is called when an unexpected error renders during
  421. /// model execution, such as a state handler throwing an exception.
  422. /// It provides derivations an opportunity to act accordingly by setting
  423. /// the appropriate status or taking other remedial action. This allows
  424. /// the model execution loop to remain exception safe. This default
  425. /// implementation does nothing.
  426. ///
  427. /// @param explanation text detailing the error and state machine context
  428. virtual void onModelFailure(const std::string& explanation);
  429. /// @brief Sets up the model to transition into given state with a given
  430. /// event.
  431. ///
  432. /// This updates the model's notion of the current state and the next
  433. /// event to process. State handlers use this method to move from one state
  434. /// to the next.
  435. ///
  436. /// @param state the new value to assign to the current state.
  437. /// @param event the new value to assign to the next event.
  438. ///
  439. /// @throw StateModelError if the state is invalid.
  440. void transition(unsigned int state, unsigned int event);
  441. /// @brief Aborts model execution.
  442. ///
  443. /// This method posts a FAILED_EVT and sets the current state to END_ST.
  444. /// It is called internally when a model violation occurs. Violations are
  445. /// any sort of inconsistency such as attempting to reference an invalid
  446. /// state, or if the next event is not valid for the current state, or a
  447. /// state handler throws an uncaught exception.
  448. ///
  449. /// @param explanation is text detailing the reason for aborting.
  450. void abortModel(const std::string& explanation);
  451. /// @brief Sets the current state to the given state value.
  452. ///
  453. /// This updates the model's notion of the current state and is the
  454. /// state whose handler will be executed on the next iteration of the run
  455. /// loop. This is intended primarily for internal use and testing. It is
  456. /// unlikely that transitioning to a new state without a new event is of
  457. /// much use.
  458. ///
  459. /// @param state the new value to assign to the current state.
  460. ///
  461. /// @throw StateModelError if the state is invalid.
  462. void setState(unsigned int state);
  463. /// @brief Sets the next event to the given event value.
  464. ///
  465. /// This updates the model's notion of the next event and is the
  466. /// event that will be passed into the current state's handler on the next
  467. /// iteration of the run loop.
  468. ///
  469. /// @param event the numeric event value to post as the next event.
  470. ///
  471. /// @throw StateModelError if the event is undefined
  472. void postNextEvent(unsigned int event);
  473. /// @brief Checks if on entry flag is true.
  474. ///
  475. /// This method acts as a one-shot test of whether or not the model is
  476. /// transitioning into a new state. It returns true if the on-entry flag
  477. /// is true upon entering this method and will set the flag false prior
  478. /// to exit. It may be used within state handlers to perform steps that
  479. /// should only occur upon entry into the state.
  480. ///
  481. /// @return true if the on entry flag is true, false otherwise.
  482. bool doOnEntry();
  483. /// @brief Checks if on exit flag is true.
  484. ///
  485. /// This method acts as a one-shot test of whether or not the model is
  486. /// transitioning out of the current state. It returns true if the
  487. /// on-exit flag is true upon entering this method and will set the flag
  488. /// false prior to exiting. It may be used within state handlers to perform
  489. /// steps that should only occur upon exiting out of the current state.
  490. ///
  491. /// @return true if the on entry flag is true, false otherwise.
  492. bool doOnExit();
  493. public:
  494. /// @brief Fetches the model's current state.
  495. ///
  496. /// This returns the model's notion of the current state. It is the
  497. /// state whose handler will be executed on the next iteration of the run
  498. /// loop.
  499. ///
  500. /// @return An unsigned int representing the current state.
  501. unsigned int getCurrState() const;
  502. /// @brief Fetches the model's previous state.
  503. ///
  504. /// @return An unsigned int representing the previous state.
  505. unsigned int getPrevState() const;
  506. /// @brief Fetches the model's last event.
  507. ///
  508. /// @return An unsigned int representing the last event.
  509. unsigned int getLastEvent() const;
  510. /// @brief Fetches the model's next event.
  511. ///
  512. /// This returns the model's notion of the next event. It is the
  513. /// event that will be passed into the current state's handler on the next
  514. /// iteration of the run loop.
  515. ///
  516. /// @return An unsigned int representing the next event.
  517. unsigned int getNextEvent() const;
  518. /// @brief Returns whether or not the model is new.
  519. ///
  520. /// @return Boolean true if the model has not been started.
  521. bool isModelNew() const;
  522. /// @brief Returns whether or not the model is running.
  523. ///
  524. /// @return Boolean true if the model has been started but has not yet
  525. /// ended.
  526. bool isModelRunning() const;
  527. /// @brief Returns whether or not the model is waiting.
  528. ///
  529. /// @return Boolean true if the model is running but is waiting for an
  530. /// external event for resumption.
  531. bool isModelWaiting() const;
  532. /// @brief Returns whether or not the model has finished execution.
  533. ///
  534. /// @return Boolean true if the model has reached the END_ST.
  535. bool isModelDone() const;
  536. /// @brief Returns whether or not the model failed.
  537. ///
  538. /// @return Boolean true if the model has reached the END_ST and the last
  539. /// event indicates a model violation, FAILED_EVT.
  540. bool didModelFail() const;
  541. /// @brief Fetches the label associated with an event value.
  542. ///
  543. /// @param event is the numeric event value for which the label is desired.
  544. ///
  545. /// @return Returns a string containing the event label or
  546. /// LabeledValueSet::UNDEFINED_LABEL if the value is undefined.
  547. std::string getEventLabel(const int event) const;
  548. /// @brief Fetches the label associated with an state value.
  549. ///
  550. /// @param state is the numeric state value for which the label is desired.
  551. ///
  552. /// @return Returns a const char* containing the state label or
  553. /// LabeledValueSet::UNDEFINED_LABEL if the value is undefined.
  554. std::string getStateLabel(const int state) const;
  555. /// @brief Convenience method which returns a string rendition of the
  556. /// current state and next event.
  557. ///
  558. /// The string will be of the form:
  559. ///
  560. /// current state: [ {state} {label} ] next event: [ {event} {label} ]
  561. ///
  562. /// @return Returns a std::string of the format described above.
  563. std::string getContextStr() const;
  564. /// @brief Convenience method which returns a string rendition of the
  565. /// previous state and last event.
  566. ///
  567. /// The string will be of the form:
  568. ///
  569. /// previous state: [ {state} {label} ] last event: [ {event} {label} ]
  570. ///
  571. /// @return Returns a std::string of the format described above.
  572. std::string getPrevContextStr() const;
  573. private:
  574. /// @brief The dictionary of valid events.
  575. LabeledValueSet events_;
  576. /// @brief The dictionary of valid states.
  577. StateSet states_;
  578. /// @brief Indicates if the event and state dictionaries have been initted.
  579. bool dictionaries_initted_;
  580. /// @brief The current state within the model's state model.
  581. unsigned int curr_state_;
  582. /// @brief The previous state within the model's state model.
  583. unsigned int prev_state_;
  584. /// @brief The event last processed by the model.
  585. unsigned int last_event_;
  586. /// @brief The event the model should process next.
  587. unsigned int next_event_;
  588. /// @brief Indicates if state entry logic should be executed.
  589. bool on_entry_flag_;
  590. /// @brief Indicates if state exit logic should be executed.
  591. bool on_exit_flag_;
  592. };
  593. /// @brief Defines a pointer to a StateModel.
  594. typedef boost::shared_ptr<StateModel> StateModelPtr;
  595. } // namespace isc::d2
  596. } // namespace isc
  597. #endif