/** * \file mb_controller.hpp * \brief MessageBroker Controller. * \author AKara */ #ifndef MB_CONTROLLER_H #define MB_CONTROLLER_H #include #include "json/json.h" #include "mb_tcpclient.hpp" #include "utils/lock.h" #include /** * \namespace NsMessageBroker * \brief MessageBroker related functions. */ namespace NsMessageBroker { /** *\class CMessageBrokerController * \brief MessageBroker Controller. */ class CMessageBrokerController : public TcpClient { public: /** * \brief Constructor. * \param address remote network address or FQDN * \param port remote local port * \param name name of component */ CMessageBrokerController(const std::string& address, uint16_t port, std::string name); /** * \brief Destructor. */ ~CMessageBrokerController(); /** * \brief Receive data from the network. * \param data if data is received it will put in this reference * \return number of bytes received or -1 if error * \note This method will blocked until data comes. */ virtual ssize_t Recv(std::string& data); /** * \brief Send data. * \param data data to send * \return number of bytes sent or -1 if error */ ssize_t Send(const std::string& data); /** * \brief send Json message. * \param message JSON message. */ void sendJsonMessage(Json::Value& message); /** * \brief generates new message id from diapason mControllersIdStart - (mControllersIdStart+999). * \return next id for message */ int getNextMessageId(); /** * \brief generates new message with id, jsonrpc version. * \param root container for prepared message */ void prepareMessage(Json::Value& root); /** * \brief generates new message with id, jsonrpc version. * \note Doesn't change/add fields id and jsonrpc * \param errCode error code * \param errMessage string of message * \param error container for prepared error message */ void prepareErrorMessage(int errCode, std::string errMessage, Json::Value& error); /** * \brief gets destination component name. * \param root JSON message. * \return string destination component name. */ std::string getDestinationComponentName(Json::Value& root); /** * \brief gets method name. * \param root JSON message. * \return string method name. */ std::string getMethodName(Json::Value& root); /** * \brief checks is message notification or not. * \param root JSON message. * \return true if notification. */ bool isNotification(Json::Value& root); /** * \brief checks is message response or not. * \param root JSON message. * \return true if response. */ bool isResponse(Json::Value& root); /** * \brief searches Method by id in mWaitResponseQueue. * \param id id of incoming JSON message. * \return string method name or "" in case not found. */ std::string findMethodById(std::string id); /** * \brief register controller on the server. * \param id message id for JSON message due the id diapason hasn't been received. */ void registerController(int id = 0); /** * \brief unregister controller on the server. */ void unregisterController(); /** * \brief subscribes controller to the property changing. * \param property property name in format ComponentName.PropertyName. */ void subscribeTo(std::string property); /** * \brief unsubscribes controller from the property changing. * \param property property name in format ComponentName.PropertyName. */ void unsubscribeFrom(std::string property); /** * \brief pure virtual method to process response. * \param method method name which has been called. * \param root JSON message. */ virtual void processResponse(std::string method, Json::Value& root) = 0; /** * \brief pure virtual method to process request. * \param root JSON message. */ virtual void processRequest(Json::Value& root) = 0; /** * \brief Process notification message. * \brief Notify subscribers about property change. * expected notification format example: * \code * {"jsonrpc": "2.0", "method": ".", "params": } * \endcode * \param root JSON message. */ virtual void processNotification(Json::Value& root) = 0; /** * \brief Checks message. * \param root JSON message. * \param error JSON message to fill in case of any errors. * \return true if message is good. */ bool checkMessage(Json::Value& root, Json::Value& error); /** * \brief Returns name of Controller. * \return name of controller. */ std::string getControllersName(); /** * \brief Method for receiving thread. */ void* MethodForReceiverThread(void * arg); virtual void exitReceivingThread() { Close(); stop = true; sync_primitives::AutoLock auto_lock(receiving_thread_lock_); } protected: /** * @brief flag top stop thread */ volatile bool stop; private: /** * \brief Method for receiving messages without tcp packeting. * \param message received data */ void onMessageReceived(Json::Value message); /** * \brief Start value of id's diapason. */ std::string m_receivingBuffer; /** * \brief Start value of id's diapason. */ int mControllersIdStart; /** * \brief Current id's value. */ int mControllersIdCurrent; /** * \brief Already sent messages Methods to recognize esponses: MessageId:MethodName. */ std::map mWaitResponseQueue; /** * \brief Name of component. */ std::string mControllersName; /** * \brief JSON reader. */ Json::Reader m_reader; /** * \brief JSON writer. */ Json::FastWriter m_writer; /** * \brief JSON writer. */ Json::FastWriter m_receiverWriter; /* * @brief mutex for mWaitResponseQueue */ sync_primitives::Lock queue_lock_; /* * @brief mutex for Mutex for correct finishing of receiving thread */ sync_primitives::Lock receiving_thread_lock_; }; } /* namespace NsMessageBroker */ #endif /* MB_CONTROLLER_H */