From 5601fde3dbea6a0edca11fdf0ea978f51bd7a9d2 Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Tue, 22 Nov 2016 21:19:00 +0100 Subject: [PATCH] [DEV] seem to work corectly --- lutin_zeus.py | 2 + tools/architecture.txt | 79 ++++- .../appl/ClientGateWayInterface.cpp | 274 +++++++++++------- .../appl/ClientGateWayInterface.hpp | 56 ++-- tools/gateway-back-end/appl/GateWay.cpp | 36 +-- tools/gateway-back-end/appl/GateWay.hpp | 2 +- .../appl/ServiceInterface.cpp | 36 ++- .../appl/ServiceInterface.hpp | 3 + .../appl/ClientInterface.cpp | 36 +-- .../appl/ClientInterface.hpp | 7 +- tools/gateway-front-end/appl/GateWay.cpp | 5 +- tools/service-user/appl/main.cpp | 197 +++++++------ zeus/Buffer.cpp | 39 ++- zeus/Buffer.hpp | 20 +- zeus/BufferCtrl.cpp | 57 ++++ zeus/BufferCtrl.hpp | 52 ++++ zeus/Service.cpp | 19 +- zeus/Service.hpp | 4 +- zeus/WebServer.cpp | 36 ++- zeus/WebServer.hpp | 30 +- 20 files changed, 671 insertions(+), 319 deletions(-) create mode 100644 zeus/BufferCtrl.cpp create mode 100644 zeus/BufferCtrl.hpp diff --git a/lutin_zeus.py b/lutin_zeus.py index 7c87214..7a81a3e 100644 --- a/lutin_zeus.py +++ b/lutin_zeus.py @@ -43,6 +43,7 @@ def configure(target, my_module): 'zeus/Buffer.cpp', 'zeus/BufferParameter.cpp', 'zeus/BufferCall.cpp', + 'zeus/BufferCtrl.cpp', 'zeus/BufferAnswer.cpp', 'zeus/BufferData.cpp', 'zeus/BufferEvent.cpp', @@ -69,6 +70,7 @@ def configure(target, my_module): 'zeus/Buffer.hpp', 'zeus/BufferParameter.hpp', 'zeus/BufferCall.hpp', + 'zeus/BufferCtrl.hpp', 'zeus/BufferAnswer.hpp', 'zeus/BufferData.hpp', 'zeus/BufferEvent.hpp', diff --git a/tools/architecture.txt b/tools/architecture.txt index 5b31e82..591491d 100644 --- a/tools/architecture.txt +++ b/tools/architecture.txt @@ -9,9 +9,9 @@ | *-------------* | *-----------------------* | | | |<-+ | | | | *-----------------------* | +-------------------+ - | | GATEWAY |<----------->| service-picture | | | | - +---------->| | *-----------------------* |<===>| USER X data | - | | | Back-end |<------+ | | | + | | |<----------->| service-picture | | | | + +---------->| GATEWAY | *-----------------------* |<===>| USER X data | + | | | |<------+ | | | | | | | | *-----------------------* | +-------------------+ | | | |<--+ +---->| service-video | | -----------* | | | | | *-----------------------* | @@ -20,11 +20,11 @@ | *-------------* | | +-------->| service-XXX | | |<----* | | | | *-----------------------* | | | | | | | | - |<----| | GATEWAY |<---+ *----------------------------------------------------------------------------* + |<----| | |<---+ *----------------------------------------------------------------------------* Internet | | | | - |<----*===>|80 | + |<----*===>|80 ROUTER | | | | | - |<----| | Front-end |<---+ *----------------------------------------------------------------------------* + |<----| | |<---+ *----------------------------------------------------------------------------* | | | | | | Docker / single binary Single User specufic program/environement | |<----* | | | | | | *-------------* | | *-----------------------* | @@ -32,9 +32,9 @@ Internet | | | | | *----------* | | *-------------* | *-----------------------* | -----------* | List | | | | |<-+ | +-------------------+ | of | | | | | *-----------------------* | | | - | user | | | | GATEWAY |<----------->| service-picture | |<===>| USER Y data | - |availlable| +---------->| | *-----------------------* | | | - *----------* | | Back-end |<------+ | +-------------------+ + | user | | | | |<----------->| service-picture | |<===>| USER Y data | + |availlable| +---------->| GATEWAY | *-----------------------* | | | + *----------* | | |<------+ | +-------------------+ | | | | *-----------------------* | | | |<--+ +---->| service-video | | | | | | *-----------------------* | @@ -54,17 +54,66 @@ This is the first acces node of the service engine ==> it redirect the user to t | | *-------------* |<----* | | - | | | | +-------------------------+ - |<----| | GATEWAY | | | + | | | ZUNS | +-------------------------+ + |<----| | | | | Internet | | | | | List of user | - |<----*===>| |<---->| associated gateway | - | | | | | address | - |<----| | Addressor | | | - | | | | +-------------------------+ + |<----*===>| zeus |<---->| associated gateway | + | | | user | | address | + |<----| | name | | | + | | | server | +-------------------------+ |<----* | | | *-------------* | | -----------* +And for the people that want to store their data without managing the routeur and have a parsonal network adresses: + +-----------* + | + | + | *-------------* + |<----+ | | + | | | | + |<----+===>| | +Internet | | | | + |<----+ | PROXY | + | | | + | | | + | | | + *------|--------->| | + | | | | + | | ... | | + | | | | + | ...--|--------->| | + | | *-------------* + | | + | | + | | <<================================== Change Machine ==================================>> + | | + | | + | | *----------------------------------------------------------------------------* + | | | Docker / single binary Single User specufic program/environement | + | | | | + | | | *-----------------------* | + | | | +--------->| service-right-manager | | + | | | *-------------* | *-----------------------* | + | | | | |<-+ | +-------------------+ + | | | | | *-----------------------* | | | + | | | | |<----------->| service-picture | |<===>| USER Y data | + +------|---------->| GATEWAY | *-----------------------* | | | + | | | |<------+ | +-------------------+ + | | | | | *-----------------------* | + | | | |<--+ +---->| service-video | | + | | | | | *-----------------------* | + | | *-------------* | | + | | | *-----------------------* | + | | +-------->| service-XXX | | + | | *-----------------------* | + | | | + | *----------------------------------------------------------------------------* + | + | +-----------* + diff --git a/tools/gateway-back-end/appl/ClientGateWayInterface.cpp b/tools/gateway-back-end/appl/ClientGateWayInterface.cpp index d54707a..4855fc6 100644 --- a/tools/gateway-back-end/appl/ClientGateWayInterface.cpp +++ b/tools/gateway-back-end/appl/ClientGateWayInterface.cpp @@ -13,93 +13,64 @@ #include - static const std::string protocolError = "PROTOCOL-ERROR"; -appl::ClientGateWayInterface::ClientGateWayInterface(const std::string& _ip, uint16_t _port, const std::string& _userName, appl::GateWay* _gatewayInterface) : - m_state(appl::ClientGateWayInterface::state::unconnect), - m_gatewayInterface(_gatewayInterface), - m_interfaceGateWayClient() { - APPL_INFO("----------------------------------------"); - APPL_INFO("-- NEW Connection to GateWay Font-end --"); - APPL_INFO("----------------------------------------"); - enet::Tcp connection = std::move(enet::connectTcpClient(_ip, _port)); - if (connection.getConnectionStatus() != enet::Tcp::status::link) { - APPL_ERROR("Can not connect the GateWay-front-end"); - return; - } - m_interfaceGateWayClient.setInterface(std::move(connection), false, _userName); - m_userConnectionName = _userName; - m_state = appl::ClientGateWayInterface::state::connect; - m_interfaceGateWayClient.connect(this, &appl::ClientGateWayInterface::onClientData); - m_interfaceGateWayClient.connect(true); - m_interfaceGateWayClient.setInterfaceName("cli-" + etk::to_string(m_uid)); +appl::userSpecificInterface::userSpecificInterface() { + m_uid = 0; + m_localIdUser = 0; + m_state = appl::clientState::unconnect; + APPL_INFO("----------------"); + APPL_INFO("-- NEW Client --"); + APPL_INFO("----------------"); } -appl::ClientGateWayInterface::~ClientGateWayInterface() { - APPL_TODO("Call All unlink ..."); - stop(); - APPL_INFO("-------------------------------------------"); - APPL_INFO("-- DELETE Connection to GateWay Font-end --"); - APPL_INFO("-------------------------------------------"); +appl::userSpecificInterface::~userSpecificInterface() { + APPL_INFO("-------------------"); + APPL_INFO("-- DELETE Client --"); + APPL_INFO("-------------------"); } -void appl::ClientGateWayInterface::start(uint64_t _uid, uint64_t _uid2) { - m_uid = _uid; - m_uid2 = _uid2; - m_state = appl::ClientGateWayInterface::state::connect; - m_interfaceGateWayClient.setInterfaceName("cli-" + etk::to_string(m_uid)); +void appl::userSpecificInterface::answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp) { + m_interfaceGateWayClient->answerError(_transactionId, protocolError, _errorHelp); + m_interfaceGateWayClient->sendCtrl("DISCONNECT", m_uid); + m_state = appl::clientState::disconnect; +} + +bool appl::userSpecificInterface::start(uint32_t _transactionId, appl::GateWay* _gatewayInterface, zeus::WebServer* _interfaceGateWayClient, uint64_t _id) { + m_interfaceGateWayClient = _interfaceGateWayClient; + m_gatewayInterface = _gatewayInterface; + m_uid = _id; + m_localIdUser = _id+1; + m_state = appl::clientState::connect; + //m_interfaceGateWayClient->setInterfaceName("cli-" + etk::to_string(m_uid)); + + APPL_WARNING("[" << m_uid << "] New client"); - APPL_WARNING("[" << m_uid << "] Connect to the user service"); m_userService = m_gatewayInterface->get("user"); if (m_userService == nullptr) { - //answerProtocolError(transactionId, "Gateway internal error 'No user interface'"); - // TODO: Can not work at all ==> or create a fallback mode ... + APPL_ERROR("missing service 'user'"); + answerProtocolError(_transactionId, "Gateway internal error 'No user interface'"); + return false; } - /* - else { - zeus::Future futLocalService = m_userService->m_interfaceClient.callClient(m_uid2, "_new", m_userConnectionName, "**Gateway**", std::vector()); - futLocalService.wait(); // TODO: Set timeout ... - m_interfaceGateWayClient.answerValue(transactionId, true); + zeus::Future futLocalService = m_userService->m_interfaceClient.callClient(m_localIdUser, "_new", m_userConnectionName, "**Gateway**", std::vector()); + futLocalService.wait(); // TODO: Set timeout ... + if (futLocalService.get() == false) { + answerProtocolError(_transactionId, "Gateway internal error 'Can not create client in user backend'"); + return false; } - APPL_WARNING("[" << m_uid << "] Client must send conection to user name ..."); - answerProtocolError(transactionId, "Missing call of connectToUser"); - return; - } - */ -} - -void appl::ClientGateWayInterface::stop() { - for (auto &it : m_listConnectedService) { - if (it == nullptr) { - continue; - } - it->m_interfaceClient.callClient(m_uid, "_delete"); - } - if (m_userService != nullptr) { - m_userService->m_interfaceClient.callClient(m_uid2, "_delete"); - m_userService = nullptr; - } - m_listConnectedService.clear(); - m_interfaceGateWayClient.disconnect(); -} - -bool appl::ClientGateWayInterface::isAlive() { - return m_interfaceGateWayClient.isActive(); -} - -void appl::ClientGateWayInterface::answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp) { - m_interfaceGateWayClient.answerError(_transactionId, protocolError, _errorHelp); - m_state = appl::ClientGateWayInterface::state::disconnect; - m_interfaceGateWayClient.disconnect(true); + return true; } -void appl::ClientGateWayInterface::onClientData(ememory::SharedPtr _value) { +void appl::userSpecificInterface::returnMessage(ememory::SharedPtr _data) { + APPL_ERROR("Get call from the Service to the user ..."); +} + +void appl::userSpecificInterface::onClientData(ememory::SharedPtr _value) { if (_value == nullptr) { return; } - APPL_ERROR("get message from front-end gateWay: " << _value); + //APPL_ERROR(" ==> parse DATA ..."); uint32_t transactionId = _value->getTransactionId(); if (transactionId == 0) { APPL_ERROR("Protocol error ==>missing id"); @@ -108,7 +79,7 @@ void appl::ClientGateWayInterface::onClientData(ememory::SharedPtr } if (_value->getType() == zeus::Buffer::typeMessage::data) { // TRANSMIT DATA ... - if (m_state != appl::ClientGateWayInterface::state::clientIdentify) { + if (m_state != appl::clientState::clientIdentify) { answerProtocolError(transactionId, "Not identify to send 'data' buffer (multiple packet element)"); return; } @@ -119,7 +90,7 @@ void appl::ClientGateWayInterface::onClientData(ememory::SharedPtr } serviceId--; if (serviceId >= m_listConnectedService.size()) { - m_interfaceGateWayClient.answerError(transactionId, "NOT-CONNECTED-SERVICE"); + m_interfaceGateWayClient->answerError(transactionId, "NOT-CONNECTED-SERVICE"); return; } if (m_listConnectedService[serviceId] == nullptr) { @@ -141,14 +112,14 @@ void appl::ClientGateWayInterface::onClientData(ememory::SharedPtr ememory::SharedPtr callObj = ememory::staticPointerCast(_value); std::string callFunction = callObj->getCall(); switch (m_state) { - case appl::ClientGateWayInterface::state::disconnect: - case appl::ClientGateWayInterface::state::unconnect: + case appl::clientState::disconnect: + case appl::clientState::unconnect: { APPL_ERROR("Must never appear"); answerProtocolError(transactionId, "Gateway internal error"); return; } - case appl::ClientGateWayInterface::state::connect: + case appl::clientState::connect: { m_clientServices.clear(); m_clientgroups.clear(); @@ -167,15 +138,15 @@ void appl::ClientGateWayInterface::onClientData(ememory::SharedPtr return; } - zeus::Future fut = m_userService->m_interfaceClient.callClient(m_uid2, "checkTocken", clientName, clientTocken); + zeus::Future fut = m_userService->m_interfaceClient.callClient(m_localIdUser, "checkTocken", clientName, clientTocken); fut.wait(); // TODO: Set timeout ... if (fut.hasError() == true) { APPL_ERROR("Get error from the service ..."); - m_interfaceGateWayClient.answerValue(transactionId, false); + m_interfaceGateWayClient->answerValue(transactionId, false); answerProtocolError(transactionId, "connection refused 1"); return; } else if (fut.get() == false) { - m_interfaceGateWayClient.answerValue(transactionId, false); + m_interfaceGateWayClient->answerValue(transactionId, false); answerProtocolError(transactionId, "connection refused 2"); return; } @@ -183,15 +154,15 @@ void appl::ClientGateWayInterface::onClientData(ememory::SharedPtr } if (callFunction == "auth") { std::string password = callObj->getParameter(0); - zeus::Future fut = m_userService->m_interfaceClient.callClient(m_uid2, "checkAuth", password); + zeus::Future fut = m_userService->m_interfaceClient.callClient(m_localIdUser, "checkAuth", password); fut.wait(); // TODO: Set timeout ... if (fut.hasError() == true) { APPL_ERROR("Get error from the service ..."); - m_interfaceGateWayClient.answerValue(transactionId, false); + m_interfaceGateWayClient->answerValue(transactionId, false); answerProtocolError(transactionId, "connection refused 1"); return; } else if (fut.get() == false) { - m_interfaceGateWayClient.answerValue(transactionId, false); + m_interfaceGateWayClient->answerValue(transactionId, false); answerProtocolError(transactionId, "connection refused 2"); return; } @@ -203,11 +174,11 @@ void appl::ClientGateWayInterface::onClientData(ememory::SharedPtr // -------------------------------- // -- Get groups: // -------------------------------- - zeus::Future> futGroup = m_userService->m_interfaceClient.callClient(m_uid2, "getGroups", m_clientName); + zeus::Future> futGroup = m_userService->m_interfaceClient.callClient(m_localIdUser, "getGroups", m_clientName); futGroup.wait(); // TODO: Set timeout ... if (futGroup.hasError() == true) { APPL_ERROR("Get error from the service ..."); - m_interfaceGateWayClient.answerValue(transactionId, false); + m_interfaceGateWayClient->answerValue(transactionId, false); answerProtocolError(transactionId, "grouping error"); return; } @@ -216,11 +187,11 @@ void appl::ClientGateWayInterface::onClientData(ememory::SharedPtr // -- Get services: // -------------------------------- std::vector currentServices = m_gatewayInterface->getAllServiceName(); - zeus::Future> futServices = m_userService->m_interfaceClient.callClient(m_uid2, "filterServices", m_clientName, currentServices); + zeus::Future> futServices = m_userService->m_interfaceClient.callClient(m_localIdUser, "filterServices", m_clientName, currentServices); futServices.wait(); // TODO: Set timeout ... if (futServices.hasError() == true) { APPL_ERROR("Get error from the service ..."); - m_interfaceGateWayClient.answerValue(transactionId, false); + m_interfaceGateWayClient->answerValue(transactionId, false); answerProtocolError(transactionId, "service filtering error"); return; } @@ -230,22 +201,22 @@ void appl::ClientGateWayInterface::onClientData(ememory::SharedPtr APPL_WARNING(" services: " << etk::to_string(m_clientServices)); - m_interfaceGateWayClient.answerValue(transactionId, true); - m_state = appl::ClientGateWayInterface::state::clientIdentify; + m_interfaceGateWayClient->answerValue(transactionId, true); + m_state = appl::clientState::clientIdentify; return; } break; - case appl::ClientGateWayInterface::state::clientIdentify: + case appl::clientState::clientIdentify: { uint32_t serviceId = callObj->getServiceId(); if (serviceId == 0) { // This is 2 default service for the cient interface that manage the authorisation of view: if (callFunction == "getServiceCount") { - m_interfaceGateWayClient.answerValue(transactionId, m_clientServices.size()); + m_interfaceGateWayClient->answerValue(transactionId, m_clientServices.size(), m_uid); return; } if (callFunction == "getServiceList") { - m_interfaceGateWayClient.answerValue(transactionId, m_clientServices); + m_interfaceGateWayClient->answerValue(transactionId, m_clientServices, m_uid); //"ServiceManager/v0.1.0" return; } @@ -268,7 +239,7 @@ void appl::ClientGateWayInterface::onClientData(ememory::SharedPtr if (it == m_listConnectedService.end()) { // check if service is connectable ... if (std::find(m_clientServices.begin(), m_clientServices.end(), serviceName) == m_clientServices.end()) { - m_interfaceGateWayClient.answerError(transactionId, "UN-AUTHORIZED-SERVICE"); + m_interfaceGateWayClient->answerError(transactionId, "UN-AUTHORIZED-SERVICE"); return; } ememory::SharedPtr srv = m_gatewayInterface->get(serviceName); @@ -277,17 +248,17 @@ void appl::ClientGateWayInterface::onClientData(ememory::SharedPtr futLink.wait(); // TODO: Set timeout ... if (futLink.hasError() == true) { APPL_ERROR("Get error from the service ... LINK"); - m_interfaceGateWayClient.answerError(transactionId, "ERROR-CREATE-SERVICE-INSTANCE"); + m_interfaceGateWayClient->answerError(transactionId, "ERROR-CREATE-SERVICE-INSTANCE"); return; } m_listConnectedService.push_back(srv); - m_interfaceGateWayClient.answerValue(transactionId, m_listConnectedService.size()); + m_interfaceGateWayClient->answerValue(transactionId, m_listConnectedService.size(), m_uid); return; } - m_interfaceGateWayClient.answerError(transactionId, "CAN-NOT-CONNECT-SERVICE"); + m_interfaceGateWayClient->answerError(transactionId, "CAN-NOT-CONNECT-SERVICE"); return; } - m_interfaceGateWayClient.answerError(transactionId, "SERVICE-ALREADY-CONNECTED");; + m_interfaceGateWayClient->answerError(transactionId, "SERVICE-ALREADY-CONNECTED");; return; } if (callFunction == "unlink") { @@ -295,28 +266,28 @@ void appl::ClientGateWayInterface::onClientData(ememory::SharedPtr int64_t localServiceID = callObj->getParameter(0)-1; // Check if service already link: if (localServiceID >= m_listConnectedService.size()) { - m_interfaceGateWayClient.answerError(transactionId, "NOT-CONNECTED-SERVICE"); + m_interfaceGateWayClient->answerError(transactionId, "NOT-CONNECTED-SERVICE"); return; } zeus::Future futUnLink = m_listConnectedService[localServiceID]->m_interfaceClient.callClient(m_uid, "_delete"); futUnLink.wait(); // TODO: Set timeout ... if (futUnLink.hasError() == true) { APPL_ERROR("Get error from the service ... UNLINK"); - m_interfaceGateWayClient.answerError(transactionId, "ERROR-CREATE-SERVICE-INSTANCE"); + m_interfaceGateWayClient->answerError(transactionId, "ERROR-CREATE-SERVICE-INSTANCE"); return; } m_listConnectedService[localServiceID] = nullptr; - m_interfaceGateWayClient.answerValue(transactionId, true); + m_interfaceGateWayClient->answerValue(transactionId, true); return; } APPL_ERROR("Function does not exist ... '" << callFunction << "'"); - m_interfaceGateWayClient.answerError(transactionId, "CALL-UNEXISTING"); + m_interfaceGateWayClient->answerError(transactionId, "CALL-UNEXISTING"); return; } // decrease service ID ... serviceId -= 1; if (serviceId >= m_listConnectedService.size()) { - m_interfaceGateWayClient.answerError(transactionId, "NOT-CONNECTED-SERVICE"); + m_interfaceGateWayClient->answerError(transactionId, "NOT-CONNECTED-SERVICE"); return; } else { if (m_listConnectedService[serviceId] == nullptr) { @@ -338,7 +309,7 @@ void appl::ClientGateWayInterface::onClientData(ememory::SharedPtr tmpp->setTransactionId(transactionId); tmpp->setServiceId(serviceId+1); APPL_DEBUG("transmit=" << tmpp); - m_interfaceGateWayClient.writeBinary(tmpp); + m_interfaceGateWayClient->writeBinary(tmpp); // multiple send element ... return tmpp->getPartFinish(); }); @@ -347,6 +318,103 @@ void appl::ClientGateWayInterface::onClientData(ememory::SharedPtr } } -void appl::ClientGateWayInterface::returnMessage(ememory::SharedPtr _data) { - APPL_ERROR("Get call from the Service to the user ..."); + + + +appl::ClientGateWayInterface::ClientGateWayInterface(const std::string& _ip, uint16_t _port, const std::string& _userName, appl::GateWay* _gatewayInterface) : + m_state(appl::clientState::unconnect), + m_gatewayInterface(_gatewayInterface), + m_interfaceGateWayClient() { + APPL_INFO("----------------------------------------"); + APPL_INFO("-- NEW Connection to GateWay Font-end --"); + APPL_INFO("----------------------------------------"); + enet::Tcp connection = std::move(enet::connectTcpClient(_ip, _port)); + if (connection.getConnectionStatus() != enet::Tcp::status::link) { + APPL_ERROR("Can not connect the GateWay-front-end"); + return; + } + m_interfaceGateWayClient.setInterface(std::move(connection), false, _userName); + //m_userConnectionName = _userName; + m_state = appl::clientState::connect; + m_interfaceGateWayClient.connect(this, &appl::ClientGateWayInterface::onClientData); + m_interfaceGateWayClient.connect(true); + m_interfaceGateWayClient.setInterfaceName("cli-GateWay-front-end"); + // TODO : Check if user name is accepted ... +} + +appl::ClientGateWayInterface::~ClientGateWayInterface() { + APPL_TODO("Call All unlink ..."); + stop(); + APPL_INFO("-------------------------------------------"); + APPL_INFO("-- DELETE Connection to GateWay Font-end --"); + APPL_INFO("-------------------------------------------"); +} + +void appl::ClientGateWayInterface::stop() { + /* TODO ... + for (auto &it : m_listConnectedService) { + if (it == nullptr) { + continue; + } + it->m_interfaceClient.callClient(m_uid, "_delete"); + } + if (m_userService != nullptr) { + m_userService->m_interfaceClient.callClient(m_uid2, "_delete"); + m_userService = nullptr; + } + m_listConnectedService.clear(); + */ + m_interfaceGateWayClient.disconnect(); +} + +bool appl::ClientGateWayInterface::isAlive() { + return m_interfaceGateWayClient.isActive(); +} + + + +void appl::ClientGateWayInterface::onClientData(ememory::SharedPtr _value) { + if (_value == nullptr) { + return; + } + // Get client ID: + uint64_t clientId = _value->getClientId(); + //APPL_ERROR("[" << clientId << "] get message from front-end gateWay: " << _value); + int64_t localId = -1; + for (size_t iii=0; iiigetTransactionId(), m_gatewayInterface, &m_interfaceGateWayClient, clientId); + if (ret == false) { + return; + } + } + m_listUser[localId].onClientData(std::move(_value)); +} + +void appl::ClientGateWayInterface::answer(uint64_t _userSessionId, const ememory::SharedPtr& _data) { + for (auto &it : m_listUser) { + if (it.checkId(_userSessionId) == false) { + continue; + } + it.returnMessage(_data); + return; + } +} + +void appl::ClientGateWayInterface::clean() { + auto it = m_listUser.begin(); + while (it != m_listUser.end()) { + if (it->m_state == appl::clientState::disconnect) { + it = m_listUser.erase(it); + continue; + } + ++it; + } } \ No newline at end of file diff --git a/tools/gateway-back-end/appl/ClientGateWayInterface.hpp b/tools/gateway-back-end/appl/ClientGateWayInterface.hpp index c33b00e..c8343a7 100644 --- a/tools/gateway-back-end/appl/ClientGateWayInterface.hpp +++ b/tools/gateway-back-end/appl/ClientGateWayInterface.hpp @@ -11,41 +11,51 @@ namespace appl { class GateWay; - class ClientGateWayInterface { - private: - enum class state { - unconnect, // starting sate - connect, // zeust get a TCP connection - clientIdentify, // client defien the mode of the acces (anonymous,client/user) - disconnect // client is dead or loal disconnection - }; - enum state m_state; // state machine ... - private: - appl::GateWay* m_gatewayInterface; - zeus::WebServer m_interfaceGateWayClient; + enum class clientState { + unconnect, // starting sate + connect, // zeust get a TCP connection + clientIdentify, // client defien the mode of the acces (anonymous,client/user) + disconnect // client is dead or loal disconnection + }; + class userSpecificInterface { public: - ememory::SharedPtr m_userService; - std::vector> m_listConnectedService; + zeus::WebServer* m_interfaceGateWayClient; + appl::GateWay* m_gatewayInterface; uint64_t m_uid; - uint64_t m_uid2; + uint64_t m_localIdUser; + enum clientState m_state; // state machine ... + std::vector> m_listConnectedService; + ememory::SharedPtr m_userService; std::string m_userConnectionName; std::string m_clientName; std::vector m_clientgroups; std::vector m_clientServices; - public: - ClientGateWayInterface(const std::string& _ip, uint16_t _port, const std::string& _userName, appl::GateWay* _gatewayInterface); - virtual ~ClientGateWayInterface(); - void start(uint64_t _uid, uint64_t _uid2); - void stop(); + userSpecificInterface(); + ~userSpecificInterface(); + bool start(uint32_t _transactionId, appl::GateWay* _gatewayInterface, zeus::WebServer* _interfaceGateWayClient, uint64_t _id); void onClientData(ememory::SharedPtr _value); void returnMessage(ememory::SharedPtr _data); bool checkId(uint64_t _id) const { return m_uid == _id - || m_uid2 == _id; + || m_localIdUser == _id; } - bool isAlive(); - void answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp); + }; + class ClientGateWayInterface { + private: + enum clientState m_state; // state machine .. + std::vector m_listUser; + private: + appl::GateWay* m_gatewayInterface; + zeus::WebServer m_interfaceGateWayClient; + public: + ClientGateWayInterface(const std::string& _ip, uint16_t _port, const std::string& _userName, appl::GateWay* _gatewayInterface); + virtual ~ClientGateWayInterface(); + void stop(); + void onClientData(ememory::SharedPtr _value); + bool isAlive(); + void answer(uint64_t _userSessionId, const ememory::SharedPtr& _data); + void clean(); }; diff --git a/tools/gateway-back-end/appl/GateWay.cpp b/tools/gateway-back-end/appl/GateWay.cpp index c498ccf..189dd1d 100644 --- a/tools/gateway-back-end/appl/GateWay.cpp +++ b/tools/gateway-back-end/appl/GateWay.cpp @@ -74,7 +74,7 @@ appl::GateWay::GateWay() : propertyServiceIp(this, "service-ip", "127.0.0.1", "Ip to listen client", &appl::GateWay::onPropertyChangeServiceIp), propertyServicePort(this, "service-port", 1982, "Port to listen client", &appl::GateWay::onPropertyChangeServicePort), propertyServiceMax(this, "service-max", 80, "Maximum of client at the same time", &appl::GateWay::onPropertyChangeServiceMax) { - m_interfaceServiceServer = ememory::makeShared(this); + m_interfaceNewService = ememory::makeShared(this); } appl::GateWay::~GateWay() { @@ -83,7 +83,8 @@ appl::GateWay::~GateWay() { void appl::GateWay::start() { m_gateWayClient = ememory::makeShared(*propertyGateWayClientIp, *propertyGateWayClientPort, *propertyUserName, this); - m_interfaceServiceServer->start(*propertyServiceIp, *propertyServicePort); + + m_interfaceNewService->start(*propertyServiceIp, *propertyServicePort); } void appl::GateWay::stop() { @@ -117,22 +118,13 @@ std::vector appl::GateWay::getAllServiceName() { void appl::GateWay::answer(uint64_t _userSessionId, const ememory::SharedPtr& _data) { - /* - for (auto &it : m_gateWayClient) { - if (it == nullptr) { - continue; - } - if (it->checkId(_userSessionId) == false) { - continue; - } - it->returnMessage(_data); - return; + if (m_gateWayClient != nullptr) { + m_gateWayClient->answer(_userSessionId, _data); } - */ } void appl::GateWay::cleanIO() { - + APPL_VERBOSE("Check if something need to be clean ..."); auto it = m_serviceList.begin(); while (it != m_serviceList.end()) { if (*it != nullptr) { @@ -146,21 +138,9 @@ void appl::GateWay::cleanIO() { } ++it; } - /* - auto it2 = m_gateWayClient.begin(); - while (it2 != m_gateWayClient.end()) { - if (*it2 != nullptr) { - if ((*it2)->isAlive() == false) { - it2 = m_gateWayClient.erase(it2); - continue; - } - } else { - it2 = m_gateWayClient.erase(it2); - continue; - } - ++it2; + if (m_gateWayClient != nullptr) { + m_gateWayClient->clean(); } - */ } void appl::GateWay::onClientConnect(const bool& _value) { diff --git a/tools/gateway-back-end/appl/GateWay.hpp b/tools/gateway-back-end/appl/GateWay.hpp index 1ae4b72..32068b4 100644 --- a/tools/gateway-back-end/appl/GateWay.hpp +++ b/tools/gateway-back-end/appl/GateWay.hpp @@ -17,7 +17,7 @@ namespace appl { std::vector> m_serviceList; //!< List of all service availlable with their specific connection interface ememory::SharedPtr m_gateWayClient; //!< Interface with the Gateway Front End - ememory::SharedPtr m_interfaceServiceServer; + ememory::SharedPtr m_interfaceNewService; public: eproperty::Value propertyUserName; eproperty::Value propertyGateWayClientIp; diff --git a/tools/gateway-back-end/appl/ServiceInterface.cpp b/tools/gateway-back-end/appl/ServiceInterface.cpp index 24c23b2..8054207 100644 --- a/tools/gateway-back-end/appl/ServiceInterface.cpp +++ b/tools/gateway-back-end/appl/ServiceInterface.cpp @@ -8,11 +8,41 @@ #include #include #include +#include // todo : cHANGE THIS ... static const std::string protocolError = "PROTOCOL-ERROR"; +bool appl::ServiceInterface::requestURI(const std::string& _uri) { + APPL_WARNING("request connect on SERVICE: '" << _uri << "'"); + if(m_gatewayInterface == nullptr) { + APPL_ERROR("Can not access to the main GateWay interface (nullptr)"); + return false; + } + std::string tmpURI = _uri; + if (tmpURI.size() == 0) { + APPL_ERROR("Empty URI ... not supported ..."); + return false; + } + if (tmpURI[0] == '/') { + tmpURI = std::string(tmpURI.begin() + 1, tmpURI.end()); + } + std::vector listValue = etk::split(tmpURI, '?'); + if (listValue.size() == 0) { + APPL_ERROR("can not parse URI ..."); + return false; + } + tmpURI = listValue[0]; + if (etk::start_with(tmpURI, "service:") == false ) { + APPL_ERROR("Missing 'service:' at the start of the URI ..."); + return false; + } + m_name = &tmpURI[8]; + APPL_INFO("Connect service name : '" << m_name << "'"); + return true; +} + appl::ServiceInterface::ServiceInterface(enet::Tcp _connection, appl::GateWay* _gatewayInterface) : m_gatewayInterface(_gatewayInterface), @@ -35,6 +65,7 @@ bool appl::ServiceInterface::isAlive() { void appl::ServiceInterface::start() { m_interfaceClient.connect(this, &appl::ServiceInterface::onServiceData); + m_interfaceClient.connectUri(this, &appl::ServiceInterface::requestURI); m_interfaceClient.connect(); m_interfaceClient.setInterfaceName("srv-?"); } @@ -74,12 +105,14 @@ void appl::ServiceInterface::onServiceData(ememory::SharedPtr _val */ return; } + /* + DEPRECATED: if (_value->getType() == zeus::Buffer::typeMessage::call) { ememory::SharedPtr callObj = ememory::staticPointerCast(_value); std::string callFunction = callObj->getCall(); if (callFunction == "connect-service") { if (m_name != "") { - APPL_WARNING("Service interface ==> try change the servie name after init: '" << callObj->getParameter(0)); + APPL_WARNING("Service interface ==> try change the service name after init: '" << callObj->getParameter(0)); m_interfaceClient.answerValue(transactionId, false); return; } @@ -90,6 +123,7 @@ void appl::ServiceInterface::onServiceData(ememory::SharedPtr _val } answerProtocolError(transactionId, "unknow function"); } + */ if (_value->getClientId() == 0) { APPL_ERROR("Service interface ==> wrong service answer ==> missing 'client-id'"); return; diff --git a/tools/gateway-back-end/appl/ServiceInterface.hpp b/tools/gateway-back-end/appl/ServiceInterface.hpp index 66ae2d4..e52927d 100644 --- a/tools/gateway-back-end/appl/ServiceInterface.hpp +++ b/tools/gateway-back-end/appl/ServiceInterface.hpp @@ -11,8 +11,10 @@ namespace appl { class GateWay; class ClientGateWayInterface; + class userSpecificInterface; class ServiceInterface { friend class appl::ClientGateWayInterface; + friend class appl::userSpecificInterface; private: appl::GateWay* m_gatewayInterface; zeus::WebServer m_interfaceClient; @@ -23,6 +25,7 @@ namespace appl { void start(); void stop(); void onServiceData(ememory::SharedPtr _value); + bool requestURI(const std::string& _uri); public: void SendData(uint64_t _userSessionId, ememory::SharedPtr _data); const std::string& getName() { diff --git a/tools/gateway-front-end/appl/ClientInterface.cpp b/tools/gateway-front-end/appl/ClientInterface.cpp index 9c6fcdc..416231e 100644 --- a/tools/gateway-front-end/appl/ClientInterface.cpp +++ b/tools/gateway-front-end/appl/ClientInterface.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include @@ -56,9 +57,8 @@ bool appl::ClientInterface::requestURI(const std::string& _uri) { return true; } -void appl::ClientInterface::start(uint64_t _uid, uint64_t _uid2) { +void appl::ClientInterface::start(uint64_t _uid) { m_uid = _uid; - //m_uid2 = _uid2; m_state = appl::ClientInterface::state::connect; m_interfaceClient.connect(this, &appl::ClientInterface::onClientData); m_interfaceClient.connectUri(this, &appl::ClientInterface::requestURI); @@ -67,20 +67,9 @@ void appl::ClientInterface::start(uint64_t _uid, uint64_t _uid2) { } void appl::ClientInterface::stop() { - for (auto &it : m_listConnectedService) { - if (it == nullptr) { - continue; - } - it->m_interfaceClient.callClient(m_uid, "_delete"); + if (m_interfaceClient.isActive() == true) { + m_interfaceClient.disconnect(); } - /* - if (m_userGateWay != nullptr) { - m_userGateWay->m_interfaceClient.callClient(m_uid2, "_delete"); - m_userGateWay = nullptr; - } - */ - m_listConnectedService.clear(); - m_interfaceClient.disconnect(); } bool appl::ClientInterface::isAlive() { @@ -98,7 +87,7 @@ void appl::ClientInterface::onClientData(ememory::SharedPtr _value if (_value == nullptr) { return; } - APPL_ERROR("receive data : " << _value); + //APPL_ERROR("receive data : " << _value); uint32_t transactionId = _value->getTransactionId(); if (transactionId == 0) { APPL_ERROR("Protocol error ==>missing id"); @@ -143,6 +132,19 @@ void appl::ClientInterface::onClientData(ememory::SharedPtr _value } void appl::ClientInterface::returnMessage(ememory::SharedPtr _data) { - APPL_ERROR("Get call from the Service to the user ..."); + if (_data == nullptr) { + return; + } + if (_data->getType() == zeus::Buffer::typeMessage::ctrl) { + std::string value = static_cast(_data.get())->getCtrl(); + if (value == "DISCONNECT") { + m_state = appl::ClientInterface::state::disconnect; + m_interfaceClient.disconnect(true); + return; + } + APPL_ERROR("Receive message from GateWay CTRL : '" << value << "' ==> not managed" ); + return; + } + APPL_ERROR("Get call from the Service to the user ... " << _data); } diff --git a/tools/gateway-front-end/appl/ClientInterface.hpp b/tools/gateway-front-end/appl/ClientInterface.hpp index 0ed0542..c4b259a 100644 --- a/tools/gateway-front-end/appl/ClientInterface.hpp +++ b/tools/gateway-front-end/appl/ClientInterface.hpp @@ -25,9 +25,7 @@ namespace appl { bool requestURI(const std::string& _uri); public: ememory::SharedPtr m_userGateWay; - std::vector> m_listConnectedService; uint64_t m_uid; - uint64_t m_uid2; std::string m_userConnectionName; std::string m_clientName; std::vector m_clientgroups; @@ -35,13 +33,12 @@ namespace appl { public: ClientInterface(enet::Tcp _connection, appl::GateWay* _gatewayInterface); virtual ~ClientInterface(); - void start(uint64_t _uid, uint64_t _uid2); + void start(uint64_t _uid); void stop(); void onClientData(ememory::SharedPtr _value); void returnMessage(ememory::SharedPtr _data); bool checkId(uint64_t _id) const { - return m_uid == _id - || m_uid2 == _id; + return m_uid == _id; } bool isAlive(); diff --git a/tools/gateway-front-end/appl/GateWay.cpp b/tools/gateway-front-end/appl/GateWay.cpp index a8587b1..b47020f 100644 --- a/tools/gateway-front-end/appl/GateWay.cpp +++ b/tools/gateway-front-end/appl/GateWay.cpp @@ -75,12 +75,13 @@ void appl::GateWay::newClientGateWayBackEnd(enet::Tcp _connection) { void appl::GateWay::newClient(enet::Tcp _connection) { ZEUS_WARNING("New TCP connection (client)"); ememory::SharedPtr tmp = ememory::makeShared(std::move(_connection), this); - tmp->start(m_clientUID++, m_clientUID++); + tmp->start(m_clientUID); + m_clientUID += 2; // Need to do it, it is une impair ID by the Gateway m_clientList.push_back(tmp); } appl::GateWay::GateWay() : - m_clientUID(1), + m_clientUID(2), propertyClientIp(this, "client-ip", "127.0.0.1", "Ip to listen client", &appl::GateWay::onPropertyChangeClientIp), propertyClientPort(this, "client-port", 1983, "Port to listen client", &appl::GateWay::onPropertyChangeClientPort), propertyClientMax(this, "client-max", 80, "Maximum of client at the same time", &appl::GateWay::onPropertyChangeClientMax), diff --git a/tools/service-user/appl/main.cpp b/tools/service-user/appl/main.cpp index 213373d..be6930a 100644 --- a/tools/service-user/appl/main.cpp +++ b/tools/service-user/appl/main.cpp @@ -16,7 +16,7 @@ static std::mutex g_mutex; -static std::string g_userName; +static std::string g_basePath; static ejson::Document g_database; namespace appl { @@ -102,7 +102,7 @@ namespace appl { std::vector filterServices(std::string _clientName, std::vector _currentList) { std::unique_lock lock(g_mutex); // When connected to our session ==> we have no control access ... - if (_clientName == g_userName) { + if (_clientName == g_basePath) { return _currentList; } std::vector out; @@ -112,120 +112,141 @@ namespace appl { }; } +bool SERVICE_IO_init(std::string _basePath) { + g_basePath = _basePath; + std::unique_lock lock(g_mutex); + APPL_WARNING("Load USER: " << g_basePath); + bool ret = g_database.load(g_basePath + "config.json"); + if (ret == false) { + APPL_WARNING(" ==> LOAD error"); + } + return true; +} + +bool SERVICE_IO_uninit() { + std::unique_lock lock(g_mutex); + APPL_DEBUG("Store User Info:"); + bool ret = g_database.storeSafe(g_basePath + "config.json"); + if (ret == false) { + APPL_WARNING(" ==> Store error"); + return false; + } + APPL_WARNING("delete USER [STOP]"); + return true; +} + +bool SERVICE_IO_execute(std::string _ip, uint16_t _port) { + APPL_INFO("==========================================================="); + APPL_INFO("== ZEUS instanciate service: " << SERVICE_NAME << " [START]"); + APPL_INFO("==========================================================="); + zeus::ServiceType serviceInterface([](ememory::SharedPtr _client){ + return ememory::makeShared(_client); + }); + if (_ip != "") { + serviceInterface.propertyIp.set(_ip); + } + if (_port != 0) { + serviceInterface.propertyPort.set(_port); + } + serviceInterface.propertyNameService.set(SERVICE_NAME); + serviceInterface.setDescription("user interface management"); + serviceInterface.setVersion("0.1.0"); + serviceInterface.setType("USER", 1); + serviceInterface.addAuthor("Heero Yui", "yui.heero@gmail.com"); + zeus::AbstractFunction* func = serviceInterface.advertise("checkTocken", &appl::SystemService::checkTocken); + if (func != nullptr) { + func->setDescription("Check if a user tocken is correct or not"); + func->addParam("clientName", "Name of the client"); + func->addParam("tocken", "String containing the Tocken"); + } + func = serviceInterface.advertise("checkAuth", &appl::SystemService::checkAuth); + if (func != nullptr) { + func->setDescription("Check the password of the curent user"); + func->addParam("password", "client/user password"); + } + func = serviceInterface.advertise("getGroups", &appl::SystemService::getGroups); + if (func != nullptr) { + func->setDescription("Get list of group availlable for a client name"); + func->addParam("clientName", "Name of the client"); + } + func = serviceInterface.advertise("filterServices", &appl::SystemService::filterServices); + if (func != nullptr) { + func->setDescription("Filter a list of service with the cuurent profile of the user (restrict area)"); + func->addParam("clientName", "Name of the client"); + func->addParam("currentList", "Vector of name of the services"); + } + APPL_INFO("==========================================================="); + APPL_INFO("== ZEUS service: " << *serviceInterface.propertyNameService << " [service instanciate]"); + APPL_INFO("==========================================================="); + if (serviceInterface.connect() == false) { + APPL_INFO("wait 5 second ..."); + std::this_thread::sleep_for(std::chrono::seconds(5)); + return false; + } + if (serviceInterface.GateWayAlive() == false) { + APPL_INFO("==========================================================="); + APPL_INFO("== ZEUS service: " << *serviceInterface.propertyNameService << " [STOP] Can not connect to the GateWay"); + APPL_INFO("==========================================================="); + APPL_INFO("wait 5 second ..."); + std::this_thread::sleep_for(std::chrono::seconds(5)); + return false; + } + int32_t iii=0; + while (serviceInterface.GateWayAlive() == true) { + std::this_thread::sleep_for(std::chrono::seconds(10)); + serviceInterface.pingIsAlive(); + APPL_INFO("service in waiting ... " << iii << "/inf"); + iii++; + } + APPL_INFO("Disconnect service ..."); + serviceInterface.disconnect(); + APPL_INFO("==========================================================="); + APPL_INFO("== ZEUS service: " << *serviceInterface.propertyNameService << " [STOP] GateWay Stop"); + APPL_INFO("==========================================================="); + return true; +} + +#ifndef APPL_BUILD_SHARED_LIBRARY int main(int _argc, const char *_argv[]) { etk::init(_argc, _argv); zeus::init(_argc, _argv); std::string ip; uint16_t port = 0; + std::string basePath; for (int32_t iii=0; iii<_argc ; ++iii) { std::string data = _argv[iii]; if (etk::start_with(data, "--ip=") == true) { ip = std::string(&data[5]); } else if (etk::start_with(data, "--port=") == true) { port = etk::string_to_uint16_t(std::string(&data[7])); - } else if (etk::start_with(data, "--name=") == true) { - g_userName = std::string(&data[7]); + } else if (etk::start_with(data, "--base-path=") == true) { + basePath = std::string(&data[12]); } else if ( data == "-h" || data == "--help") { APPL_PRINT(etk::getApplicationName() << " - help : "); APPL_PRINT(" " << _argv[0] << " [options]"); - APPL_PRINT(" --name=XXX User name of the service"); + APPL_PRINT(" --base-path=XXX base path to search data (default: 'USERDATA:')"); APPL_PRINT(" --ip=XXX Server connection IP (default: 1.7.0.0.1)"); APPL_PRINT(" --port=XXX Server connection PORT (default: 1983)"); return -1; } } - if (g_userName.size() == 0) { - APPL_ERROR("Missing User name when runnig service"); - exit(-1); - } - { - std::unique_lock lock(g_mutex); - APPL_WARNING("Load USER: " << g_userName); - bool ret = g_database.load(std::string("USERDATA:") + g_userName + ".json"); - if (ret == false) { - APPL_WARNING(" ==> LOAD error"); - } + if (basePath.size() == 0) { + basePath = "USERDATA:"; + APPL_PRINT("Use base path: " << basePath); } + SERVICE_IO_init(basePath); // TODO: Remove the While true, ==> sevice must be spown by a user call, if a service die, the wall system will die ... while (true) { - APPL_INFO("==========================================================="); - APPL_INFO("== ZEUS instanciate service: " << SERVICE_NAME << " [START]"); - APPL_INFO("==========================================================="); - - zeus::ServiceType serviceInterface([](ememory::SharedPtr _client){ - return ememory::makeShared(_client); - }); - if (ip != "") { - serviceInterface.propertyIp.set(ip); - } - if (port != 0) { - serviceInterface.propertyPort.set(port); - } - serviceInterface.propertyNameService.set(SERVICE_NAME); - serviceInterface.setDescription("user interface management"); - serviceInterface.setVersion("0.1.0"); - serviceInterface.setType("USER", 1); - serviceInterface.addAuthor("Heero Yui", "yui.heero@gmail.com"); - zeus::AbstractFunction* func = serviceInterface.advertise("checkTocken", &appl::SystemService::checkTocken); - if (func != nullptr) { - func->setDescription("Check if a user tocken is correct or not"); - func->addParam("clientName", "Name of the client"); - func->addParam("tocken", "String containing the Tocken"); - } - func = serviceInterface.advertise("checkAuth", &appl::SystemService::checkAuth); - if (func != nullptr) { - func->setDescription("Check the password of the curent user"); - func->addParam("password", "client/user password"); - } - func = serviceInterface.advertise("getGroups", &appl::SystemService::getGroups); - if (func != nullptr) { - func->setDescription("Get list of group availlable for a client name"); - func->addParam("clientName", "Name of the client"); - } - func = serviceInterface.advertise("filterServices", &appl::SystemService::filterServices); - if (func != nullptr) { - func->setDescription("Filter a list of service with the cuurent profile of the user (restrict area)"); - func->addParam("clientName", "Name of the client"); - func->addParam("currentList", "Vector of name of the services"); - } - APPL_INFO("==========================================================="); - APPL_INFO("== ZEUS service: " << *serviceInterface.propertyNameService << " [service instanciate]"); - APPL_INFO("==========================================================="); - serviceInterface.connect(); - if (serviceInterface.GateWayAlive() == false) { - APPL_INFO("==========================================================="); - APPL_INFO("== ZEUS service: " << *serviceInterface.propertyNameService << " [STOP] Can not connect to the GateWay"); - APPL_INFO("==========================================================="); - APPL_INFO("wait 5 second ..."); - std::this_thread::sleep_for(std::chrono::seconds(5)); - continue; - } - int32_t iii=0; - while (serviceInterface.GateWayAlive() == true) { - std::this_thread::sleep_for(std::chrono::seconds(10)); - serviceInterface.pingIsAlive(); - APPL_INFO("service in waiting ... " << iii << "/inf"); - iii++; - } - serviceInterface.disconnect(); - APPL_INFO("==========================================================="); - APPL_INFO("== ZEUS service: " << *serviceInterface.propertyNameService << " [STOP] GateWay Stop"); - APPL_INFO("==========================================================="); + SERVICE_IO_execute(ip, port); } APPL_INFO("Stop service ==> flush internal datas ..."); - { - std::unique_lock lock(g_mutex); - APPL_DEBUG("Store User Info:"); - bool ret = g_database.storeSafe(std::string("USERDATA:") + g_userName + ".json"); - if (ret == false) { - APPL_WARNING(" ==> Store error"); - } - APPL_WARNING("delete USER [STOP]"); - } + SERVICE_IO_uninit(); APPL_INFO("==========================================================="); APPL_INFO("== ZEUS service: " << SERVICE_NAME << " [END-APPLICATION]"); APPL_INFO("==========================================================="); return 0; } + +#endif diff --git a/zeus/Buffer.cpp b/zeus/Buffer.cpp index e3907f8..ab00785 100644 --- a/zeus/Buffer.cpp +++ b/zeus/Buffer.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -21,6 +22,8 @@ namespace etk { switch (_value) { case zeus::Buffer::typeMessage::unknow: return "unknow"; + case zeus::Buffer::typeMessage::ctrl: + return "ctrl"; case zeus::Buffer::typeMessage::call: return "call"; case zeus::Buffer::typeMessage::answer: @@ -43,12 +46,14 @@ static enum zeus::Buffer::typeMessage getTypeType(uint16_t _value) { case 0: return zeus::Buffer::typeMessage::unknow; case 1: - return zeus::Buffer::typeMessage::call; + return zeus::Buffer::typeMessage::ctrl; case 2: - return zeus::Buffer::typeMessage::answer; + return zeus::Buffer::typeMessage::call; case 3: - return zeus::Buffer::typeMessage::data; + return zeus::Buffer::typeMessage::answer; case 4: + return zeus::Buffer::typeMessage::data; + case 5: return zeus::Buffer::typeMessage::event; } return zeus::Buffer::typeMessage::unknow; @@ -106,8 +111,9 @@ std::ostream& zeus::operator <<(std::ostream& _os, ememory::SharedPtr zeus::Buffer::create(const std::vector switch (type) { case zeus::Buffer::typeMessage::unknow: return nullptr; + case zeus::Buffer::typeMessage::ctrl: { + ememory::SharedPtr value = zeus::BufferCtrl::create(); + if (value == nullptr) { + return nullptr; + } + value->setTransactionId(header.transactionID); + value->setClientId(header.clientID); + value->setPartFinish((header.flags & ZEUS_BUFFER_FLAG_FINISH) != 0); + value->composeWith(&_buffer[sizeof(headerBin)], + _buffer.size() - sizeof(headerBin)); + return value; + } + break; case zeus::Buffer::typeMessage::call: { ememory::SharedPtr value = zeus::BufferCall::create(); if (value == nullptr) { diff --git a/zeus/Buffer.hpp b/zeus/Buffer.hpp index 094824d..09ec1f0 100644 --- a/zeus/Buffer.hpp +++ b/zeus/Buffer.hpp @@ -131,6 +131,7 @@ namespace zeus { */ static ememory::SharedPtr create(const std::vector& _buffer); protected: + uint32_t m_interfaceID; //!< For debug ==> unterface ID ... headerBin m_header; //!< header of the protocol std::vector m_multipleSend; //!< Async element to send data on the webinterface when too big ... public: @@ -166,6 +167,16 @@ namespace zeus { * @brief Chear the buffer */ void clear(); + /** + * @brief Get the interface identifier of the packet + * @return value of the interface + */ + uint32_t getInterfaceId() const; + /** + * @brief Set the interface identifier of the packet + * @param[in] _value New interface id + */ + void setInterfaceId(uint32_t _value); /** * @brief Get the transaction identifier of the packet * @return value of the transaction @@ -215,10 +226,11 @@ namespace zeus { */ enum class typeMessage { unknow = 0x0000, //!< Init value - call = 0x0001, //!< Remote call on a service ID - answer = 0x0002, //!< Answer from a previous call - data = 0x0003, //!< data message happend when partId > 0 it compleate the data of a parameter or an answer or an event - event = 0x0004, //!< event message + ctrl = 0x0001, //!< Control message + call = 0x0002, //!< Remote call on a service ID + answer = 0x0003, //!< Answer from a previous call + data = 0x0004, //!< data message happend when partId > 0 it compleate the data of a parameter or an answer or an event + event = 0x0005, //!< event message }; /** * @brief Get the type of the buffer diff --git a/zeus/BufferCtrl.cpp b/zeus/BufferCtrl.cpp new file mode 100644 index 0000000..0b0c29a --- /dev/null +++ b/zeus/BufferCtrl.cpp @@ -0,0 +1,57 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2016, Edouard DUPIN, all right reserved + * @license APACHE v2.0 (see license file) + */ +#include +#include +#include +#include +#include +#include + +void zeus::BufferCtrl::generateDisplay(std::ostream& _os) const { + zeus::Buffer::generateDisplay(_os); + _os << " '" + m_ctrlValue + "'"; +} + +const std::string& zeus::BufferCtrl::getCtrl() const { + return m_ctrlValue; +} + +void zeus::BufferCtrl::setCtrl(const std::string& _value) { + m_ctrlValue = _value; +} + +bool zeus::BufferCtrl::writeOn(enet::WebSocket& _interface) { + zeus::Buffer::writeOn(_interface); + _interface.writeData((uint8_t*)m_ctrlValue.c_str(), m_ctrlValue.size() + 1); + return true; +} + +void zeus::BufferCtrl::composeWith(const uint8_t* _buffer, uint32_t _lenght) { + // First element iw the call name, after, this is the parameters... + // parse the string: (call name) + uint32_t pos = 0; + m_ctrlValue.clear(); + while( pos < _lenght + && (char)_buffer[pos] != '\0') { + m_ctrlValue += _buffer[pos]; + pos++; + } + pos++; + // TODO : Check if some parameter are present ... ==> must create an error +} + +void zeus::BufferCtrl::appendBufferData(ememory::SharedPtr _obj) { + ZEUS_ERROR("A ctrl message can not have data ..."); +} + +// ------------------------------------------------------------------------------------ +// -- Factory +// ------------------------------------------------------------------------------------ + + +ememory::SharedPtr zeus::BufferCtrl::create() { + return ememory::SharedPtr(new zeus::BufferCtrl); +} diff --git a/zeus/BufferCtrl.hpp b/zeus/BufferCtrl.hpp new file mode 100644 index 0000000..4955c7b --- /dev/null +++ b/zeus/BufferCtrl.hpp @@ -0,0 +1,52 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2016, Edouard DUPIN, all right reserved + * @license APACHE v2.0 (see license file) + */ +#pragma once +#include +#include +#include +#include + +namespace zeus { + class BufferCtrl : + public Buffer { + friend class zeus::Buffer; + protected: + std::string m_ctrlValue; + protected: + /** + * @brief basic constructor (hidden to force the use of ememory::SharedPtr) @ref zeus::BufferCall::create + */ + BufferCtrl() { + m_header.flags = ZEUS_BUFFER_FLAG_FINISH + uint8_t(zeus::Buffer::typeMessage::ctrl); + }; + void composeWith(const uint8_t* _buffer, uint32_t _lenght) override; + void appendBufferData(ememory::SharedPtr _obj) override; + bool writeOn(enet::WebSocket& _interface) override; + void generateDisplay(std::ostream& _os) const override; + public: + /** + * @brief Create a shared pointer on the BufferCall + * @return Allocated Buffer. + */ + static ememory::SharedPtr create(); + public: + enum zeus::Buffer::typeMessage getType() const override { + return zeus::Buffer::typeMessage::ctrl; + } + /** + * @brief get the call value of the buffer + * @return string of the function to call + */ + const std::string& getCtrl() const; + /** + * @brief Set the call value of the buffer + * @param[in] _value Function to call + */ + void setCtrl(const std::string& _value); + + }; +} + diff --git a/zeus/Service.cpp b/zeus/Service.cpp index 9fc2c76..d932e99 100644 --- a/zeus/Service.cpp +++ b/zeus/Service.cpp @@ -81,31 +81,28 @@ void zeus::Service::onPropertyChangePort(){ } -void zeus::Service::connect(uint32_t _numberRetry){ +bool zeus::Service::connect(uint32_t _numberRetry){ disconnect(); ZEUS_DEBUG("connect [START]"); enet::Tcp connection = std::move(enet::connectTcpClient(*propertyIp, *propertyPort, _numberRetry)); if (connection.getConnectionStatus() != enet::Tcp::status::link) { ZEUS_DEBUG("connect [STOP] ==> can not connect"); - return; + return false; } m_interfaceClient = ememory::makeShared(); if (m_interfaceClient == nullptr) { ZEUS_ERROR("Can not allocate interface ..."); - return; + return false; } m_interfaceClient->connect(this, &zeus::Service::onClientData); - m_interfaceClient->setInterface(std::move(connection), false, propertyNameService.get()); + m_interfaceClient->setInterface(std::move(connection), false, std::string("service:") + propertyNameService.get()); m_interfaceClient->connect(); - // TODO : Check error ... - /* - if (ret.get() == false) { - ZEUS_ERROR("Can not configure the interface for the service with the current name ..."); - m_interfaceClient->disconnect(); - return; + if (m_interfaceClient->isActive() == false) { + ZEUS_ERROR("Can not connect service ..."); + return false; } - */ ZEUS_DEBUG("connect [STOP]"); + return true; } void zeus::Service::disconnect(){ diff --git a/zeus/Service.hpp b/zeus/Service.hpp index 1f46283..a44b7e1 100644 --- a/zeus/Service.hpp +++ b/zeus/Service.hpp @@ -128,9 +128,9 @@ namespace zeus { /** * @brief * @param[in] - * @return + * @return true The connection is done corectly, false otherwise */ - void connect(uint32_t _numberRetry = 1); + bool connect(uint32_t _numberRetry = 1); /** * @brief * @param[in] diff --git a/zeus/WebServer.cpp b/zeus/WebServer.cpp index 1af405c..fa7f9c8 100644 --- a/zeus/WebServer.cpp +++ b/zeus/WebServer.cpp @@ -8,6 +8,7 @@ #include #include +#include ememory::SharedPtr zeus::createBaseCall(uint64_t _transactionId, const std::string& _functionName, const uint32_t& _serviceId) { @@ -26,11 +27,13 @@ void zeus::createParam(int32_t _paramId, ememory::SharedPtr _o } +static uint32_t interfaceId = 1; zeus::WebServer::WebServer() : m_connection(), m_observerElement(nullptr), m_threadAsync(nullptr) { + m_interfaceId = interfaceId++; m_threadAsyncRunning = false; m_transmissionId = 1; } @@ -39,6 +42,7 @@ zeus::WebServer::WebServer(enet::Tcp _connection, bool _isServer) : m_connection(), m_observerElement(nullptr), m_threadAsync(nullptr) { + m_interfaceId = interfaceId++; m_threadAsyncRunning = false; m_transmissionId = 1; setInterface(std::move(_connection), _isServer); @@ -140,6 +144,7 @@ class SendAsyncBinary { if (obj == nullptr) { return true; } + //obj->setInterfaceId(m_interfaceId); obj->setServiceId(m_serviceId); obj->setTransactionId(m_transactionId); obj->setPartId(m_partId); @@ -151,6 +156,10 @@ class SendAsyncBinary { } }; +#define ZEUS_LOG_INPUT_OUTPUT ZEUS_WARNING +//#define ZEUS_LOG_INPUT_OUTPUT ZEUS_VERBOSE + + int32_t zeus::WebServer::writeBinary(ememory::SharedPtr _obj) { if (m_connection.isAlive() == false) { return -2; @@ -158,7 +167,8 @@ int32_t zeus::WebServer::writeBinary(ememory::SharedPtr _obj) { if (_obj->haveAsync() == true) { _obj->setPartFinish(false); } - ZEUS_VERBOSE("Send :" << _obj); + _obj->setInterfaceId(m_interfaceId); + ZEUS_LOG_INPUT_OUTPUT("Send :" << _obj); if (_obj->writeOn(m_connection) == true) { m_connection.send(); if (_obj->haveAsync() == true) { @@ -181,6 +191,10 @@ bool zeus::WebServer::onReceiveUri(const std::string& _uri, const std::vector& _frame, bool _isBinary return; } ememory::SharedPtr dataRaw = zeus::Buffer::create(_frame); + dataRaw->setInterfaceId(m_interfaceId); newBuffer(dataRaw); } @@ -199,7 +214,7 @@ void zeus::WebServer::ping() { } void zeus::WebServer::newBuffer(ememory::SharedPtr _buffer) { - ZEUS_VERBOSE("Receive :" << _buffer); + ZEUS_LOG_INPUT_OUTPUT("Receive :" << _buffer); zeus::FutureBase future; uint64_t tid = _buffer->getTransactionId(); if (tid == 0) { @@ -328,7 +343,7 @@ zeus::FutureBase zeus::WebServer::callForward(uint32_t _clientId, //ret.setSynchronous(); if (isActive() == false) { - ememory::SharedPtr obj = zeus::BufferAnswer::create(); + auto obj = zeus::BufferAnswer::create(); obj->addError("NOT-CONNECTED", "Client interface not connected (no TCP)"); return zeus::FutureBase(0, obj, _callback); } @@ -366,8 +381,19 @@ void zeus::WebServer::callForwardMultiple(uint32_t _clientId, ZEUS_ERROR("Can not transfer part of a message ..."); } +void zeus::WebServer::sendCtrl(const std::string& _ctrlValue, uint32_t _clientId) { + auto ctrl = zeus::BufferCtrl::create(); + if (ctrl == nullptr) { + return; + } + ctrl->setTransactionId(getId()); + ctrl->setClientId(_clientId); + ctrl->setCtrl(_ctrlValue); + writeBinary(ctrl); +} + void zeus::WebServer::answerError(uint64_t _clientTransactionId, const std::string& _errorValue, const std::string& _errorHelp, uint32_t _clientId) { - ememory::SharedPtr answer = zeus::BufferAnswer::create(); + auto answer = zeus::BufferAnswer::create(); if (answer == nullptr) { return; } @@ -379,7 +405,7 @@ void zeus::WebServer::answerError(uint64_t _clientTransactionId, const std::stri void zeus::WebServer::answerVoid(uint64_t _clientTransactionId, uint32_t _clientId) { - ememory::SharedPtr answer = zeus::BufferAnswer::create(); + auto answer = zeus::BufferAnswer::create(); if (answer == nullptr) { return; } diff --git a/zeus/WebServer.hpp b/zeus/WebServer.hpp index b46aca6..4651624 100644 --- a/zeus/WebServer.hpp +++ b/zeus/WebServer.hpp @@ -90,6 +90,7 @@ namespace zeus { class WebServer { private: enet::WebSocket m_connection; + uint32_t m_interfaceId; uint16_t m_transmissionId; uint16_t getId() { return m_transmissionId++; @@ -353,9 +354,10 @@ namespace zeus { void answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp); /** - * @brief - * @param[in] - * @return + * @brief Send an Answer of a function with single value + * @param[in] _clientTransactionId Transaction ID + * @param[in] _value ... Value to return + * @param[in] _clientId Client to send control */ template void answerValue(uint64_t _clientTransactionId, ZEUS_ARG _value, uint32_t _clientId=0) { @@ -366,17 +368,27 @@ namespace zeus { writeBinary(answer); } /** - * @brief - * @param[in] - * @return + * @brief Send an Answer value (no value to set ==> void return of function) + * @param[in] _clientTransactionId Transaction ID + * @param[in] _clientId Client to send control */ void answerVoid(uint64_t _clientTransactionId, uint32_t _clientId=0); /** - * @brief - * @param[in] - * @return + * @brief Send an Answer error of a function + * @param[in] _clientTransactionId Transaction ID + * @param[in] _errorValue Value of the error + * @param[in] _errorComment Help comment of the error + * @param[in] _clientId Client to send control */ void answerError(uint64_t _clientTransactionId, const std::string& _errorValue, const std::string& _errorComment="", uint32_t _clientId=0); + /** + * @brief Send a control on the Interface + * @param[in] _clientTransactionId Transaction ID + * @param[in] _ctrlValue Value of the control + * @param[in] _clientId Client to send control + * @return + */ + void sendCtrl(const std::string& _ctrlValue, uint32_t _clientId); }; }