From fa38f8d6371f83c443251251aa72b69612a64b61 Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Tue, 29 Nov 2016 21:39:39 +0100 Subject: [PATCH] [DEV] review entire model... --- lutin_zeus.py | 2 + test/client/appl/main.cpp | 6 +- tools/gateway/appl/DirectInterface.cpp | 79 +++++++ tools/gateway/appl/DirectInterface.hpp | 30 +++ tools/gateway/appl/GateWay.cpp | 34 ++- tools/gateway/appl/GateWay.hpp | 16 +- tools/gateway/appl/IOInterface.cpp | 269 ++++++++++++++++++++++++ tools/gateway/appl/IOInterface.hpp | 41 ++++ tools/gateway/appl/RouterInterface.cpp | 160 ++++++-------- tools/gateway/appl/RouterInterface.hpp | 55 ++--- tools/gateway/appl/ServiceInterface.hpp | 2 +- tools/gateway/lutin_zeus-gateway.py | 4 +- tools/launcher/appl/main.cpp | 32 +-- tools/router/appl/ClientInterface.cpp | 74 +++---- tools/router/appl/ClientInterface.hpp | 19 +- tools/router/appl/GateWayInterface.cpp | 82 ++++---- tools/router/appl/GateWayInterface.hpp | 7 +- tools/router/appl/Router.cpp | 15 +- tools/router/appl/Router.hpp | 1 - zeus/AbstractFunctionTypeClass.hpp | 12 +- zeus/AbstractFunctionTypeDirect.hpp | 12 +- zeus/Buffer.cpp | 38 +++- zeus/Buffer.hpp | 22 +- zeus/BufferParameter_addParameter.cpp | 16 +- zeus/Client.cpp | 138 ++++++++++-- zeus/Client.hpp | 41 +++- zeus/FutureBase.cpp | 23 +- zeus/FutureBase.hpp | 10 +- zeus/FutureData.hpp | 2 +- zeus/Object.cpp | 110 ++++++++++ zeus/Object.hpp | 194 +++++++++++++++++ zeus/Service.cpp | 19 +- zeus/Service.hpp | 61 +++--- zeus/ServiceRemote.hpp | 21 -- zeus/WebServer.cpp | 55 ++--- zeus/WebServer.hpp | 44 ++-- 36 files changed, 1289 insertions(+), 457 deletions(-) create mode 100644 tools/gateway/appl/DirectInterface.cpp create mode 100644 tools/gateway/appl/DirectInterface.hpp create mode 100644 tools/gateway/appl/IOInterface.cpp create mode 100644 tools/gateway/appl/IOInterface.hpp create mode 100644 zeus/Object.cpp create mode 100644 zeus/Object.hpp diff --git a/lutin_zeus.py b/lutin_zeus.py index 56e6b3f..261e3cd 100644 --- a/lutin_zeus.py +++ b/lutin_zeus.py @@ -54,6 +54,7 @@ def configure(target, my_module): 'zeus/BufferParameter_getParameter.cpp', 'zeus/ParamType.cpp', 'zeus/Client.cpp', + 'zeus/Object.cpp', 'zeus/RemoteProcessCall.cpp', 'zeus/Service.cpp', 'zeus/ServiceRemote.cpp', @@ -83,6 +84,7 @@ def configure(target, my_module): 'zeus/ParamType.hpp', 'zeus/debug.hpp', 'zeus/Client.hpp', + 'zeus/Object.hpp', 'zeus/RemoteProcessCall.hpp', 'zeus/Service.hpp', 'zeus/ServiceRemote.hpp', diff --git a/test/client/appl/main.cpp b/test/client/appl/main.cpp index 7e806c3..cecd5b1 100644 --- a/test/client/appl/main.cpp +++ b/test/client/appl/main.cpp @@ -73,10 +73,10 @@ int main(int _argc, const char *_argv[]) { APPL_INFO(" ----------------------------------"); APPL_INFO(" -- Get service count"); APPL_INFO(" ----------------------------------"); - zeus::Future retNbService = client1.call("getServiceCount"); + zeus::Future retNbService = client1.call(ZEUS_NO_ID_OBJECT, ZEUS_ID_GATEWAY, "getServiceCount"); retNbService.wait(); APPL_INFO("Nb services = " << retNbService.get()); - zeus::Future> retServiceList = client1.call("getServiceList"); + zeus::Future> retServiceList = client1.call(ZEUS_NO_ID_OBJECT, ZEUS_ID_GATEWAY, "getServiceList"); retServiceList.wait(); APPL_INFO("List services:"); for (auto &it: retServiceList.get()) { @@ -145,7 +145,7 @@ int main(int _argc, const char *_argv[]) { APPL_INFO(" ----------------------------------"); APPL_INFO(" -- Get service picture"); APPL_INFO(" ----------------------------------"); - if (true) { + if (false) { zeus::service::ProxyPicture remoteServicePicture = client1.getService("picture"); if (remoteServicePicture.exist() == true) { zeus::Future> retCall = remoteServicePicture.getAlbums().wait(); diff --git a/tools/gateway/appl/DirectInterface.cpp b/tools/gateway/appl/DirectInterface.cpp new file mode 100644 index 0000000..b4fdb14 --- /dev/null +++ b/tools/gateway/appl/DirectInterface.cpp @@ -0,0 +1,79 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2016, Edouard DUPIN, all right reserved + * @license APACHE v2.0 (see license file) + */ + +#include +#include +#include +#include +#include + + +#include + +static const std::string protocolError = "PROTOCOL-ERROR"; + +appl::DirectInterface::DirectInterface(enet::Tcp _connection) : + m_interfaceWeb(std::move(_connection), true) { + m_uid = 0; + m_state = appl::clientState::unconnect; + APPL_INFO("-----------------------"); + APPL_INFO("-- NEW Direct Client --"); + APPL_INFO("-----------------------"); +} + +appl::DirectInterface::~DirectInterface() { + APPL_INFO("--------------------------"); + APPL_INFO("-- DELETE Direct Client --"); + APPL_INFO("--------------------------"); +} +/* +void appl::clientSpecificInterface::answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp) { + m_interfaceWeb->answerError(_transactionId, m_routeurUID, ZEUS_ID_SERVICE_ROOT, protocolError, _errorHelp); + m_interfaceWeb->sendCtrl(m_routeurUID, ZEUS_ID_SERVICE_ROOT, "DISCONNECT"); + m_state = appl::clientState::disconnect; +} +*/ +bool appl::DirectInterface::requestURI(const std::string& _uri) { + APPL_WARNING("request Direct connection: '" << _uri << "'"); + 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, "directIO") == false ) { + APPL_ERROR("Missing 'directIO:' at the start of the URI ..."); + return false; + } + return true; +} + +bool appl::DirectInterface::start(appl::GateWay* _gateway, uint16_t _id) { + appl::IOInterface::start(_gateway, _id); + m_interfaceWeb.connect(this, &appl::DirectInterface::receive); + m_interfaceWeb.connectUri(this, &appl::DirectInterface::requestURI); + m_interfaceWeb.connect(); + m_interfaceWeb.setInterfaceName("DIO-?"); + //APPL_WARNING("[" << m_uid << "] New client : " << m_clientName); + return true; +} + +void appl::DirectInterface::receive(ememory::SharedPtr _value) { + appl::IOInterface::receive(_value); +} + +void appl::DirectInterface::send(ememory::SharedPtr _value) { + m_interfaceWeb.writeBinary(_value); +} + diff --git a/tools/gateway/appl/DirectInterface.hpp b/tools/gateway/appl/DirectInterface.hpp new file mode 100644 index 0000000..29f9287 --- /dev/null +++ b/tools/gateway/appl/DirectInterface.hpp @@ -0,0 +1,30 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2016, Edouard DUPIN, all right reserved + * @license APACHE v2.0 (see license file) + */ +#pragma once + +#include +#include +#include + +namespace appl { + class GateWay; + class DirectInterface : public appl::IOInterface { + public: + zeus::WebServer m_interfaceWeb; + public: + DirectInterface(enet::Tcp _connection); + ~DirectInterface(); + bool start(appl::GateWay* _gateway, uint16_t _id); + void receive(ememory::SharedPtr _data); + void send(ememory::SharedPtr _data); + bool requestURI(const std::string& _uri); + //void answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp); + zeus::WebServer* getInterface() { + return &m_interfaceWeb; + } + }; +} + diff --git a/tools/gateway/appl/GateWay.cpp b/tools/gateway/appl/GateWay.cpp index db26931..d9adabd 100644 --- a/tools/gateway/appl/GateWay.cpp +++ b/tools/gateway/appl/GateWay.cpp @@ -7,6 +7,8 @@ #include #include #include +#include +#include namespace appl { @@ -61,18 +63,19 @@ namespace appl { void appl::GateWay::newService(enet::Tcp _connection) { APPL_WARNING("New TCP connection (service)"); - ememory::SharedPtr tmp = ememory::makeShared(std::move(_connection), this); - tmp->start(); - m_serviceList.push_back(tmp); + ememory::SharedPtr tmp = ememory::makeShared(std::move(_connection)); + tmp->start(this, m_idIncrement++); + m_listIODirect.push_back(tmp); } appl::GateWay::GateWay() : + m_idIncrement(10), propertyUserName(this, "user", "no-name", "User name of the interface"), // must be set befor start ... propertyRouterIp(this, "router-ip", "127.0.0.1", "Ip to listen client", &appl::GateWay::onPropertyChangeClientIp), propertyRouterPort(this, "router-port", 1984, "Port to listen client", &appl::GateWay::onPropertyChangeClientPort), 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) { + propertyServiceMax(this, "service-max", 0x7FFF, "Maximum of client at the same time", &appl::GateWay::onPropertyChangeServiceMax) { m_interfaceNewService = ememory::makeShared(this); } @@ -90,7 +93,7 @@ void appl::GateWay::stop() { m_routerClient.reset(); } - +/* ememory::SharedPtr appl::GateWay::get(const std::string& _serviceName) { for (auto &it : m_serviceList) { if (it == nullptr) { @@ -103,40 +106,51 @@ ememory::SharedPtr appl::GateWay::get(const std::string& } return nullptr; } +*/ std::vector appl::GateWay::getAllServiceName() { std::vector out; + // TODO : Change this it is old and deprecated ... + /* for (auto &it : m_serviceList) { if (it == nullptr) { continue; } out.push_back(it->getName()); } + */ return out; } -void appl::GateWay::answer(uint64_t _userSessionId, const ememory::SharedPtr& _data) { +void appl::GateWay::send(ememory::SharedPtr _data) { + APPL_TODO("Implement Send to a specific IO ..."); + + + /* if (m_routerClient != nullptr) { m_routerClient->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()) { + /* + auto it = m_listIODirect.begin(); + while (it != m_listIODirect.end()) { if (*it != nullptr) { if ((*it)->isAlive() == false) { - it = m_serviceList.erase(it); + it = m_listIODirect.erase(it); continue; } } else { - it = m_serviceList.erase(it); + it = m_listIODirect.erase(it); continue; } ++it; } + */ if (m_routerClient != nullptr) { m_routerClient->clean(); } diff --git a/tools/gateway/appl/GateWay.hpp b/tools/gateway/appl/GateWay.hpp index 0094bc9..cf84f80 100644 --- a/tools/gateway/appl/GateWay.hpp +++ b/tools/gateway/appl/GateWay.hpp @@ -4,15 +4,17 @@ * @license APACHE v2.0 (see license file) */ #pragma once -#include -#include +#include #include namespace appl { class TcpServerInput; + class DirectInterface; + class RouterInterface; + class IOInterface; class GateWay : public eproperty::Interface { + uint16_t m_idIncrement; private: - std::vector> m_serviceList; //!< List of all service availlable with their specific connection interface ememory::SharedPtr m_routerClient; //!< Interface with the Gateway Front End ememory::SharedPtr m_interfaceNewService; @@ -23,14 +25,18 @@ namespace appl { eproperty::Value propertyServiceIp; eproperty::Value propertyServicePort; eproperty::Value propertyServiceMax; + public: + std::vector> m_listIODirect; //!< List of all service availlable with their specific connection interface + std::vector> m_listIO; + public: GateWay(); virtual ~GateWay(); void start(); void stop(); - ememory::SharedPtr get(const std::string& _serviceName); + //ememory::SharedPtr get(const std::string& _serviceName); std::vector getAllServiceName(); - void answer(uint64_t _userSessionId, const ememory::SharedPtr& _data); + void send(ememory::SharedPtr _data); void newService(enet::Tcp _connection); void cleanIO(); private: diff --git a/tools/gateway/appl/IOInterface.cpp b/tools/gateway/appl/IOInterface.cpp new file mode 100644 index 0000000..cebc83d --- /dev/null +++ b/tools/gateway/appl/IOInterface.cpp @@ -0,0 +1,269 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2016, Edouard DUPIN, all right reserved + * @license APACHE v2.0 (see license file) + */ + +#include +#include +#include +#include +#include + + +#include + +static const std::string protocolError = "PROTOCOL-ERROR"; + +appl::IOInterface::IOInterface() { + m_uid = 0; + m_state = appl::clientState::unconnect; + APPL_INFO("------------"); + APPL_INFO("-- NEW IO --"); + APPL_INFO("------------"); +} + +appl::IOInterface::~IOInterface() { + APPL_INFO("---------------"); + APPL_INFO("-- DELETE IO --"); + APPL_INFO("---------------"); +} + +void appl::IOInterface::answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp) { + zeus::WebServer* iface = getInterface(); + iface->answerError(_transactionId, 0, ZEUS_ID_SERVICE_ROOT, protocolError, _errorHelp); + //m_interfaceRouterClient->sendCtrl(m_routeurUID, ZEUS_ID_SERVICE_ROOT, "DISCONNECT"); + APPL_TODO("Do this error return ... " << _errorHelp); + m_state = appl::clientState::disconnect; +} + +bool appl::IOInterface::start(appl::GateWay* _gateway, uint16_t _id) { + m_gateway = _gateway; + m_uid = _id; + m_state = appl::clientState::connect; + //m_interfaceRouterClient->setInterfaceName("cli-" + etk::to_string(m_uid)); + APPL_WARNING("[" << m_uid << "] New IO interface"); + return true; +} + + +void appl::IOInterface::receive(ememory::SharedPtr _value) { + if (_value == nullptr) { + return; + } + //APPL_ERROR(" ==> parse DATA ..."); + uint32_t transactionId = _value->getTransactionId(); + if (transactionId == 0) { + APPL_ERROR("Protocol error ==>missing id"); + answerProtocolError(transactionId, "missing parameter: 'id'"); + return; + } + // Check if we are the destinated Of this message + if ( _value->getDestinationId() == ZEUS_ID_GATEWAY + && _value->getDestinationObjectId() == ZEUS_ID_GATEWAY_OBJECT) { + if (_value->getType() != zeus::Buffer::typeMessage::call) { + APPL_ERROR("Protocol error ==>missing 'call'"); + answerProtocolError(transactionId, "missing parameter: 'call' / wrong type 'call'"); + return; + } + ememory::SharedPtr callObj = ememory::staticPointerCast(_value); + std::string callFunction = callObj->getCall(); + switch (m_state) { + case appl::clientState::disconnect: + case appl::clientState::unconnect: + { + APPL_ERROR("Must never appear"); + answerProtocolError(transactionId, "Gateway internal error"); + return; + } + case appl::clientState::connect: + { + /* + m_clientServices.clear(); + m_clientgroups.clear(); + m_clientName.clear(); + */ + if ( callFunction != "identify" + && callFunction != "auth" + && callFunction != "anonymous") { + answerProtocolError(transactionId, "Client must call: identify/auth/anonymous"); + return; + } + #if 0 + if (callFunction == "identify") { + std::string clientName = callObj->getParameter(0); + std::string clientTocken = callObj->getParameter(1); + if (m_userService == nullptr) { + answerProtocolError(transactionId, "gateWay internal error 3"); + return; + } + + zeus::Future fut = m_userService->m_interfaceClient.call(m_localIdUser, ZEUS_ID_SERVICE_ROOT, "checkTocken", clientName, clientTocken); + fut.wait(); // TODO: Set timeout ... + if (fut.hasError() == true) { + APPL_ERROR("Get error from the service ..."); + m_interfaceRouterClient->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), false); + answerProtocolError(transactionId, "connection refused 1"); + return; + } else if (fut.get() == false) { + m_interfaceRouterClient->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), false); + answerProtocolError(transactionId, "connection refused 2"); + return; + } + m_clientName = clientName; + } + if (callFunction == "auth") { + std::string password = callObj->getParameter(0); + zeus::Future fut = m_userService->m_interfaceClient.call(m_localIdUser, ZEUS_ID_SERVICE_ROOT, "checkAuth", password); + fut.wait(); // TODO: Set timeout ... + if (fut.hasError() == true) { + APPL_ERROR("Get error from the service ..."); + m_interfaceRouterClient->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), false); + answerProtocolError(transactionId, "connection refused 1"); + return; + } else if (fut.get() == false) { + m_interfaceRouterClient->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), false); + answerProtocolError(transactionId, "connection refused 2"); + return; + } + m_clientName = m_userConnectionName; + } + if (callFunction == "anonymous") { + m_clientName = ""; + } + #endif + #if 0 + // -------------------------------- + // -- Get groups: + // -------------------------------- + zeus::Future> futGroup = m_userService->m_interfaceClient.call(m_localIdUser, ZEUS_ID_SERVICE_ROOT, "clientGroupsGet", m_clientName); + futGroup.wait(); // TODO: Set timeout ... + if (futGroup.hasError() == true) { + APPL_ERROR("Get error from the service ..."); + m_interfaceRouterClient->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), false); + answerProtocolError(transactionId, "grouping error"); + return; + } + m_clientgroups = futGroup.get(); + // -------------------------------- + // -- Get services: + // -------------------------------- + std::vector currentServices = m_gatewayInterface->getAllServiceName(); + zeus::Future> futServices = m_userService->m_interfaceClient.call(m_localIdUser, ZEUS_ID_SERVICE_ROOT, "filterClientServices", m_clientName, currentServices); + futServices.wait(); // TODO: Set timeout ... + if (futServices.hasError() == true) { + APPL_ERROR("Get error from the service ..."); + m_interfaceRouterClient->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), false); + answerProtocolError(transactionId, "service filtering error"); + return; + } + m_clientServices = futServices.get(); + APPL_WARNING("Connection of: '" << m_clientName << "' to '" << m_userConnectionName << "'"); + APPL_WARNING(" groups: " << etk::to_string(m_clientgroups)); + APPL_WARNING(" services: " << etk::to_string(m_clientServices)); + #endif + zeus::WebServer* iface = getInterface(); + iface->answerValue(transactionId, _value->getDestination(), _value->getSource(), true); + m_state = appl::clientState::clientIdentify; + return; + } + break; + case appl::clientState::clientIdentify: + { + uint32_t serviceId = callObj->getSourceId(); + + if (serviceId == 0) { + // This is 2 default service for the cient interface that manage the authorisation of view: + if (callFunction == "getServiceCount") { + // TODO : m_interfaceRouterClient->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), m_clientServices.size()); + + return; + } + if (callFunction == "getServiceList") { + // TODO : m_interfaceRouterClient->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), m_clientServices); + //"ServiceManager/v0.1.0" + return; + } + if (callFunction == "link") { + // first param: + std::string serviceName = callObj->getParameter(0); + ZEUS_ERROR("Connect to service : " << serviceName << " " << m_uid); + // Check if service already link: + /* + auto it = m_listConnectedService.begin(); + while (it != m_listConnectedService.end()) { + if (*it == nullptr) { + ++it; + continue; + } + if ((*it)->getName() != serviceName) { + ++it; + continue; + } + break; + } + if (it == m_listConnectedService.end()) { + // check if service is connectable ... + if (std::find(m_clientServices.begin(), m_clientServices.end(), serviceName) == m_clientServices.end()) { + m_interfaceRouterClient->answerError(transactionId, _value->getClientId(), _value->getServiceId(), "UN-AUTHORIZED-SERVICE"); + return; + } + ememory::SharedPtr srv = m_gatewayInterface->get(serviceName); + if (srv != nullptr) { + zeus::Future futLink = srv->m_interfaceClient.call(m_uid, ZEUS_ID_SERVICE_ROOT, "_new", m_userConnectionName, m_clientName, m_clientgroups); + futLink.wait(); // TODO: Set timeout ... + if (futLink.hasError() == true) { + APPL_ERROR("Get error from the service ... LINK"); + m_interfaceRouterClient->answerError(transactionId, _value->getClientId(), _value->getServiceId(), "ERROR-CREATE-SERVICE-INSTANCE"); + return; + } + m_listConnectedService.push_back(srv); + ZEUS_ERROR(" ==> get ID : " << m_uid); + m_interfaceRouterClient->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), m_listConnectedService.size()); + return; + } + m_interfaceRouterClient->answerError(transactionId, _value->getClientId(), _value->getServiceId(), "CAN-NOT-CONNECT-SERVICE"); + return; + } + m_interfaceRouterClient->answerError(transactionId, _value->getClientId(), _value->getServiceId(), "SERVICE-ALREADY-CONNECTED");; + return; + */ + } + if (callFunction == "unlink") { + ZEUS_ERROR("Disconnnect from service : " << m_uid); + // first param: the service we want to unconnect ... + /* + int64_t localServiceID = callObj->getParameter(0)-1; + // Check if service already link: + if (localServiceID >= m_listConnectedService.size()) { + m_interfaceRouterClient->answerError(transactionId, _value->getClientId(), _value->getServiceId(), "NOT-CONNECTED-SERVICE"); + return; + } + zeus::Future futUnLink = m_listConnectedService[localServiceID]->m_interfaceClient.call(m_uid, ZEUS_ID_SERVICE_ROOT, "_delete"); + futUnLink.wait(); // TODO: Set timeout ... + if (futUnLink.hasError() == true) { + APPL_ERROR("Get error from the service ... UNLINK"); + m_interfaceRouterClient->answerError(transactionId, _value->getClientId(), _value->getServiceId(), "ERROR-CREATE-SERVICE-INSTANCE"); + return; + } + m_listConnectedService[localServiceID] = nullptr; + m_interfaceRouterClient->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), true); + return; + */ + } + APPL_ERROR("Function does not exist ... '" << callFunction << "'"); + zeus::WebServer* iface = getInterface(); + iface->answerError(transactionId, _value->getDestination(), _value->getSource(), "CALL-UNEXISTING"); + return; + } + } + return; + } + } + if (m_gateway != nullptr) { + m_gateway->send(_value); + } +} + + + diff --git a/tools/gateway/appl/IOInterface.hpp b/tools/gateway/appl/IOInterface.hpp new file mode 100644 index 0000000..d6c426e --- /dev/null +++ b/tools/gateway/appl/IOInterface.hpp @@ -0,0 +1,41 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2016, Edouard DUPIN, all right reserved + * @license APACHE v2.0 (see license file) + */ +#pragma once + +#include +#include + +namespace appl { + class GateWay; + 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 IOInterface { + public: + appl::GateWay* m_gateway; + protected: + uint16_t m_uid; //!< Client unique ID (for routing) + public: + enum clientState m_state; // state machine ... + IOInterface(); + virtual ~IOInterface(); + bool start(appl::GateWay* _gateway, uint16_t _id); + // Data arrive from the IO + virtual void receive(ememory::SharedPtr _value); + // Data must be send to the IO + virtual void send(ememory::SharedPtr _data) = 0; + // Verify wich ID is provided by the IO + bool checkId(uint16_t _id) const { + return m_uid == _id; + } + void answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp); + virtual zeus::WebServer* getInterface() = 0; + }; +} + diff --git a/tools/gateway/appl/RouterInterface.cpp b/tools/gateway/appl/RouterInterface.cpp index 7295156..4619168 100644 --- a/tools/gateway/appl/RouterInterface.cpp +++ b/tools/gateway/appl/RouterInterface.cpp @@ -15,61 +15,39 @@ static const std::string protocolError = "PROTOCOL-ERROR"; -appl::userSpecificInterface::userSpecificInterface(const std::string& _userName) { - m_routeurUID = 0; +appl::clientSpecificInterface::clientSpecificInterface() { m_uid = 0; - m_localIdUser = 0; - m_userConnectionName = _userName; m_state = appl::clientState::unconnect; APPL_INFO("----------------"); APPL_INFO("-- NEW Client --"); APPL_INFO("----------------"); } -appl::userSpecificInterface::~userSpecificInterface() { +appl::clientSpecificInterface::~clientSpecificInterface() { APPL_INFO("-------------------"); APPL_INFO("-- DELETE Client --"); APPL_INFO("-------------------"); } - -void appl::userSpecificInterface::answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp) { - m_interfaceRouterClient->answerError(_transactionId, m_routeurUID, ZEUS_ID_SERVICE_ROOT, protocolError, _errorHelp); - m_interfaceRouterClient->sendCtrl(m_routeurUID, ZEUS_ID_SERVICE_ROOT, "DISCONNECT"); +/* +void appl::clientSpecificInterface::answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp) { + //m_interfaceWeb->answerError(_transactionId, m_routeurUID, ZEUS_ID_SERVICE_ROOT, protocolError, _errorHelp); + //m_interfaceWeb->sendCtrl(m_routeurUID, ZEUS_ID_SERVICE_ROOT, "DISCONNECT"); m_state = appl::clientState::disconnect; } - -bool appl::userSpecificInterface::start(uint32_t _transactionId, appl::GateWay* _gatewayInterface, zeus::WebServer* _interfaceGateWayClient, uint64_t _routerId, uint64_t _id) { - m_interfaceRouterClient = _interfaceGateWayClient; - m_gatewayInterface = _gatewayInterface; - m_routeurUID = _routerId; - m_uid = _id; - m_localIdUser = _id+1; - m_state = appl::clientState::connect; - //m_interfaceRouterClient->setInterfaceName("cli-" + etk::to_string(m_uid)); - +*/ +bool appl::clientSpecificInterface::start(appl::GateWay* _gateway, zeus::WebServer* _interfaceWeb, uint16_t _id) { + appl::IOInterface::start(_gateway, _id); + m_interfaceWeb = _interfaceWeb; APPL_WARNING("[" << m_uid << "] New client : " << m_clientName); - - m_userService = m_gatewayInterface->get("user"); - if (m_userService == nullptr) { - APPL_ERROR("missing service 'user'"); - answerProtocolError(_transactionId, "Gateway internal error 'No user interface'"); - return false; - } - zeus::Future futLocalService = m_userService->m_interfaceClient.call(m_localIdUser, ZEUS_ID_SERVICE_ROOT, "_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; - } return true; } - -void appl::userSpecificInterface::returnMessage(ememory::SharedPtr _data) { - APPL_ERROR("Get call from the Service to the user ..."); +void appl::clientSpecificInterface::send(ememory::SharedPtr _value) { + m_interfaceWeb->writeBinary(_value); } -void appl::userSpecificInterface::onClientData(ememory::SharedPtr _value) { +#if 0 +void appl::clientSpecificInterface::receive(ememory::SharedPtr _value) { if (_value == nullptr) { return; } @@ -93,7 +71,7 @@ void appl::userSpecificInterface::onClientData(ememory::SharedPtr } serviceId--; if (serviceId >= m_listConnectedService.size()) { - m_interfaceRouterClient->answerError(transactionId, _value->getClientId(), _value->getServiceId(), "NOT-CONNECTED-SERVICE"); + m_interfaceWeb->answerError(transactionId, _value->getClientId(), _value->getServiceId(), "NOT-CONNECTED-SERVICE"); return; } if (m_listConnectedService[serviceId] == nullptr) { @@ -152,11 +130,11 @@ void appl::userSpecificInterface::onClientData(ememory::SharedPtr fut.wait(); // TODO: Set timeout ... if (fut.hasError() == true) { APPL_ERROR("Get error from the service ..."); - m_interfaceRouterClient->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), false); + m_interfaceWeb->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), false); answerProtocolError(transactionId, "connection refused 1"); return; } else if (fut.get() == false) { - m_interfaceRouterClient->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), false); + m_interfaceWeb->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), false); answerProtocolError(transactionId, "connection refused 2"); return; } @@ -168,11 +146,11 @@ void appl::userSpecificInterface::onClientData(ememory::SharedPtr fut.wait(); // TODO: Set timeout ... if (fut.hasError() == true) { APPL_ERROR("Get error from the service ..."); - m_interfaceRouterClient->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), false); + m_interfaceWeb->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), false); answerProtocolError(transactionId, "connection refused 1"); return; } else if (fut.get() == false) { - m_interfaceRouterClient->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), false); + m_interfaceWeb->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), false); answerProtocolError(transactionId, "connection refused 2"); return; } @@ -188,7 +166,7 @@ void appl::userSpecificInterface::onClientData(ememory::SharedPtr futGroup.wait(); // TODO: Set timeout ... if (futGroup.hasError() == true) { APPL_ERROR("Get error from the service ..."); - m_interfaceRouterClient->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), false); + m_interfaceWeb->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), false); answerProtocolError(transactionId, "grouping error"); return; } @@ -201,7 +179,7 @@ void appl::userSpecificInterface::onClientData(ememory::SharedPtr futServices.wait(); // TODO: Set timeout ... if (futServices.hasError() == true) { APPL_ERROR("Get error from the service ..."); - m_interfaceRouterClient->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), false); + m_interfaceWeb->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), false); answerProtocolError(transactionId, "service filtering error"); return; } @@ -211,7 +189,7 @@ void appl::userSpecificInterface::onClientData(ememory::SharedPtr APPL_WARNING(" services: " << etk::to_string(m_clientServices)); - m_interfaceRouterClient->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), true); + m_interfaceWeb->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), true); m_state = appl::clientState::clientIdentify; return; } @@ -223,11 +201,11 @@ void appl::userSpecificInterface::onClientData(ememory::SharedPtr if (serviceId == 0) { // This is 2 default service for the cient interface that manage the authorisation of view: if (callFunction == "getServiceCount") { - m_interfaceRouterClient->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), m_clientServices.size()); + m_interfaceWeb->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), m_clientServices.size()); return; } if (callFunction == "getServiceList") { - m_interfaceRouterClient->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), m_clientServices); + m_interfaceWeb->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), m_clientServices); //"ServiceManager/v0.1.0" return; } @@ -251,7 +229,7 @@ void appl::userSpecificInterface::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_interfaceRouterClient->answerError(transactionId, _value->getClientId(), _value->getServiceId(), "UN-AUTHORIZED-SERVICE"); + m_interfaceWeb->answerError(transactionId, _value->getClientId(), _value->getServiceId(), "UN-AUTHORIZED-SERVICE"); return; } ememory::SharedPtr srv = m_gatewayInterface->get(serviceName); @@ -260,18 +238,18 @@ void appl::userSpecificInterface::onClientData(ememory::SharedPtr futLink.wait(); // TODO: Set timeout ... if (futLink.hasError() == true) { APPL_ERROR("Get error from the service ... LINK"); - m_interfaceRouterClient->answerError(transactionId, _value->getClientId(), _value->getServiceId(), "ERROR-CREATE-SERVICE-INSTANCE"); + m_interfaceWeb->answerError(transactionId, _value->getClientId(), _value->getServiceId(), "ERROR-CREATE-SERVICE-INSTANCE"); return; } m_listConnectedService.push_back(srv); ZEUS_ERROR(" ==> get ID : " << m_uid); - m_interfaceRouterClient->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), m_listConnectedService.size()); + m_interfaceWeb->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), m_listConnectedService.size()); return; } - m_interfaceRouterClient->answerError(transactionId, _value->getClientId(), _value->getServiceId(), "CAN-NOT-CONNECT-SERVICE"); + m_interfaceWeb->answerError(transactionId, _value->getClientId(), _value->getServiceId(), "CAN-NOT-CONNECT-SERVICE"); return; } - m_interfaceRouterClient->answerError(transactionId, _value->getClientId(), _value->getServiceId(), "SERVICE-ALREADY-CONNECTED");; + m_interfaceWeb->answerError(transactionId, _value->getClientId(), _value->getServiceId(), "SERVICE-ALREADY-CONNECTED");; return; } if (callFunction == "unlink") { @@ -280,28 +258,28 @@ void appl::userSpecificInterface::onClientData(ememory::SharedPtr int64_t localServiceID = callObj->getParameter(0)-1; // Check if service already link: if (localServiceID >= m_listConnectedService.size()) { - m_interfaceRouterClient->answerError(transactionId, _value->getClientId(), _value->getServiceId(), "NOT-CONNECTED-SERVICE"); + m_interfaceWeb->answerError(transactionId, _value->getClientId(), _value->getServiceId(), "NOT-CONNECTED-SERVICE"); return; } zeus::Future futUnLink = m_listConnectedService[localServiceID]->m_interfaceClient.call(m_uid, ZEUS_ID_SERVICE_ROOT, "_delete"); futUnLink.wait(); // TODO: Set timeout ... if (futUnLink.hasError() == true) { APPL_ERROR("Get error from the service ... UNLINK"); - m_interfaceRouterClient->answerError(transactionId, _value->getClientId(), _value->getServiceId(), "ERROR-CREATE-SERVICE-INSTANCE"); + m_interfaceWeb->answerError(transactionId, _value->getClientId(), _value->getServiceId(), "ERROR-CREATE-SERVICE-INSTANCE"); return; } m_listConnectedService[localServiceID] = nullptr; - m_interfaceRouterClient->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), true); + m_interfaceWeb->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), true); return; } APPL_ERROR("Function does not exist ... '" << callFunction << "'"); - m_interfaceRouterClient->answerError(transactionId, _value->getClientId(), _value->getServiceId(), "CALL-UNEXISTING"); + m_interfaceWeb->answerError(transactionId, _value->getClientId(), _value->getServiceId(), "CALL-UNEXISTING"); return; } // decrease service ID ... serviceId -= 1; if (serviceId >= m_listConnectedService.size()) { - m_interfaceRouterClient->answerError(transactionId, _value->getClientId(), _value->getServiceId(), "NOT-CONNECTED-SERVICE"); + m_interfaceWeb->answerError(transactionId, _value->getClientId(), _value->getServiceId(), "NOT-CONNECTED-SERVICE"); return; } else { if (m_listConnectedService[serviceId] == nullptr) { @@ -321,7 +299,7 @@ void appl::userSpecificInterface::onClientData(ememory::SharedPtr tmpp->setClientId(m_routeurUID); tmpp->setServiceId(serviceId+1); APPL_DEBUG("transmit=" << tmpp); - m_interfaceRouterClient->writeBinary(tmpp); + m_interfaceWeb->writeBinary(tmpp); // multiple send element ... return tmpp->getPartFinish(); }); @@ -329,15 +307,13 @@ void appl::userSpecificInterface::onClientData(ememory::SharedPtr } } } +#endif - - -appl::RouterInterface::RouterInterface(const std::string& _ip, uint16_t _port, const std::string& _userName, appl::GateWay* _gatewayInterface) : - m_clientUID(1), +appl::RouterInterface::RouterInterface(const std::string& _ip, uint16_t _port, std::string _userName, appl::GateWay* _gateway) : m_state(appl::clientState::unconnect), - m_gatewayInterface(_gatewayInterface), - m_interfaceRouterClient() { + m_gateway(_gateway), + m_interfaceWeb() { APPL_INFO("----------------------------------------"); APPL_INFO("-- NEW Connection to GateWay Font-end --"); APPL_INFO("----------------------------------------"); @@ -346,12 +322,10 @@ appl::RouterInterface::RouterInterface(const std::string& _ip, uint16_t _port, c APPL_ERROR("Can not connect the GateWay-front-end"); return; } - m_interfaceRouterClient.setInterface(std::move(connection), false, _userName); - m_userConnectionName = _userName; - m_state = appl::clientState::connect; - m_interfaceRouterClient.connect(this, &appl::RouterInterface::onClientData); - m_interfaceRouterClient.connect(true); - m_interfaceRouterClient.setInterfaceName("cli-GateWay-front-end"); + m_interfaceWeb.setInterface(std::move(connection), false, _userName); + m_interfaceWeb.connect(this, &appl::RouterInterface::onClientData); + m_interfaceWeb.connect(true); + m_interfaceWeb.setInterfaceName("cli-GateWay-front-end"); // TODO : Check if user name is accepted ... } @@ -377,11 +351,11 @@ void appl::RouterInterface::stop() { } m_listConnectedService.clear(); */ - m_interfaceRouterClient.disconnect(); + m_interfaceWeb.disconnect(); } bool appl::RouterInterface::isAlive() { - return m_interfaceRouterClient.isActive(); + return m_interfaceWeb.isActive(); } @@ -391,42 +365,32 @@ void appl::RouterInterface::onClientData(ememory::SharedPtr _value return; } // Get client ID: - uint64_t clientId = _value->getClientId(); + uint16_t sourceId = _value->getSourceId(); //APPL_ERROR("[" << clientId << "] get message from front-end gateWay: " << _value); - int64_t localId = -1; - for (size_t iii=0; iiigetTransactionId(), m_gatewayInterface, &m_interfaceRouterClient, clientId, m_clientUID); - m_clientUID += 2; //use 2 slot of Connection for gateway get filtering ... - if (ret == false) { + for (auto &it : m_listClients) { + if (it->checkId(sourceId) == true) { + it->receive(_value); return; } } - m_listUser[localId].onClientData(std::move(_value)); -} - -void appl::RouterInterface::answer(uint64_t _userSessionId, const ememory::SharedPtr& _data) { - for (auto &it : m_listUser) { - if (it.checkId(_userSessionId) == false) { - continue; - } - it.returnMessage(_data); + m_listClients.push_back(ememory::makeShared()); + size_t localId = m_listClients.size()-1; + bool ret = m_listClients[localId]->start(m_gateway, &m_interfaceWeb, sourceId); + if (ret == false) { return; } + m_listClients[localId]->receive(_value); +} + +void appl::RouterInterface::send(const ememory::SharedPtr& _data) { + m_interfaceWeb.writeBinary(_data); } void appl::RouterInterface::clean() { - auto it = m_listUser.begin(); - while (it != m_listUser.end()) { - if (it->m_state == appl::clientState::disconnect) { - it = m_listUser.erase(it); + auto it = m_listClients.begin(); + while (it != m_listClients.end()) { + if ((*it)->m_state == appl::clientState::disconnect) { + it = m_listClients.erase(it); continue; } ++it; diff --git a/tools/gateway/appl/RouterInterface.hpp b/tools/gateway/appl/RouterInterface.hpp index c73b736..879615c 100644 --- a/tools/gateway/appl/RouterInterface.hpp +++ b/tools/gateway/appl/RouterInterface.hpp @@ -7,63 +7,40 @@ #include #include -#include +#include namespace appl { class GateWay; - 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 { + class clientSpecificInterface : public appl::IOInterface { public: - zeus::WebServer* m_interfaceRouterClient; - appl::GateWay* m_gatewayInterface; - uint64_t m_routeurUID; - private: - uint64_t m_uid; - uint64_t m_localIdUser; + zeus::WebServer* m_interfaceWeb; public: - 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; - userSpecificInterface(const std::string& _userName); - ~userSpecificInterface(); - bool start(uint32_t _transactionId, appl::GateWay* _gatewayInterface, zeus::WebServer* _interfaceGateWayClient, uint64_t _routerId, uint64_t _id); - void onClientData(ememory::SharedPtr _value); - void returnMessage(ememory::SharedPtr _data); - bool checkId(uint64_t _id) const { - return m_uid == _id - || m_localIdUser == _id; + clientSpecificInterface(); + ~clientSpecificInterface(); + bool start(appl::GateWay* _gateway, zeus::WebServer* _interfaceWeb, uint16_t _id); + void send(ememory::SharedPtr _data); + //void answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp); + zeus::WebServer* getInterface() { + return m_interfaceWeb; } - void answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp); }; + class RouterInterface { - private: - uint32_t m_clientUID; private: enum clientState m_state; // state machine .. - std::vector m_listUser; + std::vector> m_listClients; private: - appl::GateWay* m_gatewayInterface; - zeus::WebServer m_interfaceRouterClient; - std::string m_userConnectionName; + appl::GateWay* m_gateway; + zeus::WebServer m_interfaceWeb; public: - RouterInterface(const std::string& _ip, uint16_t _port, const std::string& _userName, appl::GateWay* _gatewayInterface); + RouterInterface(const std::string& _ip, uint16_t _port, std::string _userName, appl::GateWay* _gateway); virtual ~RouterInterface(); void stop(); void onClientData(ememory::SharedPtr _value); bool isAlive(); - void answer(uint64_t _userSessionId, const ememory::SharedPtr& _data); + void send(const ememory::SharedPtr& _data); void clean(); - - }; } diff --git a/tools/gateway/appl/ServiceInterface.hpp b/tools/gateway/appl/ServiceInterface.hpp index 1434aaa..d4b588a 100644 --- a/tools/gateway/appl/ServiceInterface.hpp +++ b/tools/gateway/appl/ServiceInterface.hpp @@ -7,7 +7,7 @@ #include #include - +#error remove ... namespace appl { class GateWay; class RouterInterface; diff --git a/tools/gateway/lutin_zeus-gateway.py b/tools/gateway/lutin_zeus-gateway.py index 2d80ec3..f30c890 100644 --- a/tools/gateway/lutin_zeus-gateway.py +++ b/tools/gateway/lutin_zeus-gateway.py @@ -29,8 +29,10 @@ def configure(target, my_module): my_module.add_depend(['zeus']) my_module.add_src_file([ 'appl/debug.cpp', + 'appl/IOInterface.cpp', 'appl/RouterInterface.cpp', - 'appl/ServiceInterface.cpp', + #'appl/ServiceInterface.cpp', + 'appl/DirectInterface.cpp', 'appl/GateWay.cpp', 'appl/main.cpp' ]) diff --git a/tools/launcher/appl/main.cpp b/tools/launcher/appl/main.cpp index b8b9e84..590e88f 100644 --- a/tools/launcher/appl/main.cpp +++ b/tools/launcher/appl/main.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include typedef bool (*SERVICE_IO_init_t)(int _argc, const char *_argv[], std::string _basePath); @@ -29,6 +30,7 @@ class PlugginAccess { SERVICE_IO_init_t m_SERVICE_IO_init; SERVICE_IO_uninit_t m_SERVICE_IO_uninit; SERVICE_IO_instanciate_t m_SERVICE_IO_instanciate; + zeus::Client m_client; zeus::Service* m_srv; public: PlugginAccess(const std::string& _name) : @@ -96,19 +98,20 @@ class PlugginAccess { return m_srv != nullptr; } bool connect(std::string _ip, uint16_t _port) { + if (_ip != "") { + m_client.propertyIp.set(_ip); + } + if (_port != 0) { + m_client.propertyPort.set(_port); + } + if (m_client.connect() == false) { + return false; + } + if (m_srv == nullptr) { return false; } - if (_ip != "") { - m_srv->propertyIp.set(_ip); - } - if (_port != 0) { - m_srv->propertyPort.set(_port); - } - if (m_srv->connect() == false) { - return false; - } - if (m_srv->GateWayAlive() == false) { + if (m_client.isAlive() == false) { APPL_INFO("==========================================================="); APPL_INFO("== ZEUS service: " << *m_srv->propertyNameService << " [STOP] Can not connect to the GateWay"); APPL_INFO("==========================================================="); @@ -122,16 +125,17 @@ class PlugginAccess { if (m_srv == nullptr) { return false; } - if (m_srv->GateWayAlive() == true) { - m_srv->pingIsAlive(); + if (m_client.isAlive() == true) { + m_client.pingIsAlive(); } - return m_srv->GateWayAlive(); + return m_client.isAlive(); } bool disconnect() { + m_client.disconnect(); + if (m_srv == nullptr) { return false; } - m_srv->disconnect(); APPL_INFO("==========================================================="); APPL_INFO("== ZEUS service: " << *m_srv->propertyNameService << " [STOP] GateWay Stop"); APPL_INFO("==========================================================="); diff --git a/tools/router/appl/ClientInterface.cpp b/tools/router/appl/ClientInterface.cpp index 4e14c6c..a17a703 100644 --- a/tools/router/appl/ClientInterface.cpp +++ b/tools/router/appl/ClientInterface.cpp @@ -17,7 +17,6 @@ static const std::string protocolError = "PROTOCOL-ERROR"; appl::ClientInterface::ClientInterface(enet::Tcp _connection, appl::Router* _routerInterface) : - m_state(appl::ClientInterface::state::unconnect), m_routerInterface(_routerInterface), m_interfaceClient(std::move(_connection), true) { APPL_INFO("----------------"); @@ -49,21 +48,19 @@ bool appl::ClientInterface::requestURI(const std::string& _uri) { } // TODO : Remove subParameters xxx?YYY m_userGateWay = m_routerInterface->get(tmpURI); + APPL_INFO("Connect on client done : '" << tmpURI << "'"); if (m_userGateWay == nullptr) { APPL_ERROR("Can not connect on Client ==> it does not exist ..."); return false; } - APPL_INFO("Connect on client done : '" << tmpURI << "'"); return true; } -void appl::ClientInterface::start(uint64_t _uid) { - m_uid = _uid; - m_state = appl::ClientInterface::state::connect; +void appl::ClientInterface::start() { m_interfaceClient.connect(this, &appl::ClientInterface::onClientData); m_interfaceClient.connectUri(this, &appl::ClientInterface::requestURI); m_interfaceClient.connect(true); - m_interfaceClient.setInterfaceName("cli-" + etk::to_string(m_uid)); + m_interfaceClient.setInterfaceName("cli-"); } void appl::ClientInterface::stop() { @@ -78,7 +75,6 @@ bool appl::ClientInterface::isAlive() { void appl::ClientInterface::answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp) { m_interfaceClient.answerError(_transactionId, 0, 0, protocolError, _errorHelp); - m_state = appl::ClientInterface::state::disconnect; m_interfaceClient.disconnect(true); } @@ -87,60 +83,59 @@ void appl::ClientInterface::onClientData(ememory::SharedPtr _value if (_value == nullptr) { return; } - //APPL_ERROR("receive data : " << _value); + // check transaction ID != 0 uint32_t transactionId = _value->getTransactionId(); if (transactionId == 0) { APPL_ERROR("Protocol error ==>missing id"); answerProtocolError(transactionId, "missing parameter: 'id'"); return; } - if (_value->getClientId() != 0) { - APPL_ERROR("Protocol error ==> client ID != 0"); - answerProtocolError(transactionId, "clent ID is != 0"); + // check correct SourceID + if (_value->getSourceId() != m_uid) { + answerProtocolError(transactionId, "message with the wrong source ID"); return; } - // Directly send to the user-GateWay + // Check gateway corectly connected if (m_userGateWay == nullptr) { - APPL_ERROR("USER is not existing ..."); answerProtocolError(transactionId, "GateWay error"); - // TODO : Need to kill socket ... return; } - // Special case for data, they are transiting messages ... - if (_value->getType() != zeus::Buffer::typeMessage::data) { - auto fut = m_userGateWay->m_interfaceClient.callForward(m_uid, _value, (uint64_t(m_uid) << 32) + uint64_t(transactionId)); - fut.andAll([=](zeus::FutureBase _ret) { - ememory::SharedPtr tmpp = _ret.getRaw(); - if (tmpp == nullptr) { - return true; - } - APPL_DEBUG(" ==> transmit : " << tmpp->getTransactionId() << " -> " << transactionId); - APPL_DEBUG(" msg=" << tmpp); - tmpp->setTransactionId(transactionId); - tmpp->setClientId(0); - APPL_DEBUG("transmit=" << tmpp); - m_interfaceClient.writeBinary(tmpp); - // multiple send element ... - return tmpp->getPartFinish(); - }); + // TODO: Special hook for the first call that we need to get the curretn ID of the connection, think to set this at an other position ... + if (m_uid == 0) { + APPL_INFO("special case, we need to get the ID Of the client:"); + if (_value->getType() != zeus::Buffer::typeMessage::call) { + answerProtocolError(transactionId, "Must get first the Client ID... call 'getAddress'"); + return; + } + ememory::SharedPtr callObj = ememory::staticPointerCast(_value); + if (callObj->getCall() != "getAddress") { + answerProtocolError(transactionId, "Must get first the Client ID... call 'getAddress' and not '" + callObj->getCall() + "'"); + return; + } + APPL_INFO("Get the unique ID..."); + m_uid = m_userGateWay->addClient(sharedFromThis()); + APPL_INFO("get ID : " << m_uid); + if (m_uid == 0) { + answerProtocolError(transactionId, "Can not get the Client ID..."); + return; + } + m_interfaceClient.setInterfaceName("cli-" + etk::to_string(m_uid)); + m_interfaceClient.answerValue(transactionId, _value->getDestination(), _value->getSource(), m_uid); } else { - // simply forward messages to the user gateWay ... - m_userGateWay->m_interfaceClient.callForwardMultiple( - m_uid, - _value, - (uint64_t(m_uid) << 32) + uint64_t(transactionId)); - // TODO : Check errors ... + // send data to the gateway + m_userGateWay->send(_value); } } -void appl::ClientInterface::returnMessage(ememory::SharedPtr _data) { +void appl::ClientInterface::send(ememory::SharedPtr _data) { if (_data == nullptr) { return; } + m_interfaceClient.writeBinary(_data); + /* 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; } @@ -148,5 +143,6 @@ void appl::ClientInterface::returnMessage(ememory::SharedPtr _data return; } APPL_ERROR("Get call from the Service to the user ... " << _data); + */ } diff --git a/tools/router/appl/ClientInterface.hpp b/tools/router/appl/ClientInterface.hpp index 5ba58e0..9291202 100644 --- a/tools/router/appl/ClientInterface.hpp +++ b/tools/router/appl/ClientInterface.hpp @@ -8,32 +8,27 @@ #include #include #include +#include namespace appl { class Router; - class ClientInterface { - private: - enum class state { - unconnect, // starting sate - connect, // zeust get a TCP connection - disconnect // client is dead or loal disconnection - }; - enum state m_state; // state machine ... + class GateWayInterface; + class ClientInterface : public ememory::EnableSharedFromThis { private: appl::Router* m_routerInterface; zeus::WebServer m_interfaceClient; bool requestURI(const std::string& _uri); public: ememory::SharedPtr m_userGateWay; - uint64_t m_uid; //!< gateway unique ID ==> to have an internal routage ... + uint16_t m_uid; //!< gateway unique ID ==> to have an internal routage ... public: ClientInterface(enet::Tcp _connection, appl::Router* _routerInterface); virtual ~ClientInterface(); - void start(uint64_t _uid); + void start(); void stop(); void onClientData(ememory::SharedPtr _value); - void returnMessage(ememory::SharedPtr _data); - bool checkId(uint64_t _id) const { + void send(ememory::SharedPtr _data); + bool checkId(uint16_t _id) const { return m_uid == _id; } bool isAlive(); diff --git a/tools/router/appl/GateWayInterface.cpp b/tools/router/appl/GateWayInterface.cpp index 87bdb52..a208d3f 100644 --- a/tools/router/appl/GateWayInterface.cpp +++ b/tools/router/appl/GateWayInterface.cpp @@ -16,7 +16,8 @@ static const std::string protocolError = "PROTOCOL-ERROR"; appl::GateWayInterface::GateWayInterface(enet::Tcp _connection, appl::Router* _routerInterface) : m_routerInterface(_routerInterface), - m_interfaceClient(std::move(_connection), true) { + m_interfaceClient(std::move(_connection), true), + m_lastSourceID(0x8000) { ZEUS_INFO("--------------------------"); ZEUS_INFO("-- NEW GateWay Back-end --"); ZEUS_INFO("--------------------------"); @@ -64,7 +65,7 @@ void appl::GateWayInterface::start() { m_interfaceClient.connect(this, &appl::GateWayInterface::onServiceData); m_interfaceClient.connectUri(this, &appl::GateWayInterface::requestURI); m_interfaceClient.connect(); - m_interfaceClient.setInterfaceName("srv-?"); + m_interfaceClient.setInterfaceName("GW-?"); } void appl::GateWayInterface::stop() { @@ -72,57 +73,58 @@ void appl::GateWayInterface::stop() { } -void appl::GateWayInterface::SendData(uint64_t _userSessionId, ememory::SharedPtr _data) { - _data->setClientId(_userSessionId); +void appl::GateWayInterface::send(ememory::SharedPtr _data) { m_interfaceClient.writeBinary(_data); } +uint16_t appl::GateWayInterface::addClient(ememory::SharedPtr _value) { + m_clientConnected.push_back(_value); + return m_lastSourceID++; +} + +void appl::GateWayInterface::rmClient(ememory::SharedPtr _value) { + auto it = m_clientConnected.begin(); + while (it != m_clientConnected.end()) { + if (*it == _value) { + it = m_clientConnected.erase(it); + } else { + ++it; + } + } +} + void appl::GateWayInterface::onServiceData(ememory::SharedPtr _value) { if (_value == nullptr) { return; } - uint32_t transactionId = _value->getTransactionId(); - //data.add("from-service", ejson::String(m_name)); - if (_value->getType() == zeus::Buffer::typeMessage::event) { - /* - if (data.valueExist("event") == true) { - // No need to have a user ID ... - if (data["event"].toString().get() == "IS-ALIVE") { - ZEUS_VERBOSE("Service Alive ..."); - if (std::chrono::steady_clock::now() - m_interfaceClient.getLastTimeSend() >= std::chrono::seconds(20)) { - ejson::Object tmpp; - tmpp.add("event", ejson::String("IS-ALIVE")); - m_interfaceClient.writeJson(tmpp); + if (m_name == "") { + uint32_t transactionId = _value->getTransactionId(); + 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 != "") { + ZEUS_WARNING("Service interface ==> try change the servie name after init: '" << callObj->getParameter(0)); + m_interfaceClient.answerValue(transactionId, _value->getDestination(), _value->getSource(), false); + return; } - } else { - ZEUS_INFO("Unknow service event: '" << data["event"].toString().get() << "'"); - } - return; - } - */ - return; - } - 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 != "") { - ZEUS_WARNING("Service interface ==> try change the servie name after init: '" << callObj->getParameter(0)); - m_interfaceClient.answerValue(transactionId, _value->getClientId(), _value->getServiceId(), false); + m_name = callObj->getParameter(0); + m_interfaceClient.setInterfaceName("srv-" + m_name); + m_interfaceClient.answerValue(transactionId, _value->getDestination(), _value->getSource(), true); return; } - m_name = callObj->getParameter(0); - m_interfaceClient.setInterfaceName("srv-" + m_name); - m_interfaceClient.answerValue(transactionId, _value->getClientId(), _value->getServiceId(), true); - return; + answerProtocolError(transactionId, "unknow function"); } - answerProtocolError(transactionId, "unknow function"); - } - if (_value->getClientId() == 0) { - ZEUS_ERROR("Service interface ==> wrong service answer ==> missing 'client-id'"); return; } - m_routerInterface->answer(_value->getClientId(), _value); + uint16_t destinationId = _value->getDestinationId(); + for (auto &it : m_clientConnected) { + if (it->checkId(destinationId) == true) { + it->send(_value); + return; + } + } + m_interfaceClient.answerError(_value->getTransactionId(), _value->getDestination(), _value->getSource(), "UNKNOW-DESTINATION", "the Id=" + etk::to_string(destinationId) + " is unknow"); } diff --git a/tools/router/appl/GateWayInterface.hpp b/tools/router/appl/GateWayInterface.hpp index ce7f523..d2696f3 100644 --- a/tools/router/appl/GateWayInterface.hpp +++ b/tools/router/appl/GateWayInterface.hpp @@ -12,10 +12,11 @@ namespace appl { class Router; class ClientInterface; class GateWayInterface { - friend class appl::ClientInterface; private: appl::Router* m_routerInterface; zeus::WebServer m_interfaceClient; + uint16_t m_lastSourceID; //!< The source dynbamic generated ID is manage in 2 part the value <= 0x7FFF is used by the gateway and the value >= 0x8000 is manage by the router + std::vector> m_clientConnected; std::string m_name; bool requestURI(const std::string& _uri); public: @@ -25,7 +26,9 @@ namespace appl { void stop(); void onServiceData(ememory::SharedPtr _value); public: - void SendData(uint64_t _userSessionId, ememory::SharedPtr _data); + uint16_t addClient(ememory::SharedPtr _value); + void rmClient(ememory::SharedPtr _value); + void send(ememory::SharedPtr _data); const std::string& getName() { return m_name; } diff --git a/tools/router/appl/Router.cpp b/tools/router/appl/Router.cpp index a37edca..81decd8 100644 --- a/tools/router/appl/Router.cpp +++ b/tools/router/appl/Router.cpp @@ -75,8 +75,7 @@ void appl::Router::newClientGateWay(enet::Tcp _connection) { void appl::Router::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_clientList.push_back(tmp); } @@ -135,18 +134,6 @@ std::vector appl::Router::getAllUserName() { } -void appl::Router::answer(uint64_t _userSessionId, const ememory::SharedPtr& _data) { - for (auto &it : m_clientList) { - if (it == nullptr) { - continue; - } - if (it->checkId(_userSessionId) == false) { - continue; - } - it->returnMessage(_data); - return; - } -} void appl::Router::cleanIO() { diff --git a/tools/router/appl/Router.hpp b/tools/router/appl/Router.hpp index db6b4d5..7b1a338 100644 --- a/tools/router/appl/Router.hpp +++ b/tools/router/appl/Router.hpp @@ -36,7 +36,6 @@ namespace appl { ememory::SharedPtr get(const std::string& _userName); std::vector getAllUserName(); - void answer(uint64_t _userSessionId, const ememory::SharedPtr& _data); void newClientGateWay(enet::Tcp _connection); void newClient(enet::Tcp _connection); void cleanIO(); diff --git a/zeus/AbstractFunctionTypeClass.hpp b/zeus/AbstractFunctionTypeClass.hpp index 2e7e9e1..6700466 100644 --- a/zeus/AbstractFunctionTypeClass.hpp +++ b/zeus/AbstractFunctionTypeClass.hpp @@ -38,7 +38,7 @@ namespace zeus { ret = (*_pointer.*_func)(_obj->getParameter(idParam--)...); } _interfaceClient->addAsync([=](WebServer* _interface) { - _interface->answerValue(_obj->getTransactionId(), _obj->getClientId(), _obj->getServiceId(), ret); + _interface->answerValue(_obj->getTransactionId(), _obj->getDestination(), _obj->getSource(), ret); return true; }); } @@ -67,7 +67,7 @@ namespace zeus { (*_pointer.*_func)(_obj->getParameter(idParam--)...); } _interfaceClient->addAsync([=](WebServer* _interface) { - _interface->answerVoid(_obj->getTransactionId(), _obj->getClientId(), _obj->getServiceId()); + _interface->answerVoid(_obj->getTransactionId(), _obj->getDestination(), _obj->getSource()); return true; }); } @@ -122,8 +122,8 @@ namespace zeus { help += " parameters. prototype function:"; help += getPrototype(); _interfaceClient->answerError(_obj->getTransactionId(), - _obj->getClientId(), - _obj->getServiceId(), + _obj->getDestination(), + _obj->getSource(), "WRONG-PARAMETER-NUMBER", help); return; @@ -132,8 +132,8 @@ namespace zeus { for (size_t iii=0; iiigetParameterType(iii)) == false) { _interfaceClient->answerError(_obj->getTransactionId(), - _obj->getClientId(), - _obj->getServiceId(), + _obj->getDestination(), + _obj->getSource(), "WRONG-PARAMETER-TYPE", std::string("Parameter id ") + etk::to_string(iii) + " not compatible with type: '" + m_paramType[iii].getName() + "'"); return; diff --git a/zeus/AbstractFunctionTypeDirect.hpp b/zeus/AbstractFunctionTypeDirect.hpp index 62c5249..edad3c4 100644 --- a/zeus/AbstractFunctionTypeDirect.hpp +++ b/zeus/AbstractFunctionTypeDirect.hpp @@ -33,7 +33,7 @@ namespace zeus { ret = _func(_obj->getParameter(idParam--)...); } _interfaceClient->addAsync([=](WebServer* _interface) { - _interface->answerValue(_obj->getTransactionId(), _obj->getClientId(), _obj->getServiceId(), ret); + _interface->answerValue(_obj->getTransactionId(), _obj->getDestination(), _obj->getSource(), ret); return true; }); } @@ -60,7 +60,7 @@ namespace zeus { _func(_obj->getParameter(idParam--)...); } _interfaceClient->addAsync([=](WebServer* _interface) { - _interface->answerVoid(_obj->getTransactionId(), _obj->getClientId(), _obj->getServiceId()); + _interface->answerVoid(_obj->getTransactionId(), _obj->getDestination(), _obj->getSource()); return true; }); } @@ -110,8 +110,8 @@ namespace zeus { help += " parameters. prototype function:"; help += getPrototype(); _interfaceClient->answerError(_obj->getTransactionId(), - _obj->getClientId(), - _obj->getServiceId(), + _obj->getDestination(), + _obj->getSource(), "WRONG-PARAMETER-NUMBER", help); return; @@ -120,8 +120,8 @@ namespace zeus { for (size_t iii=0; iiigetParameterType(iii)) == false) { _interfaceClient->answerError(_obj->getTransactionId(), - _obj->getClientId(), - _obj->getServiceId(), + _obj->getDestination(), + _obj->getSource(), "WRONG-PARAMETER-TYPE", std::string("Parameter id ") + etk::to_string(iii) + " not compatible with type: '" + m_paramType[iii].getName() + "'"); return; diff --git a/zeus/Buffer.cpp b/zeus/Buffer.cpp index 7e4eab0..92a3fd6 100644 --- a/zeus/Buffer.cpp +++ b/zeus/Buffer.cpp @@ -157,10 +157,19 @@ uint32_t zeus::Buffer::getTransactionId() const { return m_header.transactionId; } -void zeus::Buffer::settransactionId(uint16_t _value) { +void zeus::Buffer::setTransactionId(uint32_t _value) { m_header.transactionId = _value; } +uint32_t zeus::Buffer::getSource() const { + return (uint32_t(m_header.sourceId) << 16) + m_header.sourceObjectId; +} + +void zeus::Buffer::setSource(uint32_t _value) { + m_header.sourceId = _value >> 16; + m_header.sourceObjectId = _value & 0xFFFF; +} + uint16_t zeus::Buffer::getSourceId() const { return m_header.sourceId; } @@ -177,11 +186,20 @@ void zeus::Buffer::setSourceObjectId(uint16_t _value) { m_header.sourceObjectId = _value; } +uint32_t zeus::Buffer::getDestination() const { + return (uint32_t(m_header.destinationId) << 16) + m_header.destinationObjectId; +} + +void zeus::Buffer::setDestination(uint32_t _value) { + m_header.destinationId = _value >> 16; + m_header.destinationObjectId = _value & 0xFFFF; +} + uint16_t zeus::Buffer::getDestinationId() const { return m_header.destinationId; } -void zeus::Buffer::setDestinationId(uint32_t _value) { +void zeus::Buffer::setDestinationId(uint16_t _value) { m_header.destinationId = _value; } @@ -232,9 +250,9 @@ ememory::SharedPtr zeus::Buffer::create(const std::vector if (value == nullptr) { return nullptr; } - value->settransactionId(header.transactionId); + value->setTransactionId(header.transactionId); value->setSourceId(header.sourceId); - value->setSourceOjectId(header.sourceObjectId); + value->setSourceObjectId(header.sourceObjectId); value->setDestinationId(header.destinationId); value->setDestinationObjectId(header.destinationObjectId); value->setPartFinish((header.flags & ZEUS_BUFFER_FLAG_FINISH) != 0); @@ -248,9 +266,9 @@ ememory::SharedPtr zeus::Buffer::create(const std::vector if (value == nullptr) { return nullptr; } - value->settransactionId(header.transactionId); + value->setTransactionId(header.transactionId); value->setSourceId(header.sourceId); - value->setSourceOjectId(header.sourceObjectId); + value->setSourceObjectId(header.sourceObjectId); value->setDestinationId(header.destinationId); value->setDestinationObjectId(header.destinationObjectId); value->setPartFinish((header.flags & ZEUS_BUFFER_FLAG_FINISH) != 0); @@ -264,9 +282,9 @@ ememory::SharedPtr zeus::Buffer::create(const std::vector if (value == nullptr) { return nullptr; } - value->settransactionId(header.transactionId); + value->setTransactionId(header.transactionId); value->setSourceId(header.sourceId); - value->setSourceOjectId(header.sourceObjectId); + value->setSourceObjectId(header.sourceObjectId); value->setDestinationId(header.destinationId); value->setDestinationObjectId(header.destinationObjectId); value->setPartFinish((header.flags & ZEUS_BUFFER_FLAG_FINISH) != 0); @@ -280,9 +298,9 @@ ememory::SharedPtr zeus::Buffer::create(const std::vector if (value == nullptr) { return nullptr; } - value->settransactionId(header.transactionId); + value->setTransactionId(header.transactionId); value->setSourceId(header.sourceId); - value->setSourceOjectId(header.sourceObjectId); + value->setSourceObjectId(header.sourceObjectId); value->setDestinationId(header.destinationId); value->setDestinationObjectId(header.destinationObjectId); value->setPartFinish((header.flags & ZEUS_BUFFER_FLAG_FINISH) != 0); diff --git a/zeus/Buffer.hpp b/zeus/Buffer.hpp index 319129d..ce907e2 100644 --- a/zeus/Buffer.hpp +++ b/zeus/Buffer.hpp @@ -175,13 +175,23 @@ namespace zeus { /** * @brief Get the transaction identifier of the packet * @return value of the transaction - */getTransactionId + */ uint32_t getTransactionId() const; /** * @brief Set the transaction identifier of the packet * @param[in] _value New transaction id */ void setTransactionId(uint32_t _value); + /** + * @brief Get the Source handle (getSourceId()<<16 + getSourceObjectId()) + * @return Value of the Source handle + */ + uint32_t getSource() const; + /** + * @brief Set the Source handle (getSourceId()<<16 + getSourceObjectId()) + * @param[in] _value New value of the Source handle + */ + void setSource(uint32_t _value); /** * @brief Get the Source identifier of the packet * @return Value of the Source identifier @@ -202,6 +212,16 @@ namespace zeus { * @param[in] _value New value of the Source Object identifier */ void setSourceObjectId(uint16_t _value); + /** + * @brief Get the Destination handle (getDestinationId()<<16 + getDestinationObjectId()) + * @return Value of the Destination identifier + */ + uint32_t getDestination() const; + /** + * @brief Set the Destination handle (getDestinationId()<<16 + getDestinationObjectId()) + * @param[in] _value New value of the Destination handle + */ + void setDestination(uint32_t _value); /** * @brief Get the Destination identifier of the packet * @return Value of the Destination identifier diff --git a/zeus/BufferParameter_addParameter.cpp b/zeus/BufferParameter_addParameter.cpp index 7818ef5..21dc877 100644 --- a/zeus/BufferParameter_addParameter.cpp +++ b/zeus/BufferParameter_addParameter.cpp @@ -326,14 +326,14 @@ namespace zeus { } bool operator() (zeus::WebServer* _interface, - uint32_t _clientId, - uint32_t _serviceId, + uint32_t _source, + uint32_t _destination, uint32_t _transactionId, uint32_t _partId) { ememory::SharedPtr answer = zeus::BufferData::create(); answer->setTransactionId(_transactionId); - answer->setClientId(_clientId); - answer->setServiceId(_serviceId); + answer->setSource(_source); + answer->setDestination(_destination); answer->setPartId(_partId); answer->setPartFinish(false); int32_t tmpSize = ZEUS_MINIMUM_SIZE_MULTIPLE; @@ -396,8 +396,8 @@ namespace zeus { } bool operator() (zeus::WebServer* _interface, - uint32_t _clientId, - uint32_t _serviceId, + uint32_t _source, + uint32_t _destination, uint32_t _transactionId, uint32_t _partId) { if (m_node.fileIsOpen() == false) { @@ -405,8 +405,8 @@ namespace zeus { } ememory::SharedPtr answer = zeus::BufferData::create(); answer->setTransactionId(_transactionId); - answer->setClientId(_clientId); - answer->setServiceId(_serviceId); + answer->setSource(_source); + answer->setDestination(_destination); answer->setPartId(_partId); answer->setPartFinish(false); int32_t tmpSize = ZEUS_MINIMUM_SIZE_MULTIPLE; diff --git a/zeus/Client.cpp b/zeus/Client.cpp index 47e1315..3127c08 100644 --- a/zeus/Client.cpp +++ b/zeus/Client.cpp @@ -12,7 +12,9 @@ zeus::Client::Client() : propertyIp(this, "ip", "127.0.0.1", "Ip to connect server", &zeus::Client::onPropertyChangeIp), - propertyPort(this, "port", 1983, "Port to connect server", &zeus::Client::onPropertyChangePort) { + propertyPort(this, "port", 1983, "Port to connect server", &zeus::Client::onPropertyChangePort), + m_localAddress(0), + m_licalIdObjectIncrement(1) { } @@ -25,6 +27,7 @@ void zeus::Client::onClientData(ememory::SharedPtr _value) { return; } // TODO : We will receive here some notification and call ...like : + /* if (call && id = 0 && objectid == 0) { we will have : if call == "ValidateConnection" @@ -32,9 +35,90 @@ void zeus::Client::onClientData(ememory::SharedPtr _value) { local name like clientname::subID (if multiple connection in parallele) ... and after we can do many thing like provide servies ... } + */ + // TODO: all the basic checks ... + + if (_value == nullptr) { + return; + } + //APPL_ERROR(" ==> parse DATA ..."); + uint32_t transactionId = _value->getTransactionId(); + if (transactionId == 0) { + APPL_ERROR("Protocol error ==>missing id"); + answerProtocolError(transactionId, "missing parameter: 'id'"); + return; + } + // Check if we are the destinated Of this message + if (_value->getDestinationId() != m_localAddress) { + APPL_ERROR("Protocol error ==> Wrong ID of the interface " << _value->getDestinationId() << " != " << m_localAddress); + answerProtocolError(transactionId, "wrong adress: request " + etk::to_string(m_localAddress) + " have " + etk::to_string(m_localAddress)); + return; + } + if (_value->getDestinationObjectId() == ZEUS_ID_GATEWAY_OBJECT) { + if (_value->getType() == zeus::Buffer::typeMessage::call) { + ememory::SharedPtr callObj = ememory::staticPointerCast(_value); + std::string callFunction = callObj->getCall(); + if ( callFunction != "link" + && callFunction != "unlink") { + answerProtocolError(transactionId, "interact with client, musty only call: link/unlink"); + return; + } + if (callFunction != "link") { + // link with a specific service: + std::string serviceName = callObj->getParameter(0); + for (auto &it : m_listServicesAvaillable) { + if (it.first == serviceName) { + ZEUS_INFO("find service : " << it.first); + // TODO: ... + // Check if it is not already connected to this service, if it is true ==> reject IT + + // Create new service object + + ememory::SharedPtr newService = it.second(*this, m_licalIdObjectIncrement); + // TODO : Do it better ... + + m_listLocalObject.push_back(newService); + // Return the Value of the object service .... this is really bad, Maybe add a message type for this... + m_interfaceWeb->answerValue(transactionId, _value->getDestination(), _value->getSource(), (uint32_t(m_localAddress)<<16)+m_licalIdObjectIncrement ); + m_licalIdObjectIncrement++; + return; + } + } + m_interfaceWeb->answerError(transactionId, _value->getDestination(), _value->getSource(), "UNKNOW-SERVICE"); + } + } + m_interfaceWeb->answerError(transactionId, _value->getDestination(), _value->getSource(), "UNKNOW-ACTION"); + return; + } + // find the object to communicate the adress to send value ... + ZEUS_ERROR("Get Data On the Communication interface that is not understand ... : " << _value); } +bool zeus::Client::serviceAdd(const std::string& _serviceName, factoryService _factory) { + // Check if we can provide new service: + zeus::Future futValidate = m_interfaceWeb->call(m_localAddress, ZEUS_GATEWAY_ADDRESS, "serviceAdd", _serviceName); + futValidate.wait(); // TODO: Set timeout ... + if (futValidate.hasError() == true) { + ZEUS_ERROR("Can not provide a new sevice ... '" << futValidate.getErrorType() << "' help:" << futValidate.getErrorHelp()); + return false; + } + m_listServicesAvaillable.add(std::make_pair(_serviceName, _factory)); + return true; +} + +bool zeus::Client::serviceRemove(const std::string& _serviceName) { + // Check if we can provide new service: + zeus::Future futValidate = m_interfaceWeb->call(m_localAddress, ZEUS_GATEWAY_ADDRESS, "serviceRemove", _serviceName); + futValidate.wait(); // TODO: Set timeout ... + if (futValidate.hasError() == true) { + ZEUS_ERROR("Can not provide a new sevice ... '" << futValidate.getErrorType() << "' help:" << futValidate.getErrorHelp()); + return false; + } + ZEUS_TODO("remove service : " << _serviceName); + return true; +} + zeus::ServiceRemote zeus::Client::getService(const std::string& _name) { ZEUS_TODO("Lock here"); auto it = m_listConnectedService.begin(); @@ -48,7 +132,7 @@ zeus::ServiceRemote zeus::Client::getService(const std::string& _name) { return zeus::ServiceRemote(val); } } - ememory::SharedPtr tmp = ememory::makeShared(m_interfaceClient, _name); + ememory::SharedPtr tmp = ememory::makeShared(m_interfaceWeb, _name); m_listConnectedService.push_back(tmp); return zeus::ServiceRemote(tmp); } @@ -66,17 +150,25 @@ bool zeus::Client::connectTo(const std::string& _address) { ZEUS_DEBUG("connect [START]"); disconnect(); enet::Tcp connection = std::move(enet::connectTcpClient(*propertyIp, *propertyPort)); - m_interfaceClient = ememory::makeShared(); - if (m_interfaceClient == nullptr) { + m_interfaceWeb = ememory::makeShared(); + if (m_interfaceWeb == nullptr) { ZEUS_ERROR("Allocate connection error"); return false; } ZEUS_WARNING("Request connect user " << _address); - m_interfaceClient->connect(this, &zeus::Client::onClientData); - m_interfaceClient->setInterface(std::move(connection), false, _address); - m_interfaceClient->connect(); + m_interfaceWeb->connect(this, &zeus::Client::onClientData); + m_interfaceWeb->setInterface(std::move(connection), false, _address); + m_interfaceWeb->connect(); + + zeus::Future retIdentify = call(0, ZEUS_ID_GATEWAY, "getAddress").wait(); + if (retIdentify.hasError() == true) { + disconnect(); + return false; + } + m_localAddress = retIdentify.get(); + /* - ZEUS_WARNING("Request connect user " << _address); + ZEUS_WARNING("Now, we get information relative with our name and adress" << _address); zeus::Future ret = call("connectToUser", _address, "zeus-client"); ret.wait(); if (ret.hasError() == true) { @@ -97,11 +189,11 @@ bool zeus::Client::connectTo(const std::string& _address) { } bool zeus::Client::connect() { - bool ret = connectTo("srvIO"); + bool ret = connectTo("directIO"); if (ret==false) { return false; } - zeus::Future retIdentify = call("anonymous").wait(); + zeus::Future retIdentify = call(0, ZEUS_ID_GATEWAY, "service").wait(); if (retIdentify.hasError() == true) { disconnect(); return false; @@ -118,7 +210,7 @@ bool zeus::Client::connect(const std::string& _address) { if (ret==false) { return false; } - zeus::Future retIdentify = call("anonymous").wait(); + zeus::Future retIdentify = call(0, ZEUS_ID_GATEWAY, "anonymous").wait(); if (retIdentify.hasError() == true) { disconnect(); return false; @@ -135,7 +227,7 @@ bool zeus::Client::connect(const std::string& _address, const std::string& _user if (ret==false) { return false; } - zeus::Future retIdentify = call("auth", _userPassword).wait(); + zeus::Future retIdentify = call(0, ZEUS_ID_GATEWAY, "auth", _userPassword).wait(); if (retIdentify.hasError() == true) { disconnect(); return false; @@ -152,7 +244,7 @@ bool zeus::Client::connect(const std::string& _address, const std::string& _clie if (ret==false) { return false; } - zeus::Future retIdentify = call("identify", _clientName, _clientTocken).wait(); + zeus::Future retIdentify = call(0, ZEUS_ID_GATEWAY, "identify", _clientName, _clientTocken).wait(); if (retIdentify.hasError() == true) { disconnect(); return false; @@ -165,11 +257,25 @@ bool zeus::Client::connect(const std::string& _address, const std::string& _clie void zeus::Client::disconnect() { ZEUS_DEBUG("disconnect [START]"); - if (m_interfaceClient != nullptr) { - m_interfaceClient->disconnect(); - m_interfaceClient.reset(); + if (m_interfaceWeb != nullptr) { + m_interfaceWeb->disconnect(); + m_interfaceWeb.reset(); } else { ZEUS_VERBOSE("Nothing to disconnect ..."); } ZEUS_DEBUG("disconnect [STOP]"); } + +bool zeus::Client::isAlive() { + if (m_interfaceWeb == nullptr) { + return false; + } + return m_interfaceWeb->isActive(); +} + +void zeus::Client::pingIsAlive() { + if (std::chrono::steady_clock::now() - m_interfaceWeb->getLastTimeSend() >= std::chrono::seconds(30)) { + m_interfaceWeb->ping(); + } +} + diff --git a/zeus/Client.hpp b/zeus/Client.hpp index 3129cf8..05795d4 100644 --- a/zeus/Client.hpp +++ b/zeus/Client.hpp @@ -12,8 +12,10 @@ #include #include +#include namespace zeus { + class Service; /** * @brief Client interface to acces on the remote service and gateway */ @@ -23,10 +25,13 @@ namespace zeus { eproperty::Value propertyIp; //!< Ip of WebSocket TCP connection eproperty::Value propertyPort; //!< Port of the WebSocket connection private: + uint16_t m_localAddress; + uint16_t m_licalIdObjectIncrement; //!< attribute a unique ID for an object std::string m_clientName; //!< Local client name to generate the local serrvice name if needed (if direct connection ==> no name) - ememory::SharedPtr m_interfaceClient; //!< Interface on the Websocket interface + ememory::SharedPtr m_interfaceWeb; //!< Interface on the Websocket interface std::vector> m_listConnectedService; //!< Connect only one time on each service, not needed more. std::vector> m_listProvicedService; //!< Connect only one time on each service, not needed more. + std::vector> m_listLocalObject; public: /** * @brief @@ -81,13 +86,17 @@ namespace zeus { * @return Pointer on an interface of remote service */ zeus::ServiceRemote getService(const std::string& _serviceName); + using factoryService = std::function, zeus::Client&, uint16_t objId)>; + + std::map m_listServicesAvaillable; //!< list of all factory availlable /** * @brief Provide a service with a specific name * @param[in] _serviceName Name of the service * @param[in] _service handle on the service provided * @return true if the service is acepted or false if not */ - bool provideService(const std::string& _serviceName, ememory::SharedPtr& _service); + bool serviceAdd(const std::string& _serviceName, factoryService _factory); + bool serviceRemove(const std::string& _serviceName); private: /** * @brief When receive data from the websocket ... call this ... @@ -101,17 +110,22 @@ namespace zeus { * @param[in] _args... multiple argument neededs * @return a future that will contain the aswer when receiveed (need to transmit over ethernet) */ - /* template - zeus::FutureBase call(const std::string& _functionName, _ARGS&&... _args) { - if (m_interfaceClient == nullptr) { + zeus::FutureBase call(uint16_t _srcObjectId, + uint32_t _destination, + const std::string& _functionName, + _ARGS&&... _args) { + if (m_interfaceWeb == nullptr) { ememory::SharedPtr ret = zeus::BufferAnswer::create(); ret->addError("NULLPTR", "call " + _functionName + " with no interface open"); return zeus::FutureBase(0, ret); } - return m_interfaceClient->call(ZEUS_NO_ID_CLIENT, ZEUS_ID_SERVICE_ROOT, _functionName, _args...); + uint32_t source = (uint32_t(m_localAddress) << 16) + _srcObjectId; + return m_interfaceWeb->call(source, _destination, _functionName, _args...); + } + uint16_t getlocalAddress() { + return m_localAddress; } - */ private: /** * @brief Internal (called when user change the Ip of the client interface) @@ -121,6 +135,19 @@ namespace zeus { * @brief Internal (called when user change the port of the client interface) */ void onPropertyChangePort(); + public: + /** + * @brief + * @param[in] + * @return + */ + void pingIsAlive(); + /** + * @brief + * @param[in] + * @return + */ + bool isAlive(); }; } diff --git a/zeus/FutureBase.cpp b/zeus/FutureBase.cpp index b8aaebd..91d27bd 100644 --- a/zeus/FutureBase.cpp +++ b/zeus/FutureBase.cpp @@ -17,16 +17,15 @@ zeus::FutureBase::FutureBase() { m_data = nullptr; } -zeus::FutureBase::FutureBase(uint32_t _transactionId, /*zeus::FutureData::ObserverFinish _callback, */uint32_t _clientId) { +zeus::FutureBase::FutureBase(uint32_t _transactionId, uint32_t _source) { m_data = ememory::makeShared(); if (m_data == nullptr) { return; } m_data->m_sendTime = std::chrono::steady_clock::now(); m_data->m_transactionId = _transactionId; - m_data->m_clientId = _clientId; + m_data->m_source = _source; m_data->m_isSynchronous = false; - //m_data->m_callbackFinish = _callback; } ememory::SharedPtr zeus::FutureBase::getRaw() { @@ -36,29 +35,19 @@ ememory::SharedPtr zeus::FutureBase::getRaw() { return m_data->m_returnData; } -zeus::FutureBase::FutureBase(uint32_t _transactionId, ememory::SharedPtr _returnData, /*zeus::FutureData::ObserverFinish _callback, */uint32_t _clientId) { +zeus::FutureBase::FutureBase(uint32_t _transactionId, ememory::SharedPtr _returnData, uint32_t _source) { m_data = ememory::makeShared(); if (m_data == nullptr) { return; } m_data->m_sendTime = std::chrono::steady_clock::now(); m_data->m_transactionId = _transactionId; - m_data->m_clientId = _clientId; + m_data->m_source = _source; m_data->m_isSynchronous = false; m_data->m_returnData = _returnData; - #if 0 - m_data->m_callbackFinish = _callback; - if (isFinished() == true) { - m_data->m_receiveTime = std::chrono::steady_clock::now(); - if (m_data->m_callbackFinish != nullptr) { - m_data->m_callbackFinish(*this); - } - } - #else if (isFinished() == true) { m_data->m_receiveTime = std::chrono::steady_clock::now(); } - #endif } void zeus::FutureBase::andAll(zeus::FutureData::Observer _callback) { @@ -191,11 +180,11 @@ uint32_t zeus::FutureBase::getTransactionId() const { return m_data->m_transactionId; } -uint32_t zeus::FutureBase::getClientId() const { +uint32_t zeus::FutureBase::getSource() const { if (m_data == nullptr) { return 0; } - return m_data->m_clientId; + return m_data->m_source; } bool zeus::FutureBase::hasError() const { diff --git a/zeus/FutureBase.hpp b/zeus/FutureBase.hpp index c95166c..7552e12 100644 --- a/zeus/FutureBase.hpp +++ b/zeus/FutureBase.hpp @@ -27,17 +27,17 @@ namespace zeus { /** * @brief Contructor of the FutureBase with an ofserver * @param[in] _transactionId Transaction waiting answer - * @param[in] _clientId Client/sevice Id waiting answer + * @param[in] _source Client/sevice Id waiting answer */ - FutureBase(uint32_t _transactionId, uint32_t _clientId=0); + FutureBase(uint32_t _transactionId, uint32_t _source=0); /** * @brief Contructor of the FutureBase for direct error answer * @param[in] _transactionId Transaction waiting answer * @param[in] _isFinished set state finish or not * @param[in] _returnData Set return value - * @param[in] _clientId Client/sevice Id waiting answer + * @param[in] _source Source that is waiting for answer */ - FutureBase(uint32_t _transactionId, ememory::SharedPtr _returnData, uint32_t _clientId=0); + FutureBase(uint32_t _transactionId, ememory::SharedPtr _returnData, uint32_t _source=0); /** * @brief Attach callback on all return type of value * @param[in] _callback Handle on the function to call in all case @@ -86,7 +86,7 @@ namespace zeus { * @brief Get the client Id of the Future * @return Client id requested or 0 */ - uint32_t getClientId() const; + uint32_t getSource() const; /** * @brief check if the answer have an error * @return return true if an error is registered diff --git a/zeus/FutureData.hpp b/zeus/FutureData.hpp index d181c15..6e74915 100644 --- a/zeus/FutureData.hpp +++ b/zeus/FutureData.hpp @@ -22,7 +22,7 @@ namespace zeus { using Observer = std::function; //!< Define an Observer: function pointer public: uint32_t m_transactionId; //!< waiting answer data - uint32_t m_clientId; //!< need to anser at this client. + uint32_t m_source; //!< Source of the message. bool m_isSynchronous; //!< the future is synchronous. (call when receive data) ememory::SharedPtr m_returnData; //!< all buffer concatenate or last buffer if synchronous Observer m_callbackThen; //!< observer callback When data arrive and NO error appear diff --git a/zeus/Object.cpp b/zeus/Object.cpp new file mode 100644 index 0000000..3ae24d0 --- /dev/null +++ b/zeus/Object.cpp @@ -0,0 +1,110 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2016, Edouard DUPIN, all right reserved + * @license APACHE v2.0 (see license file) + */ + +#include +#include +#include +#include + + + +zeus::Object::Object() { + zeus::AbstractFunction* func = advertise("getExtention", &zeus::Object::getExtention); + if (func != nullptr) { + func->setDescription("Get List of availlable extention of this Object"); + func->setReturn("A list of extention register in the Object"); + } +} + +zeus::Object::~Object() { + +} + + +void zeus::Object::receive(ememory::SharedPtr _value) { + if (_value == nullptr) { + return; + } + ZEUS_WARNING("BUFFER" << _value); + uint32_t tmpID = _value->getTransactionId(); + uint32_t source = _value->getSource(); + if (_value->getType() == zeus::Buffer::typeMessage::data) { + auto it = m_callMultiData.begin(); + while (it != m_callMultiData.end()) { + if ( it->getTransactionId() == tmpID + && it->getSource() == source) { + ZEUS_WARNING("Append data ... " << tmpID); + it->appendData(_value); + if (it->isFinished() == true) { + ZEUS_WARNING("CALL Function ..."); + callBinary(it->getRaw()); + it = m_callMultiData.erase(it); + } + return; + } + ++it; + } + ZEUS_ERROR("Un-associated data ..."); + return; + } + ZEUS_WARNING("direct call"); + zeus::FutureBase futData(tmpID, _value, source); + if (futData.isFinished() == true) { + ZEUS_INFO("Call Binary .."); + callBinary(futData.getRaw()); + } else { + ZEUS_INFO("ADD ..."); + m_callMultiData.push_back(futData); + } +} + +void zeus::Object::callBinary(ememory::SharedPtr _obj) { + ZEUS_INFO("plop 1 ..."); + if (_obj == nullptr) { + return; + } + ZEUS_INFO("plop 2 ..."); + if (_obj->getType() == zeus::Buffer::typeMessage::event) { + ZEUS_ERROR("Unknow event: '...'"); + return; + } + ZEUS_INFO("plop 3 ..."); + if (_obj->getType() == zeus::Buffer::typeMessage::answer) { + ZEUS_ERROR("Local Answer: '...'"); + return; + } + ZEUS_INFO("plop 4 ..."); + if (_obj->getType() == zeus::Buffer::typeMessage::call) { + ZEUS_INFO("plop 5 ... "); + ememory::SharedPtr callObj = ememory::staticPointerCast(_obj); + uint32_t source = callObj->getSource(); + uint32_t sourceId = callObj->getSourceId(); + std::string callFunction = callObj->getCall(); + ZEUS_INFO("plop - ... " << callFunction); + if (callFunction[0] == '_') { + if (callFunction == "_new") { + std::string userName = callObj->getParameter(0); + std::string clientName = callObj->getParameter(1); + std::vector clientGroup = callObj->getParameter>(2); + clientConnect(sourceId, userName, clientName, clientGroup); + } else if (callFunction == "_delete") { + clientDisconnect(sourceId); + } + m_interfaceClient->answerValue(callObj->getTransactionId(), uint32_t(m_id)<<16, source, true); + return; + } else if (isFunctionAuthorized(sourceId, callFunction) == true) { + ZEUS_INFO("plop 6 ..."); + callBinary2(callFunction, callObj); + return; + } else { + ZEUS_INFO("plop 7 ..."); + m_interfaceClient->answerError(callObj->getTransactionId(), uint32_t(m_id)<<16, source, "NOT-AUTHORIZED-FUNCTION", ""); + return; + } + } +} + + diff --git a/zeus/Object.hpp b/zeus/Object.hpp new file mode 100644 index 0000000..13abdb9 --- /dev/null +++ b/zeus/Object.hpp @@ -0,0 +1,194 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2016, Edouard DUPIN, all right reserved + * @license APACHE v2.0 (see license file) + */ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +/** + * @brief Main zeus library namespace + */ +namespace zeus { + /** + * @brief + * @param[in] + * @return + */ + class Object : public zeus::RemoteProcessCall { + protected: + std::mutex m_mutex; + protected: + ememory::SharedPtr m_interfaceClient; + uint16_t m_ObjectId; + //std::vector m_callMultiData; + public: + /** + * @brief + * @param[in] + * @return + */ + Object(); + /** + * @brief + * @param[in] + * @return + */ + virtual ~Object(); + private: + /** + * @brief + * @param[in] + * @return + */ + void receive(ememory::SharedPtr _value); + private: + /** + * @brief + * @param[in] + * @return + */ + void callBinary(ememory::SharedPtr _obj); + /** + * @brief + * @param[in] + * @return + */ + virtual void callBinary2(const std::string& _call, ememory::SharedPtr _obj); + public: + /** + * @brief + * @param[in] + * @return + */ + // Add Local fuction (depend on this class) + template + zeus::AbstractFunction* advertise(std::string _name, + ZEUS_RETURN_VALUE (ZEUS_CLASS_TYPE::*_func)(ZEUS_FUNC_ARGS_TYPE... _args)) { + _name = "srv." + _name; + for (auto &it : m_listFunction) { + if (it == nullptr) { + continue; + } + if (it->getName() == _name) { + ZEUS_ERROR("Advertise function already bind .. ==> can not be done...: '" << _name << "'"); + return nullptr; + } + } + AbstractFunction* tmp = createAbstractFunctionClass(_name, _func); + if (tmp == nullptr) { + ZEUS_ERROR("can not create abstract function ... '" << _name << "'"); + return nullptr; + } + tmp->setType(zeus::AbstractFunction::type::service); + ZEUS_INFO("Add function '" << _name << "' in local mode"); + m_listFunction.push_back(tmp); + return tmp; + } + }; + + template + class ObjectType : public zeus::Object { + private: + ZEUS_TYPE_OBJECT m_interface; // direct handle on the data; + public: + /** + * @brief + * @param[in] + * @return + */ + template + zeus::AbstractFunction* advertise(const std::string& _name, + ZEUS_RETURN_VALUE (ZEUS_CLASS_TYPE::*_func)(ZEUS_FUNC_ARGS_TYPE... _args)) { + if (etk::start_with(_name, "srv.") == true) { + ZEUS_ERROR("Advertise function start with 'srv.' is not permited ==> only allow for internal service: '" << _name << "'"); + return nullptr; + } + for (auto &it : m_listFunction) { + if (it == nullptr) { + continue; + } + if (it->getName() == _name) { + ZEUS_ERROR("Advertise function already bind .. ==> can not be done...: '" << _name << "'"); + return nullptr; + } + } + zeus::AbstractFunction* tmp = createAbstractFunctionClass(_name, _func); + if (tmp == nullptr) { + ZEUS_ERROR("can not create abstract function ... '" << _name << "'"); + return nullptr; + } + tmp->setType(zeus::AbstractFunction::type::object); + ZEUS_INFO("Add function '" << _name << "' in object mode"); + m_listFunction.push_back(tmp); + return tmp; + } + /** + * @brief + * @param[in] + * @return + */ + bool isFunctionAuthorized(uint64_t _clientId, const std::string& _funcName) { + /* + auto it = m_interface.find(_clientId); + if (it == m_interface.end()) { + ZEUS_ERROR("CLIENT does not exist ... " << _clientId << " " << _funcName); + return false; + } + return it->second.first->isFunctionAuthorized(_funcName); + */ + return true; + } + /** + * @brief + * @param[in] + * @return + */ + void callBinary2(const std::string& _call, ememory::SharedPtr _obj) { + for (auto &it2 : m_listFunction) { + if (it2 == nullptr) { + continue; + } + if (it2->getName() != _call) { + continue; + } + switch (it2->getType()) { + case zeus::AbstractFunction::type::object: { + it2->execute(m_interfaceClient, _obj, (void*)m_interface); + return; + } + case zeus::AbstractFunction::type::local: { + it2->execute(m_interfaceClient, _obj, (void*)((RemoteProcessCall*)this)); + return; + } + case zeus::AbstractFunction::type::service: { + it2->execute(m_interfaceClient, _obj, (void*)this); + return; + } + case zeus::AbstractFunction::type::global: { + it2->execute(m_interfaceClient, _obj, nullptr); + return; + } + case zeus::AbstractFunction::type::unknow: + ZEUS_ERROR("Can not call unknow type ..."); + break; + } + } + m_interfaceClient->answerError(_obj->getTransactionId(), _obj->getDestination(), _obj->getSource(), "FUNCTION-UNKNOW", "not find function name: '" + _call + "'"); + return; + } + }; +} + + diff --git a/zeus/Service.cpp b/zeus/Service.cpp index eaa995d..4445115 100644 --- a/zeus/Service.cpp +++ b/zeus/Service.cpp @@ -38,12 +38,12 @@ void zeus::Service::onClientData(ememory::SharedPtr _value) { } ZEUS_WARNING("BUFFER" << _value); uint32_t tmpID = _value->getTransactionId(); - uint32_t clientId = _value->getClientId(); + uint32_t source = _value->getSource(); if (_value->getType() == zeus::Buffer::typeMessage::data) { auto it = m_callMultiData.begin(); while (it != m_callMultiData.end()) { if ( it->getTransactionId() == tmpID - && it->getClientId() == clientId) { + && it->getSource() == source) { ZEUS_WARNING("Append data ... " << tmpID); it->appendData(_value); if (it->isFinished() == true) { @@ -59,7 +59,7 @@ void zeus::Service::onClientData(ememory::SharedPtr _value) { return; } ZEUS_WARNING("direct call"); - zeus::FutureBase futData(tmpID, _value, clientId); + zeus::FutureBase futData(tmpID, _value, source); if (futData.isFinished() == true) { ZEUS_INFO("Call Binary .."); callBinary(futData.getRaw()); @@ -154,7 +154,8 @@ void zeus::Service::callBinary(ememory::SharedPtr _obj) { if (_obj->getType() == zeus::Buffer::typeMessage::call) { ZEUS_INFO("plop 5 ... "); ememory::SharedPtr callObj = ememory::staticPointerCast(_obj); - uint32_t clientId = callObj->getClientId(); + uint32_t source = callObj->getSource(); + uint32_t sourceId = callObj->getSourceId(); std::string callFunction = callObj->getCall(); ZEUS_INFO("plop - ... " << callFunction); if (callFunction[0] == '_') { @@ -162,19 +163,19 @@ void zeus::Service::callBinary(ememory::SharedPtr _obj) { std::string userName = callObj->getParameter(0); std::string clientName = callObj->getParameter(1); std::vector clientGroup = callObj->getParameter>(2); - clientConnect(clientId, userName, clientName, clientGroup); + clientConnect(sourceId, userName, clientName, clientGroup); } else if (callFunction == "_delete") { - clientDisconnect(clientId); + clientDisconnect(sourceId); } - m_interfaceClient->answerValue(callObj->getTransactionId(), clientId, m_id, true); + m_interfaceClient->answerValue(callObj->getTransactionId(), uint32_t(m_id)<<16, source, true); return; - } else if (isFunctionAuthorized(clientId, callFunction) == true) { + } else if (isFunctionAuthorized(sourceId, callFunction) == true) { ZEUS_INFO("plop 6 ..."); callBinary2(callFunction, callObj); return; } else { ZEUS_INFO("plop 7 ..."); - m_interfaceClient->answerError(callObj->getTransactionId(), clientId, m_id, "NOT-AUTHORIZED-FUNCTION", ""); + m_interfaceClient->answerError(callObj->getTransactionId(), uint32_t(m_id)<<16, source, "NOT-AUTHORIZED-FUNCTION", ""); return; } } diff --git a/zeus/Service.hpp b/zeus/Service.hpp index 8a5a09b..3b4d310 100644 --- a/zeus/Service.hpp +++ b/zeus/Service.hpp @@ -180,17 +180,17 @@ namespace zeus { void onPropertyChangePort(); /** * @brief A extern client connect on specific user - * @param[in] _clientId Source session Id on the client + * @param[in] _sourceId Source session Id on the client * @param[in] _userName User name of the client to connect * @todo Set a relur like ==> service not availlable / service close / service maintenance / service right reject */ - virtual void clientConnect(uint64_t _clientId, const std::string& _userName, const std::string& _clientName, const std::vector& _groups) = 0; + virtual void clientConnect(uint16_t _sourceId, const std::string& _userName, const std::string& _clientName, const std::vector& _groups) = 0; /** * @brief * @param[in] * @return */ - virtual void clientDisconnect(uint64_t _clientId) = 0; + virtual void clientDisconnect(uint16_t _sourceId) = 0; /** * @brief * @param[in] @@ -245,15 +245,10 @@ namespace zeus { }; template class ServiceType : public zeus::Service { - private: - std::function(ememory::SharedPtr, const std::string&)> m_factory; - public: - ServiceType(std::function(ememory::SharedPtr, const std::string&)> _factory) { - m_factory = _factory; - } private: // no need of shared_ptr or unique_ptr (if service die all is lost and is client die, the gateway notify us...) - std::map, ememory::SharedPtr>> m_interface; + ememory::SharedPtr m_property + ZEUS_TYPE_SERVICE m_interface; public: /** * @brief @@ -294,21 +289,25 @@ namespace zeus { * @return */ bool isFunctionAuthorized(uint64_t _clientId, const std::string& _funcName) { + /* auto it = m_interface.find(_clientId); if (it == m_interface.end()) { ZEUS_ERROR("CLIENT does not exist ... " << _clientId << " " << _funcName); return false; } return it->second.first->isFunctionAuthorized(_funcName); + */ + return true; } /** * @brief * @param[in] * @return */ - void clientConnect(uint64_t _clientId, const std::string& _userName, const std::string& _clientName, const std::vector& _groups) { + /* + void clientConnect(uint16_t _sourceId, const std::string& _userName, const std::string& _clientName, const std::vector& _groups) { std::unique_lock lock(m_mutex); - ZEUS_DEBUG("connect: " << _clientId << " to '" << _userName << "'"); + ZEUS_DEBUG("connect: " << _sourceId << " to '" << _userName << "'"); ZEUS_DEBUG(" client name='" << _clientName << "'"); ZEUS_DEBUG(" groups=" << etk::to_string(_groups)); ememory::SharedPtr tmpProperty = ememory::makeShared(_clientName, _groups); @@ -318,7 +317,7 @@ namespace zeus { } else { ZEUS_ERROR("Create service with no factory"); } - m_interface.insert(std::make_pair(_clientId, std::make_pair(tmpProperty, tmpSrv))); + m_interface.insert(std::make_pair(_sourceId, std::make_pair(tmpProperty, tmpSrv))); // enable list of function availlable: for (auto &it : m_listFunction) { if (it == nullptr) { @@ -327,61 +326,70 @@ namespace zeus { tmpProperty->addAuthorized(it->getName()); } } + */ /** * @brief * @param[in] * @return */ - void clientDisconnect(uint64_t _clientId) { + /* + void clientDisconnect(uint16_t _sourceId) { std::unique_lock lock(m_mutex); - ZEUS_DEBUG("disconnect: " << _clientId); - auto it = m_interface.find(_clientId); + ZEUS_DEBUG("disconnect: " << _sourceId); + auto it = m_interface.find(_sourceId); if (it == m_interface.end()) { - ZEUS_WARNING("disconnect ==> Not find Client ID " << _clientId); + ZEUS_WARNING("disconnect ==> Not find Client ID " << _sourceId); // noting to do ==> user never conected. return; } m_interface.erase(it); } + */ /** * @brief * @param[in] * @return */ - void clientSetName(uint64_t _clientId, const std::string& _clientName) { + /* + void clientSetName(uint16_t _sourceId, const std::string& _clientName) { std::unique_lock lock(m_mutex); - auto it = m_interface.find(_clientId); + auto it = m_interface.find(_sourceId); if (it == m_interface.end()) { ZEUS_ERROR("Change the client property but client was not created ..."); return; } it->second.first->setName(_clientName); } + */ /** * @brief * @param[in] * @return */ - void clientSetGroup(uint64_t _clientId, const std::vector& _clientGroups) { + /* + void clientSetGroup(uint16_t _sourceId, const std::vector& _clientGroups) { std::unique_lock lock(m_mutex); - auto it = m_interface.find(_clientId); + auto it = m_interface.find(_sourceId); if (it == m_interface.end()) { ZEUS_ERROR("Change the client property but client was not created ..."); return; } it->second.first->setGroups(_clientGroups); } + */ /** * @brief * @param[in] * @return */ void callBinary2(const std::string& _call, ememory::SharedPtr _obj) { - auto it = m_interface.find(_obj->getClientId()); + /* + auto it = m_interface.find(_obj->getSourceId()); if (it == m_interface.end()) { - m_interfaceClient->answerError(_obj->getTransactionId(), _obj->getClientId(), _obj->getServiceId(), "CLIENT-UNKNOW", ""); + m_interfaceClient->answerError(_obj->getTransactionId(), _obj->getDestination(), _obj->getSource(), "CLIENT-UNKNOW", ""); return; } + */ for (auto &it2 : m_listFunction) { if (it2 == nullptr) { continue; @@ -391,8 +399,9 @@ namespace zeus { } switch (it2->getType()) { case zeus::AbstractFunction::type::object: { - ZEUS_TYPE_SERVICE* elem = it->second.second.get(); - it2->execute(m_interfaceClient, _obj, (void*)elem); + //ZEUS_TYPE_SERVICE* elem = it->second.second.get(); + //it2->execute(m_interfaceClient, _obj, (void*)elem); + it2->execute(m_interfaceClient, _obj, (void*)m_interface); return; } case zeus::AbstractFunction::type::local: { @@ -412,7 +421,7 @@ namespace zeus { break; } } - m_interfaceClient->answerError(_obj->getTransactionId(), _obj->getClientId(), _obj->getServiceId(), "FUNCTION-UNKNOW", ""); + m_interfaceClient->answerError(_obj->getTransactionId(), _obj->getDestination(), _obj->getSource(), "FUNCTION-UNKNOW", ""); return; } }; diff --git a/zeus/ServiceRemote.hpp b/zeus/ServiceRemote.hpp index 219c53b..80f67f3 100644 --- a/zeus/ServiceRemote.hpp +++ b/zeus/ServiceRemote.hpp @@ -94,7 +94,6 @@ namespace zeus { */ template zeus::FutureBase call(const std::string& _functionName, _ARGS&&... _args) { - if ( m_interface == nullptr || m_interface->m_interfaceClient == nullptr) { ememory::SharedPtr ret = zeus::BufferAnswer::create(); @@ -105,26 +104,6 @@ namespace zeus { } return m_interface->m_interfaceClient->call(ZEUS_NO_ID_CLIENT, m_interface->m_serviceId, _functionName, _args...); } - /** - * @brief - * @param[in] - * @return - */ - // TODO: Remove the callback to add it in future with the "then(_callback)" and "else(_callback)" and "abort(_callbacl)" ... - /* - template - zeus::FutureBase callAction(const std::string& _functionName, _ARGS&&... _args, zeus::FutureData::ObserverFinish _callback) { - if ( m_interface == nullptr - || m_interface->m_interfaceClient == nullptr) { - ememory::SharedPtr ret = zeus::BufferAnswer::create(); - if (ret != nullptr) { - ret->addError("NULLPTR", "call " + _functionName + " with no interface open"); - } - return zeus::FutureBase(0, ret, _callback); - } - return m_interface->m_interfaceClient->callServiceAction(ZEUS_NO_ID_CLIENT, m_interface->m_serviceId, _functionName, _args..., _callback); - } - */ }; diff --git a/zeus/WebServer.cpp b/zeus/WebServer.cpp index dde86a9..52c3233 100644 --- a/zeus/WebServer.cpp +++ b/zeus/WebServer.cpp @@ -11,13 +11,13 @@ #include -ememory::SharedPtr zeus::createBaseCall(uint64_t _transactionId, const uint32_t& _clientId, const uint32_t& _serviceId, const std::string& _functionName) { +ememory::SharedPtr zeus::createBaseCall(uint64_t _transactionId, const uint32_t& _source, const uint32_t& _destination, const std::string& _functionName) { ememory::SharedPtr obj = zeus::BufferCall::create(); if (obj == nullptr) { return nullptr; } - obj->setServiceId(_serviceId); - obj->setClientId(_clientId); + obj->setSource(_source); + obj->setDestination(_destination); obj->setCall(_functionName); obj->setTransactionId(_transactionId); return obj; @@ -118,22 +118,22 @@ class SendAsyncBinary { private: std::vector m_async; uint64_t m_transactionId; - uint32_t m_clientId; - uint32_t m_serviceId; + uint32_t m_source; + uint32_t m_destination; uint32_t m_partId; public: - SendAsyncBinary(uint64_t _transactionId, const uint32_t& _clientId, const uint32_t& _serviceId, std::vector _async) : + SendAsyncBinary(uint64_t _transactionId, const uint32_t& _source, const uint32_t& _destination, std::vector _async) : m_async(std::move(_async)), m_transactionId(_transactionId), - m_clientId(_clientId), - m_serviceId(_serviceId), + m_source(_source), + m_destination(_destination), m_partId(1) { } bool operator() (zeus::WebServer* _interface){ auto it = m_async.begin(); while (it != m_async.end()) { - bool ret = (*it)(_interface, m_clientId, m_serviceId, m_transactionId, m_partId); + bool ret = (*it)(_interface, m_source, m_destination, m_transactionId, m_partId); if (ret == true) { // Remove it ... it = m_async.erase(it); @@ -148,8 +148,8 @@ class SendAsyncBinary { return true; } //obj->setInterfaceId(m_interfaceId); - obj->setClientId(m_clientId); - obj->setServiceId(m_serviceId); + obj->setSource(m_source); + obj->setDestination(m_destination); obj->setTransactionId(m_transactionId); obj->setPartId(m_partId); obj->setPartFinish(true); @@ -176,7 +176,7 @@ int32_t zeus::WebServer::writeBinary(ememory::SharedPtr _obj) { if (_obj->writeOn(m_connection) == true) { m_connection.send(); if (_obj->haveAsync() == true) { - addAsync(SendAsyncBinary(_obj->getTransactionId(), _obj->getClientId(), _obj->getServiceId(), std::move(_obj->moveAsync()))); + addAsync(SendAsyncBinary(_obj->getTransactionId(), _obj->getSource(), _obj->getDestination(), std::move(_obj->moveAsync()))); } return 1; } @@ -322,7 +322,7 @@ void zeus::WebServer::threadAsyncCallback() { zeus::FutureBase zeus::WebServer::callBinary(uint64_t _transactionId, ememory::SharedPtr _obj, - const uint32_t& _serviceId) { + const uint32_t& _destination) { if (isActive() == false) { ZEUS_ERROR("Send [STOP] ==> not connected (no TCP)"); ememory::SharedPtr obj = zeus::BufferAnswer::create(); @@ -337,8 +337,8 @@ zeus::FutureBase zeus::WebServer::callBinary(uint64_t _transactionId, writeBinary(_obj); return tmpFuture; } - -zeus::FutureBase zeus::WebServer::callForward(uint32_t _clientId, +/* +zeus::FutureBase zeus::WebServer::callForward(uint16_t _srcObjectId, ememory::SharedPtr _buffer, uint64_t _singleReferenceId) { //zeus::FutureBase ret = callBinary(id, _Buffer, async, _callback); @@ -351,7 +351,7 @@ zeus::FutureBase zeus::WebServer::callForward(uint32_t _clientId, } uint64_t id = getId(); _buffer->setTransactionId(id); - _buffer->setClientId(_clientId); + _buffer->setClientId(_srcObjectId); zeus::FutureBase tmpFuture(id); tmpFuture.setSynchronous(); { @@ -362,7 +362,7 @@ zeus::FutureBase zeus::WebServer::callForward(uint32_t _clientId, return tmpFuture; } -void zeus::WebServer::callForwardMultiple(uint32_t _clientId, +void zeus::WebServer::callForwardMultiple(uint16_t _srcObjectId, ememory::SharedPtr _buffer, uint64_t _singleReferenceId){ if (_buffer == nullptr) { @@ -375,47 +375,48 @@ void zeus::WebServer::callForwardMultiple(uint32_t _clientId, if (itCall.first == _singleReferenceId) { // Find element ==> transmit it ... _buffer->setTransactionId(itCall.second.getTransactionId()); - _buffer->setClientId(_clientId); + _buffer->setClientId(_srcObjectId); writeBinary(_buffer); return; } } ZEUS_ERROR("Can not transfer part of a message ..."); } +*/ -void zeus::WebServer::sendCtrl(uint32_t _clientId, uint32_t _serviceId, const std::string& _ctrlValue) { +void zeus::WebServer::sendCtrl(uint32_t _source, uint32_t _destination, const std::string& _ctrlValue) { auto ctrl = zeus::BufferCtrl::create(); if (ctrl == nullptr) { return; } ctrl->setTransactionId(getId()); - ctrl->setClientId(_clientId); - ctrl->setServiceId(_serviceId); + ctrl->setSource(_source); + ctrl->setDestination(_destination); ctrl->setCtrl(_ctrlValue); writeBinary(ctrl); } -void zeus::WebServer::answerError(uint64_t _clientTransactionId, uint32_t _clientId, uint32_t _serviceId, const std::string& _errorValue, const std::string& _errorHelp) { +void zeus::WebServer::answerError(uint32_t _clientTransactionId, uint32_t _source, uint32_t _destination, const std::string& _errorValue, const std::string& _errorHelp) { auto answer = zeus::BufferAnswer::create(); if (answer == nullptr) { return; } answer->setTransactionId(_clientTransactionId); - answer->setClientId(_clientId); - answer->setServiceId(_serviceId); + answer->setSource(_source); + answer->setDestination(_destination); answer->addError(_errorValue, _errorHelp); writeBinary(answer); } -void zeus::WebServer::answerVoid(uint64_t _clientTransactionId, uint32_t _clientId, uint32_t _serviceId) { +void zeus::WebServer::answerVoid(uint32_t _clientTransactionId, uint32_t _source, uint32_t _destination) { auto answer = zeus::BufferAnswer::create(); if (answer == nullptr) { return; } answer->setTransactionId(_clientTransactionId); - answer->setClientId(_clientId); - answer->setServiceId(_serviceId); + answer->setSource(_source); + answer->setDestination(_destination); answer->addParameter(); writeBinary(answer); } diff --git a/zeus/WebServer.hpp b/zeus/WebServer.hpp index 513ee35..0739a57 100644 --- a/zeus/WebServer.hpp +++ b/zeus/WebServer.hpp @@ -14,7 +14,12 @@ //#define ZEUS_NO_ID_CLIENT (0xFFFFFFFF) #define ZEUS_NO_ID_CLIENT (0x00000000) +#define ZEUS_NO_ID_OBJECT (0x00000000) #define ZEUS_ID_SERVICE_ROOT (0x00000000) +#define ZEUS_ID_GATEWAY (0x00000000) +#define ZEUS_ID_GATEWAY_OBJECT (0x0000) +#define ZEUS_GATEWAY_ADDRESS (0x00000000) + namespace zeus { /** @@ -22,7 +27,7 @@ namespace zeus { * @param[in] * @return */ - ememory::SharedPtr createBaseCall(uint64_t _transactionId, const uint32_t& _clientId, const uint32_t& _serviceId, const std::string& _functionName); + ememory::SharedPtr createBaseCall(uint64_t _transactionId, const uint32_t& _source, const uint32_t& _destination, const std::string& _functionName); /** * @brief * @param[in] @@ -64,8 +69,8 @@ namespace zeus { * @return */ template - ememory::SharedPtr createCall(uint64_t _transactionId, const uint32_t& _clientId, const uint32_t& _serviceId, const std::string& _functionName, _ARGS&&... _args) { - ememory::SharedPtr callElem = createBaseCall(_transactionId, _clientId, _serviceId, _functionName); + ememory::SharedPtr createCall(uint64_t _transactionId, const uint32_t& _source, const uint32_t& _destination, const std::string& _functionName, _ARGS&&... _args) { + ememory::SharedPtr callElem = createBaseCall(_transactionId, _source, _destination, _functionName); if (callElem == nullptr) { return nullptr; } @@ -253,18 +258,19 @@ namespace zeus { * @return */ template - zeus::FutureBase call(const uint32_t& _clientId, const uint32_t& _serviceId, const std::string& _functionName, _ARGS&&... _args) { + zeus::FutureBase call(const uint32_t& _source, const uint32_t& _destination, const std::string& _functionName, _ARGS&&... _args) { uint16_t id = getId(); - ememory::SharedPtr callElem = zeus::createCall(id, _clientId, _serviceId, _functionName, std::forward<_ARGS>(_args)...); + ememory::SharedPtr callElem = zeus::createCall(id, _source, _destination, _functionName, std::forward<_ARGS>(_args)...); return callBinary(id, callElem); } public: + #if 0 /** * @brief * @param[in] * @return */ - zeus::FutureBase callForward(uint32_t _clientId, + zeus::FutureBase callForward(uint32_t _source, ememory::SharedPtr _Buffer, uint64_t _singleReferenceId); /** @@ -272,9 +278,10 @@ namespace zeus { * @param[in] * @return */ - void callForwardMultiple(uint32_t _clientId, + void callForwardMultiple(uint32_t _source, ememory::SharedPtr _Buffer, uint64_t _singleReferenceId); + #endif public: // answers ... /** * @brief @@ -287,38 +294,39 @@ namespace zeus { * @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 + * @param[in] _srcObjectId Client to send control */ template - void answerValue(uint64_t _clientTransactionId, uint32_t _clientId, uint32_t _serviceId, ZEUS_ARG _value) { + void answerValue(uint32_t _clientTransactionId, uint32_t _source, uint32_t _destination, ZEUS_ARG _value) { ememory::SharedPtr answer = zeus::BufferAnswer::create(); answer->setTransactionId(_clientTransactionId); - answer->setClientId(_clientId); + answer->setSource(_source); + answer->setDestination(_destination); answer->addAnswer(_value); writeBinary(answer); } /** * @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 + * @param[in] _srcObjectId Client to send control */ - void answerVoid(uint64_t _clientTransactionId, uint32_t _clientId, uint32_t _serviceId); + void answerVoid(uint32_t _clientTransactionId, uint32_t _source, uint32_t _destination); /** * @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 + * @param[in] _srcObjectId Client to send control */ - void answerError(uint64_t _clientTransactionId, uint32_t _clientId, uint32_t _serviceId, const std::string& _errorValue, const std::string& _errorComment=""); + void answerError(uint32_t _clientTransactionId, uint32_t _source, uint32_t _destination, const std::string& _errorValue, const std::string& _errorComment=""); /** * @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 + * @param[in] _source Source of the message + * @param[in] _destination Destination of the message + * @param[in] _ctrlValue Control to send * @return */ - void sendCtrl(uint32_t _clientId, uint32_t _serviceId, const std::string& _ctrlValue); + void sendCtrl(uint32_t _source, uint32_t _destination, const std::string& _ctrlValue); }; }