From 040eaf491f986b565fa497d1d03b07fdef41357a Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Mon, 21 Nov 2016 22:15:46 +0100 Subject: [PATCH] [DEV] update interface with a double gateway to permit to have a dockerisation of user service --- lutinParseSubFolders.txt | 3 +- tools/architecture.txt | 70 ++++++ .../appl/ClientGateWayInterface.cpp} | 203 +++++++++--------- .../appl/ClientGateWayInterface.hpp | 53 +++++ tools/gateway-back-end/appl/GateWay.cpp | 196 +++++++++++++++++ .../appl/GateWay.hpp | 14 +- .../appl/ServiceInterface.cpp | 22 +- .../appl/ServiceInterface.hpp | 4 +- .../appl/debug.cpp | 0 .../appl/debug.hpp | 0 .../appl/main.cpp | 20 +- .../lutin_zeus-gateway-back-end.py} | 2 +- .../appl/ClientInterface.cpp | 148 +++++++++++++ .../appl/ClientInterface.hpp | 9 +- .../appl/GateWay.cpp | 47 ++-- tools/gateway-front-end/appl/GateWay.hpp | 54 +++++ .../appl/GateWayInterface.cpp | 132 ++++++++++++ .../appl/GateWayInterface.hpp | 37 ++++ tools/gateway-front-end/appl/debug.cpp | 12 ++ tools/gateway-front-end/appl/debug.hpp | 40 ++++ tools/gateway-front-end/appl/main.cpp | 59 +++++ .../lutin_zeus-gateway-front-end.py | 40 ++++ tools/player-video/appl/MediaDecoder.cpp | 2 +- zeus/Client.cpp | 8 +- zeus/WebServer.cpp | 11 +- zeus/WebServer.hpp | 22 +- 26 files changed, 1039 insertions(+), 169 deletions(-) create mode 100644 tools/architecture.txt rename tools/{gateway/appl/ClientInterface.cpp => gateway-back-end/appl/ClientGateWayInterface.cpp} (57%) create mode 100644 tools/gateway-back-end/appl/ClientGateWayInterface.hpp create mode 100644 tools/gateway-back-end/appl/GateWay.cpp rename tools/{gateway => gateway-back-end}/appl/GateWay.hpp (72%) rename tools/{gateway => gateway-back-end}/appl/ServiceInterface.cpp (85%) rename tools/{gateway => gateway-back-end}/appl/ServiceInterface.hpp (91%) rename tools/{gateway => gateway-back-end}/appl/debug.cpp (100%) rename tools/{gateway => gateway-back-end}/appl/debug.hpp (100%) rename tools/{gateway => gateway-back-end}/appl/main.cpp (71%) rename tools/{gateway/lutin_zeus-gateway.py => gateway-back-end/lutin_zeus-gateway-back-end.py} (94%) create mode 100644 tools/gateway-front-end/appl/ClientInterface.cpp rename tools/{gateway => gateway-front-end}/appl/ClientInterface.hpp (81%) rename tools/{gateway => gateway-front-end}/appl/GateWay.cpp (71%) create mode 100644 tools/gateway-front-end/appl/GateWay.hpp create mode 100644 tools/gateway-front-end/appl/GateWayInterface.cpp create mode 100644 tools/gateway-front-end/appl/GateWayInterface.hpp create mode 100644 tools/gateway-front-end/appl/debug.cpp create mode 100644 tools/gateway-front-end/appl/debug.hpp create mode 100644 tools/gateway-front-end/appl/main.cpp create mode 100644 tools/gateway-front-end/lutin_zeus-gateway-front-end.py diff --git a/lutinParseSubFolders.txt b/lutinParseSubFolders.txt index 274841d..7cc8c57 100644 --- a/lutinParseSubFolders.txt +++ b/lutinParseSubFolders.txt @@ -1,5 +1,6 @@ +tools/gateway-front-end +tools/gateway-back-end tools/service-user -tools/gateway tools/service-picture tools/service-video tools/player-video diff --git a/tools/architecture.txt b/tools/architecture.txt new file mode 100644 index 0000000..5b31e82 --- /dev/null +++ b/tools/architecture.txt @@ -0,0 +1,70 @@ + + + + *----------------------------------------------------------------------------* + | Docker / single binary Single User specufic program/environement | + | | + | *-----------------------* | + | +--------->| service-right-manager | | + | *-------------* | *-----------------------* | + | | |<-+ | + | | | *-----------------------* | +-------------------+ + | | GATEWAY |<----------->| service-picture | | | | + +---------->| | *-----------------------* |<===>| USER X data | + | | | Back-end |<------+ | | | + | | | | | *-----------------------* | +-------------------+ + | | | |<--+ +---->| service-video | | +-----------* | | | | | *-----------------------* | + | | | *-------------* | | + | | | | *-----------------------* | + | *-------------* | | +-------->| service-XXX | | + |<----* | | | | *-----------------------* | + | | | | | | | + |<----| | GATEWAY |<---+ *----------------------------------------------------------------------------* +Internet | | | | + |<----*===>|80 | + | | | | + |<----| | Front-end |<---+ *----------------------------------------------------------------------------* + | | | | | | Docker / single binary Single User specufic program/environement | + |<----* | | | | | + | *-------------* | | *-----------------------* | + | || | | +--------->| service-right-manager | | + | *----------* | | *-------------* | *-----------------------* | +-----------* | List | | | | |<-+ | +-------------------+ + | of | | | | | *-----------------------* | | | + | user | | | | GATEWAY |<----------->| service-picture | |<===>| USER Y data | + |availlable| +---------->| | *-----------------------* | | | + *----------* | | Back-end |<------+ | +-------------------+ + | | | | *-----------------------* | + | | |<--+ +---->| service-video | | + | | | | *-----------------------* | + | *-------------* | | + | | *-----------------------* | + | +-------->| service-XXX | | + | *-----------------------* | + | | + *----------------------------------------------------------------------------* + + + +This is the first acces node of the service engine ==> it redirect the user to the correct gateway IP address + +-----------* + | + | + | *-------------* + |<----* | | + | | | | +-------------------------+ + |<----| | GATEWAY | | | +Internet | | | | | List of user | + |<----*===>| |<---->| associated gateway | + | | | | | address | + |<----| | Addressor | | | + | | | | +-------------------------+ + |<----* | | + | *-------------* + | + | +-----------* + + diff --git a/tools/gateway/appl/ClientInterface.cpp b/tools/gateway-back-end/appl/ClientGateWayInterface.cpp similarity index 57% rename from tools/gateway/appl/ClientInterface.cpp rename to tools/gateway-back-end/appl/ClientGateWayInterface.cpp index 0f4666a..d54707a 100644 --- a/tools/gateway/appl/ClientInterface.cpp +++ b/tools/gateway-back-end/appl/ClientGateWayInterface.cpp @@ -5,9 +5,10 @@ */ #include -#include +#include #include #include +#include #include @@ -15,33 +16,60 @@ static const std::string protocolError = "PROTOCOL-ERROR"; -appl::ClientInterface::ClientInterface(enet::Tcp _connection, appl::GateWay* _gatewayInterface) : - m_state(appl::ClientInterface::state::unconnect), +appl::ClientGateWayInterface::ClientGateWayInterface(const std::string& _ip, uint16_t _port, const std::string& _userName, appl::GateWay* _gatewayInterface) : + m_state(appl::ClientGateWayInterface::state::unconnect), m_gatewayInterface(_gatewayInterface), - m_interfaceClient(std::move(_connection), true) { - ZEUS_INFO("----------------"); - ZEUS_INFO("-- NEW Client --"); - ZEUS_INFO("----------------"); + m_interfaceGateWayClient() { + APPL_INFO("----------------------------------------"); + APPL_INFO("-- NEW Connection to GateWay Font-end --"); + APPL_INFO("----------------------------------------"); + enet::Tcp connection = std::move(enet::connectTcpClient(_ip, _port)); + if (connection.getConnectionStatus() != enet::Tcp::status::link) { + APPL_ERROR("Can not connect the GateWay-front-end"); + return; + } + m_interfaceGateWayClient.setInterface(std::move(connection), false, _userName); + m_userConnectionName = _userName; + m_state = appl::ClientGateWayInterface::state::connect; + m_interfaceGateWayClient.connect(this, &appl::ClientGateWayInterface::onClientData); + m_interfaceGateWayClient.connect(true); + m_interfaceGateWayClient.setInterfaceName("cli-" + etk::to_string(m_uid)); } -appl::ClientInterface::~ClientInterface() { - ZEUS_TODO("Call All unlink ..."); +appl::ClientGateWayInterface::~ClientGateWayInterface() { + APPL_TODO("Call All unlink ..."); stop(); - ZEUS_INFO("-------------------"); - ZEUS_INFO("-- DELETE Client --"); - ZEUS_INFO("-------------------"); + APPL_INFO("-------------------------------------------"); + APPL_INFO("-- DELETE Connection to GateWay Font-end --"); + APPL_INFO("-------------------------------------------"); } -void appl::ClientInterface::start(uint64_t _uid, uint64_t _uid2) { +void appl::ClientGateWayInterface::start(uint64_t _uid, uint64_t _uid2) { m_uid = _uid; m_uid2 = _uid2; - m_state = appl::ClientInterface::state::connect; - m_interfaceClient.connect(this, &appl::ClientInterface::onClientData); - m_interfaceClient.connect(true); - m_interfaceClient.setInterfaceName("cli-" + etk::to_string(m_uid)); + m_state = appl::ClientGateWayInterface::state::connect; + m_interfaceGateWayClient.setInterfaceName("cli-" + etk::to_string(m_uid)); + + APPL_WARNING("[" << m_uid << "] Connect to the user service"); + m_userService = m_gatewayInterface->get("user"); + if (m_userService == nullptr) { + //answerProtocolError(transactionId, "Gateway internal error 'No user interface'"); + // TODO: Can not work at all ==> or create a fallback mode ... + } + /* + else { + zeus::Future futLocalService = m_userService->m_interfaceClient.callClient(m_uid2, "_new", m_userConnectionName, "**Gateway**", std::vector()); + futLocalService.wait(); // TODO: Set timeout ... + m_interfaceGateWayClient.answerValue(transactionId, true); + } + APPL_WARNING("[" << m_uid << "] Client must send conection to user name ..."); + answerProtocolError(transactionId, "Missing call of connectToUser"); + return; + } + */ } -void appl::ClientInterface::stop() { +void appl::ClientGateWayInterface::stop() { for (auto &it : m_listConnectedService) { if (it == nullptr) { continue; @@ -53,33 +81,34 @@ void appl::ClientInterface::stop() { m_userService = nullptr; } m_listConnectedService.clear(); - m_interfaceClient.disconnect(); + m_interfaceGateWayClient.disconnect(); } -bool appl::ClientInterface::isAlive() { - return m_interfaceClient.isActive(); +bool appl::ClientGateWayInterface::isAlive() { + return m_interfaceGateWayClient.isActive(); } -void appl::ClientInterface::answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp) { - m_interfaceClient.answerError(_transactionId, protocolError, _errorHelp); - m_state = appl::ClientInterface::state::disconnect; - m_interfaceClient.disconnect(true); +void appl::ClientGateWayInterface::answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp) { + m_interfaceGateWayClient.answerError(_transactionId, protocolError, _errorHelp); + m_state = appl::ClientGateWayInterface::state::disconnect; + m_interfaceGateWayClient.disconnect(true); } -void appl::ClientInterface::onClientData(ememory::SharedPtr _value) { +void appl::ClientGateWayInterface::onClientData(ememory::SharedPtr _value) { if (_value == nullptr) { return; } + APPL_ERROR("get message from front-end gateWay: " << _value); uint32_t transactionId = _value->getTransactionId(); if (transactionId == 0) { - ZEUS_ERROR("Protocol error ==>missing id"); + APPL_ERROR("Protocol error ==>missing id"); answerProtocolError(transactionId, "missing parameter: 'id'"); return; } if (_value->getType() == zeus::Buffer::typeMessage::data) { // TRANSMIT DATA ... - if (m_state != appl::ClientInterface::state::clientIdentify) { + if (m_state != appl::ClientGateWayInterface::state::clientIdentify) { answerProtocolError(transactionId, "Not identify to send 'data' buffer (multiple packet element)"); return; } @@ -90,12 +119,12 @@ void appl::ClientInterface::onClientData(ememory::SharedPtr _value } serviceId--; if (serviceId >= m_listConnectedService.size()) { - m_interfaceClient.answerError(transactionId, "NOT-CONNECTED-SERVICE"); + m_interfaceGateWayClient.answerError(transactionId, "NOT-CONNECTED-SERVICE"); return; } if (m_listConnectedService[serviceId] == nullptr) { // TODO ... - ZEUS_ERROR("TODO : Manage this case ..."); + APPL_ERROR("TODO : Manage this case ..."); return; } m_listConnectedService[serviceId]->m_interfaceClient.callForwardMultiple( @@ -105,49 +134,21 @@ void appl::ClientInterface::onClientData(ememory::SharedPtr _value return; } if (_value->getType() != zeus::Buffer::typeMessage::call) { - ZEUS_ERROR("Protocol error ==>missing '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::ClientInterface::state::disconnect: - case appl::ClientInterface::state::unconnect: + case appl::ClientGateWayInterface::state::disconnect: + case appl::ClientGateWayInterface::state::unconnect: { - ZEUS_ERROR("Must never appear"); + APPL_ERROR("Must never appear"); answerProtocolError(transactionId, "Gateway internal error"); return; } - case appl::ClientInterface::state::connect: - { - if (m_userConnectionName != "") { - answerProtocolError(transactionId, "Gateway internal error 2"); - return; - } - if (callFunction == "connectToUser") { - m_userConnectionName = callObj->getParameter(0); - if (m_userConnectionName == "") { - answerProtocolError(transactionId, "Call connectToUser with no parameter 'user'"); - } else { - ZEUS_WARNING("[" << m_uid << "] Set client connect to user : '" << m_userConnectionName << "'"); - m_userService = m_gatewayInterface->get("system-user"); - if (m_userService == nullptr) { - answerProtocolError(transactionId, "Gateway internal error 'No user interface'"); - } else { - zeus::Future futLocalService = m_userService->m_interfaceClient.callClient(m_uid2, "_new", m_userConnectionName, "**Gateway**", std::vector()); - futLocalService.wait(); // TODO: Set timeout ... - m_state = appl::ClientInterface::state::userIdentify; - m_interfaceClient.answerValue(transactionId, true); - } - } - return; - } - ZEUS_WARNING("[" << m_uid << "] Client must send conection to user name ..."); - answerProtocolError(transactionId, "Missing call of connectToUser"); - return; - } - case appl::ClientInterface::state::userIdentify: + case appl::ClientGateWayInterface::state::connect: { m_clientServices.clear(); m_clientgroups.clear(); @@ -169,12 +170,12 @@ void appl::ClientInterface::onClientData(ememory::SharedPtr _value zeus::Future fut = m_userService->m_interfaceClient.callClient(m_uid2, "checkTocken", clientName, clientTocken); fut.wait(); // TODO: Set timeout ... if (fut.hasError() == true) { - ZEUS_ERROR("Get error from the service ..."); - m_interfaceClient.answerValue(transactionId, false); + APPL_ERROR("Get error from the service ..."); + m_interfaceGateWayClient.answerValue(transactionId, false); answerProtocolError(transactionId, "connection refused 1"); return; } else if (fut.get() == false) { - m_interfaceClient.answerValue(transactionId, false); + m_interfaceGateWayClient.answerValue(transactionId, false); answerProtocolError(transactionId, "connection refused 2"); return; } @@ -185,12 +186,12 @@ void appl::ClientInterface::onClientData(ememory::SharedPtr _value zeus::Future fut = m_userService->m_interfaceClient.callClient(m_uid2, "checkAuth", password); fut.wait(); // TODO: Set timeout ... if (fut.hasError() == true) { - ZEUS_ERROR("Get error from the service ..."); - m_interfaceClient.answerValue(transactionId, false); + APPL_ERROR("Get error from the service ..."); + m_interfaceGateWayClient.answerValue(transactionId, false); answerProtocolError(transactionId, "connection refused 1"); return; } else if (fut.get() == false) { - m_interfaceClient.answerValue(transactionId, false); + m_interfaceGateWayClient.answerValue(transactionId, false); answerProtocolError(transactionId, "connection refused 2"); return; } @@ -205,8 +206,8 @@ void appl::ClientInterface::onClientData(ememory::SharedPtr _value zeus::Future> futGroup = m_userService->m_interfaceClient.callClient(m_uid2, "getGroups", m_clientName); futGroup.wait(); // TODO: Set timeout ... if (futGroup.hasError() == true) { - ZEUS_ERROR("Get error from the service ..."); - m_interfaceClient.answerValue(transactionId, false); + APPL_ERROR("Get error from the service ..."); + m_interfaceGateWayClient.answerValue(transactionId, false); answerProtocolError(transactionId, "grouping error"); return; } @@ -218,33 +219,33 @@ void appl::ClientInterface::onClientData(ememory::SharedPtr _value zeus::Future> futServices = m_userService->m_interfaceClient.callClient(m_uid2, "filterServices", m_clientName, currentServices); futServices.wait(); // TODO: Set timeout ... if (futServices.hasError() == true) { - ZEUS_ERROR("Get error from the service ..."); - m_interfaceClient.answerValue(transactionId, false); + APPL_ERROR("Get error from the service ..."); + m_interfaceGateWayClient.answerValue(transactionId, false); answerProtocolError(transactionId, "service filtering error"); return; } m_clientServices = futServices.get(); - ZEUS_WARNING("Connection of: '" << m_clientName << "' to '" << m_userConnectionName << "'"); - ZEUS_WARNING(" groups: " << etk::to_string(m_clientgroups)); - ZEUS_WARNING(" services: " << etk::to_string(m_clientServices)); + 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)); - m_interfaceClient.answerValue(transactionId, true); - m_state = appl::ClientInterface::state::clientIdentify; + m_interfaceGateWayClient.answerValue(transactionId, true); + m_state = appl::ClientGateWayInterface::state::clientIdentify; return; } break; - case appl::ClientInterface::state::clientIdentify: + case appl::ClientGateWayInterface::state::clientIdentify: { uint32_t serviceId = callObj->getServiceId(); if (serviceId == 0) { // This is 2 default service for the cient interface that manage the authorisation of view: if (callFunction == "getServiceCount") { - m_interfaceClient.answerValue(transactionId, m_clientServices.size()); + m_interfaceGateWayClient.answerValue(transactionId, m_clientServices.size()); return; } if (callFunction == "getServiceList") { - m_interfaceClient.answerValue(transactionId, m_clientServices); + m_interfaceGateWayClient.answerValue(transactionId, m_clientServices); //"ServiceManager/v0.1.0" return; } @@ -267,7 +268,7 @@ void appl::ClientInterface::onClientData(ememory::SharedPtr _value if (it == m_listConnectedService.end()) { // check if service is connectable ... if (std::find(m_clientServices.begin(), m_clientServices.end(), serviceName) == m_clientServices.end()) { - m_interfaceClient.answerError(transactionId, "UN-AUTHORIZED-SERVICE"); + m_interfaceGateWayClient.answerError(transactionId, "UN-AUTHORIZED-SERVICE"); return; } ememory::SharedPtr srv = m_gatewayInterface->get(serviceName); @@ -275,18 +276,18 @@ void appl::ClientInterface::onClientData(ememory::SharedPtr _value zeus::Future futLink = srv->m_interfaceClient.callClient(m_uid, "_new", m_userConnectionName, m_clientName, m_clientgroups); futLink.wait(); // TODO: Set timeout ... if (futLink.hasError() == true) { - ZEUS_ERROR("Get error from the service ... LINK"); - m_interfaceClient.answerError(transactionId, "ERROR-CREATE-SERVICE-INSTANCE"); + APPL_ERROR("Get error from the service ... LINK"); + m_interfaceGateWayClient.answerError(transactionId, "ERROR-CREATE-SERVICE-INSTANCE"); return; } m_listConnectedService.push_back(srv); - m_interfaceClient.answerValue(transactionId, m_listConnectedService.size()); + m_interfaceGateWayClient.answerValue(transactionId, m_listConnectedService.size()); return; } - m_interfaceClient.answerError(transactionId, "CAN-NOT-CONNECT-SERVICE"); + m_interfaceGateWayClient.answerError(transactionId, "CAN-NOT-CONNECT-SERVICE"); return; } - m_interfaceClient.answerError(transactionId, "SERVICE-ALREADY-CONNECTED");; + m_interfaceGateWayClient.answerError(transactionId, "SERVICE-ALREADY-CONNECTED");; return; } if (callFunction == "unlink") { @@ -294,33 +295,33 @@ void appl::ClientInterface::onClientData(ememory::SharedPtr _value int64_t localServiceID = callObj->getParameter(0)-1; // Check if service already link: if (localServiceID >= m_listConnectedService.size()) { - m_interfaceClient.answerError(transactionId, "NOT-CONNECTED-SERVICE"); + m_interfaceGateWayClient.answerError(transactionId, "NOT-CONNECTED-SERVICE"); return; } zeus::Future futUnLink = m_listConnectedService[localServiceID]->m_interfaceClient.callClient(m_uid, "_delete"); futUnLink.wait(); // TODO: Set timeout ... if (futUnLink.hasError() == true) { - ZEUS_ERROR("Get error from the service ... UNLINK"); - m_interfaceClient.answerError(transactionId, "ERROR-CREATE-SERVICE-INSTANCE"); + APPL_ERROR("Get error from the service ... UNLINK"); + m_interfaceGateWayClient.answerError(transactionId, "ERROR-CREATE-SERVICE-INSTANCE"); return; } m_listConnectedService[localServiceID] = nullptr; - m_interfaceClient.answerValue(transactionId, true); + m_interfaceGateWayClient.answerValue(transactionId, true); return; } - ZEUS_ERROR("Function does not exist ... '" << callFunction << "'"); - m_interfaceClient.answerError(transactionId, "CALL-UNEXISTING"); + APPL_ERROR("Function does not exist ... '" << callFunction << "'"); + m_interfaceGateWayClient.answerError(transactionId, "CALL-UNEXISTING"); return; } // decrease service ID ... serviceId -= 1; if (serviceId >= m_listConnectedService.size()) { - m_interfaceClient.answerError(transactionId, "NOT-CONNECTED-SERVICE"); + m_interfaceGateWayClient.answerError(transactionId, "NOT-CONNECTED-SERVICE"); return; } else { if (m_listConnectedService[serviceId] == nullptr) { // TODO ... - ZEUS_ERROR("TODO : Manage this case ..."); + APPL_ERROR("TODO : Manage this case ..."); return; } m_listConnectedService[serviceId]->m_interfaceClient.callForward( @@ -332,12 +333,12 @@ void appl::ClientInterface::onClientData(ememory::SharedPtr _value if (tmpp == nullptr) { return true; } - ZEUS_DEBUG(" ==> transmit : " << tmpp->getTransactionId() << " -> " << transactionId); - ZEUS_DEBUG(" msg=" << tmpp); + APPL_DEBUG(" ==> transmit : " << tmpp->getTransactionId() << " -> " << transactionId); + APPL_DEBUG(" msg=" << tmpp); tmpp->setTransactionId(transactionId); tmpp->setServiceId(serviceId+1); - ZEUS_DEBUG("transmit=" << tmpp); - m_interfaceClient.writeBinary(tmpp); + APPL_DEBUG("transmit=" << tmpp); + m_interfaceGateWayClient.writeBinary(tmpp); // multiple send element ... return tmpp->getPartFinish(); }); @@ -346,6 +347,6 @@ void appl::ClientInterface::onClientData(ememory::SharedPtr _value } } -void appl::ClientInterface::returnMessage(ememory::SharedPtr _data) { - ZEUS_ERROR("Get call from the Service to the user ..."); +void appl::ClientGateWayInterface::returnMessage(ememory::SharedPtr _data) { + APPL_ERROR("Get call from the Service to the user ..."); } \ No newline at end of file diff --git a/tools/gateway-back-end/appl/ClientGateWayInterface.hpp b/tools/gateway-back-end/appl/ClientGateWayInterface.hpp new file mode 100644 index 0000000..c33b00e --- /dev/null +++ b/tools/gateway-back-end/appl/ClientGateWayInterface.hpp @@ -0,0 +1,53 @@ +/** @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 ClientGateWayInterface { + private: + enum class state { + unconnect, // starting sate + connect, // zeust get a TCP connection + clientIdentify, // client defien the mode of the acces (anonymous,client/user) + disconnect // client is dead or loal disconnection + }; + enum state m_state; // state machine ... + private: + appl::GateWay* m_gatewayInterface; + zeus::WebServer m_interfaceGateWayClient; + public: + ememory::SharedPtr m_userService; + std::vector> m_listConnectedService; + uint64_t m_uid; + uint64_t m_uid2; + std::string m_userConnectionName; + std::string m_clientName; + std::vector m_clientgroups; + std::vector m_clientServices; + public: + ClientGateWayInterface(const std::string& _ip, uint16_t _port, const std::string& _userName, appl::GateWay* _gatewayInterface); + virtual ~ClientGateWayInterface(); + void start(uint64_t _uid, uint64_t _uid2); + void stop(); + void onClientData(ememory::SharedPtr _value); + void returnMessage(ememory::SharedPtr _data); + bool checkId(uint64_t _id) const { + return m_uid == _id + || m_uid2 == _id; + } + bool isAlive(); + + void answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp); + + + }; +} + diff --git a/tools/gateway-back-end/appl/GateWay.cpp b/tools/gateway-back-end/appl/GateWay.cpp new file mode 100644 index 0000000..c498ccf --- /dev/null +++ b/tools/gateway-back-end/appl/GateWay.cpp @@ -0,0 +1,196 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2016, Edouard DUPIN, all right reserved + * @license APACHE v2.0 (see license file) + */ + +#include +#include +#include + + +namespace appl { + class TcpServerInput { + private: + enet::TcpServer m_interface; + std::thread* m_thread; + bool m_threadRunning; + appl::GateWay* m_gateway; + public: + TcpServerInput(appl::GateWay* _gateway) : + m_thread(nullptr), + m_threadRunning(false), + m_gateway(_gateway) { + + } + virtual ~TcpServerInput() {} + void start(const std::string& _host, uint16_t _port) { + m_interface.setHostNane(_host); + m_interface.setPort(_port); + m_interface.link(); + m_threadRunning = true; + m_thread = new std::thread([&](void *){ this->threadCallback();}, nullptr); + if (m_thread == nullptr) { + m_threadRunning = false; + APPL_ERROR("creating callback thread!"); + return; + } + } + void stop() { + if (m_thread != nullptr) { + m_threadRunning = false; + } + m_interface.unlink(); + if (m_thread != nullptr) { + m_thread->join(); + delete m_thread; + m_thread = nullptr; + } + } + void threadCallback() { + // get datas: + while (m_threadRunning == true) { + // READ section data: + enet::Tcp data = std::move(m_interface.waitNext()); + APPL_VERBOSE("New connection"); + m_gateway->newService(std::move(data)); + } + } + }; +} + +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); +} + +appl::GateWay::GateWay() : + m_clientUID(1), + propertyUserName(this, "user", "no-name", "User name of the interface"), // must be set befor start ... + propertyGateWayClientIp(this, "gw-ip", "127.0.0.1", "Ip to listen client", &appl::GateWay::onPropertyChangeClientIp), + propertyGateWayClientPort(this, "gw-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) { + m_interfaceServiceServer = ememory::makeShared(this); +} + +appl::GateWay::~GateWay() { + +} + +void appl::GateWay::start() { + m_gateWayClient = ememory::makeShared(*propertyGateWayClientIp, *propertyGateWayClientPort, *propertyUserName, this); + m_interfaceServiceServer->start(*propertyServiceIp, *propertyServicePort); +} + +void appl::GateWay::stop() { + m_gateWayClient.reset(); + +} + +ememory::SharedPtr appl::GateWay::get(const std::string& _serviceName) { + for (auto &it : m_serviceList) { + if (it == nullptr) { + continue; + } + if (it->getName() != _serviceName) { + continue; + } + return it; + } + return nullptr; +} + +std::vector appl::GateWay::getAllServiceName() { + std::vector out; + 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) { + /* + for (auto &it : m_gateWayClient) { + if (it == nullptr) { + continue; + } + if (it->checkId(_userSessionId) == false) { + continue; + } + it->returnMessage(_data); + return; + } + */ +} + +void appl::GateWay::cleanIO() { + + auto it = m_serviceList.begin(); + while (it != m_serviceList.end()) { + if (*it != nullptr) { + if ((*it)->isAlive() == false) { + it = m_serviceList.erase(it); + continue; + } + } else { + it = m_serviceList.erase(it); + continue; + } + ++it; + } + /* + auto it2 = m_gateWayClient.begin(); + while (it2 != m_gateWayClient.end()) { + if (*it2 != nullptr) { + if ((*it2)->isAlive() == false) { + it2 = m_gateWayClient.erase(it2); + continue; + } + } else { + it2 = m_gateWayClient.erase(it2); + continue; + } + ++it2; + } + */ +} + +void appl::GateWay::onClientConnect(const bool& _value) { + APPL_TODO("Client connection: " << _value); +} + +void appl::GateWay::onServiceConnect(const bool& _value) { + APPL_TODO("Service connection: " << _value); +} + +void appl::GateWay::onPropertyChangeClientIp() { + +} + +void appl::GateWay::onPropertyChangeClientPort() { + +} + +void appl::GateWay::onPropertyChangeClientMax() { + +} + +void appl::GateWay::onPropertyChangeServiceIp() { + +} + +void appl::GateWay::onPropertyChangeServicePort() { + +} + +void appl::GateWay::onPropertyChangeServiceMax() { + +} diff --git a/tools/gateway/appl/GateWay.hpp b/tools/gateway-back-end/appl/GateWay.hpp similarity index 72% rename from tools/gateway/appl/GateWay.hpp rename to tools/gateway-back-end/appl/GateWay.hpp index cbf576d..1ae4b72 100644 --- a/tools/gateway/appl/GateWay.hpp +++ b/tools/gateway-back-end/appl/GateWay.hpp @@ -5,7 +5,7 @@ */ #pragma once #include -#include +#include #include namespace appl { @@ -15,14 +15,13 @@ namespace appl { uint64_t m_clientUID; private: std::vector> m_serviceList; //!< List of all service availlable with their specific connection interface - std::vector> m_clientList; //!< List of all Client interface with their own connection - //TODO: std::vector m_ServerList; //!< List of all Server connected to this gateway - ememory::SharedPtr m_interfaceClientServer; + ememory::SharedPtr m_gateWayClient; //!< Interface with the Gateway Front End + ememory::SharedPtr m_interfaceServiceServer; public: - eproperty::Value propertyClientIp; - eproperty::Value propertyClientPort; - eproperty::Value propertyClientMax; + eproperty::Value propertyUserName; + eproperty::Value propertyGateWayClientIp; + eproperty::Value propertyGateWayClientPort; eproperty::Value propertyServiceIp; eproperty::Value propertyServicePort; eproperty::Value propertyServiceMax; @@ -35,7 +34,6 @@ namespace appl { std::vector getAllServiceName(); void answer(uint64_t _userSessionId, const ememory::SharedPtr& _data); void newService(enet::Tcp _connection); - void newClient(enet::Tcp _connection); void cleanIO(); private: void onPropertyChangeClientIp(); diff --git a/tools/gateway/appl/ServiceInterface.cpp b/tools/gateway-back-end/appl/ServiceInterface.cpp similarity index 85% rename from tools/gateway/appl/ServiceInterface.cpp rename to tools/gateway-back-end/appl/ServiceInterface.cpp index 312e6b1..24c23b2 100644 --- a/tools/gateway/appl/ServiceInterface.cpp +++ b/tools/gateway-back-end/appl/ServiceInterface.cpp @@ -6,7 +6,7 @@ #include #include -#include +#include #include // todo : cHANGE THIS ... @@ -17,16 +17,16 @@ static const std::string protocolError = "PROTOCOL-ERROR"; appl::ServiceInterface::ServiceInterface(enet::Tcp _connection, appl::GateWay* _gatewayInterface) : m_gatewayInterface(_gatewayInterface), m_interfaceClient(std::move(_connection), true) { - ZEUS_INFO("-----------------"); - ZEUS_INFO("-- NEW Service --"); - ZEUS_INFO("-----------------"); + APPL_INFO("-----------------"); + APPL_INFO("-- NEW Service --"); + APPL_INFO("-----------------"); } appl::ServiceInterface::~ServiceInterface() { - ZEUS_INFO("--------------------"); - ZEUS_INFO("-- DELETE Service --"); - ZEUS_INFO("--------------------"); + APPL_INFO("--------------------"); + APPL_INFO("-- DELETE Service --"); + APPL_INFO("--------------------"); } bool appl::ServiceInterface::isAlive() { @@ -60,14 +60,14 @@ void appl::ServiceInterface::onServiceData(ememory::SharedPtr _val if (data.valueExist("event") == true) { // No need to have a user ID ... if (data["event"].toString().get() == "IS-ALIVE") { - ZEUS_VERBOSE("Service Alive ..."); + APPL_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); } } else { - ZEUS_INFO("Unknow service event: '" << data["event"].toString().get() << "'"); + APPL_INFO("Unknow service event: '" << data["event"].toString().get() << "'"); } return; } @@ -79,7 +79,7 @@ void appl::ServiceInterface::onServiceData(ememory::SharedPtr _val 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)); + APPL_WARNING("Service interface ==> try change the servie name after init: '" << callObj->getParameter(0)); m_interfaceClient.answerValue(transactionId, false); return; } @@ -91,7 +91,7 @@ void appl::ServiceInterface::onServiceData(ememory::SharedPtr _val answerProtocolError(transactionId, "unknow function"); } if (_value->getClientId() == 0) { - ZEUS_ERROR("Service interface ==> wrong service answer ==> missing 'client-id'"); + APPL_ERROR("Service interface ==> wrong service answer ==> missing 'client-id'"); return; } m_gatewayInterface->answer(_value->getClientId(), _value); diff --git a/tools/gateway/appl/ServiceInterface.hpp b/tools/gateway-back-end/appl/ServiceInterface.hpp similarity index 91% rename from tools/gateway/appl/ServiceInterface.hpp rename to tools/gateway-back-end/appl/ServiceInterface.hpp index fdc5b0c..66ae2d4 100644 --- a/tools/gateway/appl/ServiceInterface.hpp +++ b/tools/gateway-back-end/appl/ServiceInterface.hpp @@ -10,9 +10,9 @@ namespace appl { class GateWay; - class ClientInterface; + class ClientGateWayInterface; class ServiceInterface { - friend class appl::ClientInterface; + friend class appl::ClientGateWayInterface; private: appl::GateWay* m_gatewayInterface; zeus::WebServer m_interfaceClient; diff --git a/tools/gateway/appl/debug.cpp b/tools/gateway-back-end/appl/debug.cpp similarity index 100% rename from tools/gateway/appl/debug.cpp rename to tools/gateway-back-end/appl/debug.cpp diff --git a/tools/gateway/appl/debug.hpp b/tools/gateway-back-end/appl/debug.hpp similarity index 100% rename from tools/gateway/appl/debug.hpp rename to tools/gateway-back-end/appl/debug.hpp diff --git a/tools/gateway/appl/main.cpp b/tools/gateway-back-end/appl/main.cpp similarity index 71% rename from tools/gateway/appl/main.cpp rename to tools/gateway-back-end/appl/main.cpp index 6901e52..82d6209 100644 --- a/tools/gateway/appl/main.cpp +++ b/tools/gateway-back-end/appl/main.cpp @@ -18,12 +18,12 @@ int main(int _argc, const char *_argv[]) { appl::GateWay basicGateway; for (int32_t iii=0; iii<_argc ; ++iii) { std::string data = _argv[iii]; - if (etk::start_with(data, "--client-ip=") == true) { - basicGateway.propertyClientIp.set(std::string(&data[12])); - } else if (etk::start_with(data, "--client-port=") == true) { - basicGateway.propertyClientPort.set(etk::string_to_uint16_t(std::string(&data[14]))); - } else if (etk::start_with(data, "--client-max=") == true) { - basicGateway.propertyClientMax.set(etk::string_to_uint16_t(std::string(&data[13]))); + if (etk::start_with(data, "--user=") == true) { + basicGateway.propertyUserName.set(std::string(&data[7])); + } else if (etk::start_with(data, "--gw-ip=") == true) { + basicGateway.propertyGateWayClientIp.set(std::string(&data[8])); + } else if (etk::start_with(data, "--gw-port=") == true) { + basicGateway.propertyGateWayClientPort.set(etk::string_to_uint16_t(std::string(&data[10]))); } else if (etk::start_with(data, "--service-ip=") == true) { basicGateway.propertyServiceIp.set(std::string(&data[13])); } else if (etk::start_with(data, "--service-port=") == true) { @@ -34,11 +34,11 @@ int main(int _argc, const char *_argv[]) { || data == "--help") { APPL_PRINT(etk::getApplicationName() << " - help : "); APPL_PRINT(" " << _argv[0] << " [options]"); - APPL_PRINT(" --client-ip=XXX Client connection IP (default: 1.7.0.0.1)"); - APPL_PRINT(" --client-port=XXX Client connection PORT (default: 1983)"); - APPL_PRINT(" --client-max=XXX Clainet Maximum parallele connection (default: 80)"); + APPL_PRINT(" --user=XXX Name of the user that we are connected."); + APPL_PRINT(" --gw-ip=XXX GateWay Front-end connection IP (default: 1.7.0.0.1)"); + APPL_PRINT(" --gw-port=XXX GateWay Front-end connection PORT (default: 1984)"); APPL_PRINT(" --service-ip=XXX Service connection IP (default: 1.7.0.0.1)"); - APPL_PRINT(" --service-port=XXX Service connection PORT (default: 1984)"); + APPL_PRINT(" --service-port=XXX Service connection PORT (default: 1982)"); APPL_PRINT(" --service-max=XXX Service Maximum IO (default: 15)"); return -1; } diff --git a/tools/gateway/lutin_zeus-gateway.py b/tools/gateway-back-end/lutin_zeus-gateway-back-end.py similarity index 94% rename from tools/gateway/lutin_zeus-gateway.py rename to tools/gateway-back-end/lutin_zeus-gateway-back-end.py index e8cbbfd..2cd4958 100644 --- a/tools/gateway/lutin_zeus-gateway.py +++ b/tools/gateway-back-end/lutin_zeus-gateway-back-end.py @@ -29,7 +29,7 @@ def configure(target, my_module): my_module.add_depend(['zeus']) my_module.add_src_file([ 'appl/debug.cpp', - 'appl/ClientInterface.cpp', + 'appl/ClientGateWayInterface.cpp', 'appl/ServiceInterface.cpp', 'appl/GateWay.cpp', 'appl/main.cpp' diff --git a/tools/gateway-front-end/appl/ClientInterface.cpp b/tools/gateway-front-end/appl/ClientInterface.cpp new file mode 100644 index 0000000..9c6fcdc --- /dev/null +++ b/tools/gateway-front-end/appl/ClientInterface.cpp @@ -0,0 +1,148 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2016, Edouard DUPIN, all right reserved + * @license APACHE v2.0 (see license file) + */ + +#include +#include +#include +#include + + +#include + + +static const std::string protocolError = "PROTOCOL-ERROR"; + +appl::ClientInterface::ClientInterface(enet::Tcp _connection, appl::GateWay* _gatewayInterface) : + m_state(appl::ClientInterface::state::unconnect), + m_gatewayInterface(_gatewayInterface), + m_interfaceClient(std::move(_connection), true) { + APPL_INFO("----------------"); + APPL_INFO("-- NEW Client --"); + APPL_INFO("----------------"); +} + +appl::ClientInterface::~ClientInterface() { + APPL_INFO("Call All unlink ..."); + stop(); + APPL_INFO("-------------------"); + APPL_INFO("-- DELETE Client --"); + APPL_INFO("-------------------"); +} + +bool appl::ClientInterface::requestURI(const std::string& _uri) { + APPL_WARNING("request connect on CLIENT: '" << _uri << "'"); + if(m_gatewayInterface == nullptr) { + APPL_ERROR("Can not access to the main GateWay interface (nullptr)"); + return false; + } + std::string tmpURI = _uri; + if (tmpURI.size() == 0) { + APPL_ERROR("Empty URI ... not supported ..."); + return false; + } + if (tmpURI[0] == '/') { + tmpURI = std::string(tmpURI.begin() + 1, tmpURI.end()); + } + // TODO : Remove subParameters xxx?YYY + m_userGateWay = m_gatewayInterface->get(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, uint64_t _uid2) { + m_uid = _uid; + //m_uid2 = _uid2; + m_state = appl::ClientInterface::state::connect; + m_interfaceClient.connect(this, &appl::ClientInterface::onClientData); + m_interfaceClient.connectUri(this, &appl::ClientInterface::requestURI); + m_interfaceClient.connect(true); + m_interfaceClient.setInterfaceName("cli-" + etk::to_string(m_uid)); +} + +void appl::ClientInterface::stop() { + for (auto &it : m_listConnectedService) { + if (it == nullptr) { + continue; + } + it->m_interfaceClient.callClient(m_uid, "_delete"); + } + /* + if (m_userGateWay != nullptr) { + m_userGateWay->m_interfaceClient.callClient(m_uid2, "_delete"); + m_userGateWay = nullptr; + } + */ + m_listConnectedService.clear(); + m_interfaceClient.disconnect(); +} + +bool appl::ClientInterface::isAlive() { + return m_interfaceClient.isActive(); +} + +void appl::ClientInterface::answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp) { + m_interfaceClient.answerError(_transactionId, protocolError, _errorHelp); + m_state = appl::ClientInterface::state::disconnect; + m_interfaceClient.disconnect(true); +} + + +void appl::ClientInterface::onClientData(ememory::SharedPtr _value) { + if (_value == nullptr) { + return; + } + APPL_ERROR("receive data : " << _value); + uint32_t transactionId = _value->getTransactionId(); + if (transactionId == 0) { + APPL_ERROR("Protocol error ==>missing id"); + answerProtocolError(transactionId, "missing parameter: 'id'"); + return; + } + // Directly send to the user-GateWay + 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) { + m_userGateWay->m_interfaceClient.callForward( + m_uid, + _value, + (uint64_t(m_uid) << 32) + uint64_t(transactionId), + [=](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->setServiceId(serviceId+1); + APPL_DEBUG("transmit=" << tmpp); + m_interfaceClient.writeBinary(tmpp); + // multiple send element ... + return tmpp->getPartFinish(); + }); + } 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 ... + } +} + +void appl::ClientInterface::returnMessage(ememory::SharedPtr _data) { + APPL_ERROR("Get call from the Service to the user ..."); +} + diff --git a/tools/gateway/appl/ClientInterface.hpp b/tools/gateway-front-end/appl/ClientInterface.hpp similarity index 81% rename from tools/gateway/appl/ClientInterface.hpp rename to tools/gateway-front-end/appl/ClientInterface.hpp index 2f31416..0ed0542 100644 --- a/tools/gateway/appl/ClientInterface.hpp +++ b/tools/gateway-front-end/appl/ClientInterface.hpp @@ -7,7 +7,7 @@ #include #include -#include +#include namespace appl { class GateWay; @@ -16,17 +16,16 @@ namespace appl { enum class state { unconnect, // starting sate connect, // zeust get a TCP connection - userIdentify, // client set the user it want to access - clientIdentify, // client defien the mode of the acces (anonymous,client/user) disconnect // client is dead or loal disconnection }; enum state m_state; // state machine ... private: appl::GateWay* m_gatewayInterface; zeus::WebServer m_interfaceClient; + bool requestURI(const std::string& _uri); public: - ememory::SharedPtr m_userService; - std::vector> m_listConnectedService; + ememory::SharedPtr m_userGateWay; + std::vector> m_listConnectedService; uint64_t m_uid; uint64_t m_uid2; std::string m_userConnectionName; diff --git a/tools/gateway/appl/GateWay.cpp b/tools/gateway-front-end/appl/GateWay.cpp similarity index 71% rename from tools/gateway/appl/GateWay.cpp rename to tools/gateway-front-end/appl/GateWay.cpp index 541b19e..a8587b1 100644 --- a/tools/gateway/appl/GateWay.cpp +++ b/tools/gateway-front-end/appl/GateWay.cpp @@ -56,7 +56,7 @@ namespace appl { enet::Tcp data = std::move(m_interface.waitNext()); ZEUS_VERBOSE("New connection"); if (m_service == true) { - m_gateway->newService(std::move(data)); + m_gateway->newClientGateWayBackEnd(std::move(data)); } else { m_gateway->newClient(std::move(data)); } @@ -65,11 +65,11 @@ namespace appl { }; } -void appl::GateWay::newService(enet::Tcp _connection) { +void appl::GateWay::newClientGateWayBackEnd(enet::Tcp _connection) { ZEUS_WARNING("New TCP connection (service)"); - ememory::SharedPtr tmp = ememory::makeShared(std::move(_connection), this); + ememory::SharedPtr tmp = ememory::makeShared(std::move(_connection), this); tmp->start(); - m_serviceList.push_back(tmp); + m_gatewayBackEndList.push_back(tmp); } void appl::GateWay::newClient(enet::Tcp _connection) { @@ -84,11 +84,11 @@ appl::GateWay::GateWay() : propertyClientIp(this, "client-ip", "127.0.0.1", "Ip to listen client", &appl::GateWay::onPropertyChangeClientIp), propertyClientPort(this, "client-port", 1983, "Port to listen client", &appl::GateWay::onPropertyChangeClientPort), propertyClientMax(this, "client-max", 80, "Maximum of client at the same time", &appl::GateWay::onPropertyChangeClientMax), - 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) { + propertyGatewayBackEndIp(this, "gw-ip", "127.0.0.1", "Ip to listen client", &appl::GateWay::onPropertyChangeGateWayIp), + propertyGatewayBackEndPort(this, "gw-port", 1984, "Port to listen client", &appl::GateWay::onPropertyChangeGateWayPort), + propertyGatewayBackEndMax(this, "gw-max", 80, "Maximum of client at the same time", &appl::GateWay::onPropertyChangeGateWayMax) { m_interfaceClientServer = ememory::makeShared(this, false); - m_interfaceServiceServer = ememory::makeShared(this, true); + m_interfaceGatewayBackEndServer = ememory::makeShared(this, true); } appl::GateWay::~GateWay() { @@ -97,19 +97,21 @@ appl::GateWay::~GateWay() { void appl::GateWay::start() { m_interfaceClientServer->start(*propertyClientIp, *propertyClientPort); - m_interfaceServiceServer->start(*propertyServiceIp, *propertyServicePort); + m_interfaceGatewayBackEndServer->start(*propertyGatewayBackEndIp, *propertyGatewayBackEndPort); } void appl::GateWay::stop() { + // TODO : Stop all server ... } -ememory::SharedPtr appl::GateWay::get(const std::string& _serviceName) { - for (auto &it : m_serviceList) { +ememory::SharedPtr appl::GateWay::get(const std::string& _userName) { + // TODO : Start USer only when needed, not get it all time started... + for (auto &it : m_gatewayBackEndList) { if (it == nullptr) { continue; } - if (it->getName() != _serviceName) { + if (it->getName() != _userName) { continue; } return it; @@ -117,14 +119,17 @@ ememory::SharedPtr appl::GateWay::get(const std::string& return nullptr; } -std::vector appl::GateWay::getAllServiceName() { + +std::vector appl::GateWay::getAllUserName() { std::vector out; - for (auto &it : m_serviceList) { + /* + for (auto &it : m_gatewayBackEndList) { if (it == nullptr) { continue; } out.push_back(it->getName()); } + */ return out; } @@ -144,15 +149,15 @@ void appl::GateWay::answer(uint64_t _userSessionId, const ememory::SharedPtrisAlive() == false) { - it = m_serviceList.erase(it); + it = m_gatewayBackEndList.erase(it); continue; } } else { - it = m_serviceList.erase(it); + it = m_gatewayBackEndList.erase(it); continue; } ++it; @@ -193,14 +198,14 @@ void appl::GateWay::onPropertyChangeClientMax() { } -void appl::GateWay::onPropertyChangeServiceIp() { +void appl::GateWay::onPropertyChangeGateWayIp() { } -void appl::GateWay::onPropertyChangeServicePort() { +void appl::GateWay::onPropertyChangeGateWayPort() { } -void appl::GateWay::onPropertyChangeServiceMax() { +void appl::GateWay::onPropertyChangeGateWayMax() { } diff --git a/tools/gateway-front-end/appl/GateWay.hpp b/tools/gateway-front-end/appl/GateWay.hpp new file mode 100644 index 0000000..5112add --- /dev/null +++ b/tools/gateway-front-end/appl/GateWay.hpp @@ -0,0 +1,54 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2016, Edouard DUPIN, all right reserved + * @license APACHE v2.0 (see license file) + */ +#pragma once +#include +#include +#include +#include + +namespace appl { + class TcpServerInput; + class GateWay : public eproperty::Interface { + private: + uint64_t m_clientUID; + private: + std::vector> m_gatewayBackEndList; //!< List of all service availlable with their specific connection interface + std::vector> m_clientList; //!< List of all Client interface with their own connection + ememory::SharedPtr m_interfaceClientServer; + ememory::SharedPtr m_interfaceGatewayBackEndServer; + ejson::Document m_listUser; + public: + eproperty::Value propertyClientIp; + eproperty::Value propertyClientPort; + eproperty::Value propertyClientMax; + eproperty::Value propertyGatewayBackEndIp; + eproperty::Value propertyGatewayBackEndPort; + eproperty::Value propertyGatewayBackEndMax; + public: + GateWay(); + virtual ~GateWay(); + void start(); + void stop(); + // Get a specific user gateway: + ememory::SharedPtr get(const std::string& _userName); + + std::vector getAllUserName(); + void answer(uint64_t _userSessionId, const ememory::SharedPtr& _data); + void newClientGateWayBackEnd(enet::Tcp _connection); + void newClient(enet::Tcp _connection); + void cleanIO(); + private: + void onPropertyChangeClientIp(); + void onPropertyChangeClientPort(); + void onPropertyChangeClientMax(); + void onPropertyChangeGateWayIp(); + void onPropertyChangeGateWayPort(); + void onPropertyChangeGateWayMax(); + void onClientConnect(const bool& _value); + void onServiceConnect(const bool& _value); + }; +} + diff --git a/tools/gateway-front-end/appl/GateWayInterface.cpp b/tools/gateway-front-end/appl/GateWayInterface.cpp new file mode 100644 index 0000000..7b836ae --- /dev/null +++ b/tools/gateway-front-end/appl/GateWayInterface.cpp @@ -0,0 +1,132 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2016, Edouard DUPIN, all right reserved + * @license APACHE v2.0 (see license file) + */ + +#include +#include +#include +#include + +// todo : cHANGE THIS ... +static const std::string protocolError = "PROTOCOL-ERROR"; + + + +appl::GateWayInterface::GateWayInterface(enet::Tcp _connection, appl::GateWay* _gatewayInterface) : + m_gatewayInterface(_gatewayInterface), + m_interfaceClient(std::move(_connection), true) { + ZEUS_INFO("--------------------------"); + ZEUS_INFO("-- NEW GateWay Back-end --"); + ZEUS_INFO("--------------------------"); + +} + +appl::GateWayInterface::~GateWayInterface() { + + ZEUS_INFO("------------------------------"); + ZEUS_INFO("-- DELETE GateWay Back-end --"); + ZEUS_INFO("------------------------------"); +} + +bool appl::GateWayInterface::isAlive() { + return m_interfaceClient.isActive(); +} + +bool appl::GateWayInterface::requestURI(const std::string& _uri) { + ZEUS_INFO("request connect on User - GateWay: '" << _uri << "'"); + if(m_gatewayInterface == nullptr) { + ZEUS_ERROR("Can not access to the main GateWay interface (nullptr)"); + return false; + } + std::string tmpURI = _uri; + if (tmpURI.size() == 0) { + ZEUS_ERROR("Empty URI ... not supported ..."); + return false; + } + if (tmpURI[0] == '/') { + tmpURI = std::string(tmpURI.begin() + 1, tmpURI.end()); + } + // TODO : Remove subParameters xxx?YYY + // check if the USER is already connected: + ememory::SharedPtr tmp = m_gatewayInterface->get(tmpURI); + if (tmp != nullptr) { + ZEUS_ERROR("User is already connected ==> this is a big error ..."); + return false; + } + m_name = tmpURI; + ZEUS_WARNING("Connection of user : '" << tmpURI << "'"); + return true; +} + +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-?"); +} + +void appl::GateWayInterface::stop() { + m_interfaceClient.disconnect(); +} + + +void appl::GateWayInterface::SendData(uint64_t _userSessionId, ememory::SharedPtr _data) { + _data->setClientId(_userSessionId); + m_interfaceClient.writeBinary(_data); +} + +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); + } + } 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, false); + return; + } + m_name = callObj->getParameter(0); + m_interfaceClient.setInterfaceName("srv-" + m_name); + m_interfaceClient.answerValue(transactionId, true); + return; + } + answerProtocolError(transactionId, "unknow function"); + } + if (_value->getClientId() == 0) { + ZEUS_ERROR("Service interface ==> wrong service answer ==> missing 'client-id'"); + return; + } + m_gatewayInterface->answer(_value->getClientId(), _value); +} + + +void appl::GateWayInterface::answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp) { + m_interfaceClient.answerError(_transactionId, protocolError, _errorHelp); + m_interfaceClient.disconnect(true); +} \ No newline at end of file diff --git a/tools/gateway-front-end/appl/GateWayInterface.hpp b/tools/gateway-front-end/appl/GateWayInterface.hpp new file mode 100644 index 0000000..34f8524 --- /dev/null +++ b/tools/gateway-front-end/appl/GateWayInterface.hpp @@ -0,0 +1,37 @@ +/** @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; + class ClientInterface; + class GateWayInterface { + friend class appl::ClientInterface; + private: + appl::GateWay* m_gatewayInterface; + zeus::WebServer m_interfaceClient; + std::string m_name; + bool requestURI(const std::string& _uri); + public: + GateWayInterface(enet::Tcp _connection, appl::GateWay* _gatewayInterface); + virtual ~GateWayInterface(); + void start(); + void stop(); + void onServiceData(ememory::SharedPtr _value); + public: + void SendData(uint64_t _userSessionId, ememory::SharedPtr _data); + const std::string& getName() { + return m_name; + } + bool isAlive(); + protected: + void answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp); + }; +} + diff --git a/tools/gateway-front-end/appl/debug.cpp b/tools/gateway-front-end/appl/debug.cpp new file mode 100644 index 0000000..f1450e8 --- /dev/null +++ b/tools/gateway-front-end/appl/debug.cpp @@ -0,0 +1,12 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2016, Edouard DUPIN, all right reserved + * @license APACHE v2.0 (see license file) + */ + +#include + +int32_t appl::getLogId() { + static int32_t g_val = elog::registerInstance("zeus-gateway"); + return g_val; +} diff --git a/tools/gateway-front-end/appl/debug.hpp b/tools/gateway-front-end/appl/debug.hpp new file mode 100644 index 0000000..cdc460d --- /dev/null +++ b/tools/gateway-front-end/appl/debug.hpp @@ -0,0 +1,40 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2016, Edouard DUPIN, all right reserved + * @license APACHE v2.0 (see license file) + */ +#pragma once + +#include + +namespace appl { + int32_t getLogId(); +}; + +#define APPL_BASE(info,data) ELOG_BASE(appl::getLogId(),info,data) + +#define APPL_PRINT(data) APPL_BASE(-1, data) +#define APPL_CRITICAL(data) APPL_BASE(1, data) +#define APPL_ERROR(data) APPL_BASE(2, data) +#define APPL_WARNING(data) APPL_BASE(3, data) +#ifdef DEBUG + #define APPL_INFO(data) APPL_BASE(4, data) + #define APPL_DEBUG(data) APPL_BASE(5, data) + #define APPL_VERBOSE(data) APPL_BASE(6, data) + #define APPL_TODO(data) APPL_BASE(4, "TODO : " << data) +#else + #define APPL_INFO(data) do { } while(false) + #define APPL_DEBUG(data) do { } while(false) + #define APPL_VERBOSE(data) do { } while(false) + #define APPL_TODO(data) do { } while(false) +#endif + +#define APPL_ASSERT(cond,data) \ + do { \ + if (!(cond)) { \ + APPL_CRITICAL(data); \ + assert(!#cond); \ + } \ + } while (0) + + diff --git a/tools/gateway-front-end/appl/main.cpp b/tools/gateway-front-end/appl/main.cpp new file mode 100644 index 0000000..923b5fb --- /dev/null +++ b/tools/gateway-front-end/appl/main.cpp @@ -0,0 +1,59 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2014, Edouard DUPIN, all right reserved + * @license APACHE v2.0 (see license file) + */ + +#include +#include +#include +#include + + +#include + +int main(int _argc, const char *_argv[]) { + etk::init(_argc, _argv); + zeus::init(_argc, _argv); + appl::GateWay basicGateway; + for (int32_t iii=0; iii<_argc ; ++iii) { + std::string data = _argv[iii]; + if (etk::start_with(data, "--client-ip=") == true) { + basicGateway.propertyClientIp.set(std::string(&data[12])); + } else if (etk::start_with(data, "--client-port=") == true) { + basicGateway.propertyClientPort.set(etk::string_to_uint16_t(std::string(&data[14]))); + } else if (etk::start_with(data, "--client-max=") == true) { + basicGateway.propertyClientMax.set(etk::string_to_uint16_t(std::string(&data[13]))); + } else if (etk::start_with(data, "--gw-ip=") == true) { + basicGateway.propertyGatewayBackEndIp.set(std::string(&data[8])); + } else if (etk::start_with(data, "--gw-port=") == true) { + basicGateway.propertyGatewayBackEndPort.set(etk::string_to_uint16_t(std::string(&data[10]))); + } else if (etk::start_with(data, "--gw-max=") == true) { + basicGateway.propertyGatewayBackEndMax.set(etk::string_to_uint16_t(std::string(&data[9]))); + } else if ( data == "-h" + || data == "--help") { + APPL_PRINT(etk::getApplicationName() << " - help : "); + APPL_PRINT(" " << _argv[0] << " [options]"); + APPL_PRINT(" --client-ip=XXX Client connection IP (default: 1.7.0.0.1)"); + APPL_PRINT(" --client-port=XXX Client connection PORT (default: 1983)"); + APPL_PRINT(" --client-max=XXX Client Maximum parallele connection (default: 80)"); + APPL_PRINT(" --gw-ip=XXX Back-end Gateway connection IP (default: 1.7.0.0.1)"); + APPL_PRINT(" --gw-port=XXX Back-end Gateway connection PORT (default: 1984)"); + APPL_PRINT(" --gw-max=XXX Back-end Gateway Maximum IO (default: 15)"); + return -1; + } + } + APPL_INFO("=================================="); + APPL_INFO("== ZEUS gateway start =="); + APPL_INFO("=================================="); + basicGateway.start(); + while (true) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + basicGateway.cleanIO(); + } + basicGateway.stop(); + APPL_INFO("=================================="); + APPL_INFO("== ZEUS gateway stop =="); + APPL_INFO("=================================="); + return 0; +} diff --git a/tools/gateway-front-end/lutin_zeus-gateway-front-end.py b/tools/gateway-front-end/lutin_zeus-gateway-front-end.py new file mode 100644 index 0000000..4835754 --- /dev/null +++ b/tools/gateway-front-end/lutin_zeus-gateway-front-end.py @@ -0,0 +1,40 @@ +#!/usr/bin/python +import lutin.debug as debug +import lutin.tools as tools + + +def get_type(): + return "BINARY" + +def get_sub_type(): + return "TOOLS" + +def get_desc(): + return "ZEUS generic gateway" + +def get_licence(): + return "APACHE-2" + +def get_compagny_type(): + return "com" + +def get_compagny_name(): + return "atria-soft" + +def get_maintainer(): + return ["Mr DUPIN Edouard "] + +def configure(target, my_module): + my_module.add_path(".") + my_module.add_depend(['zeus', 'ejson']) + my_module.add_src_file([ + 'appl/debug.cpp', + 'appl/ClientInterface.cpp', + 'appl/GateWayInterface.cpp', + 'appl/GateWay.cpp', + 'appl/main.cpp' + ]) + return True + + + diff --git a/tools/player-video/appl/MediaDecoder.cpp b/tools/player-video/appl/MediaDecoder.cpp index 3ddbc5e..1dad240 100644 --- a/tools/player-video/appl/MediaDecoder.cpp +++ b/tools/player-video/appl/MediaDecoder.cpp @@ -296,7 +296,7 @@ int appl::MediaDecoder::open_codec_context(int *_streamId, AVFormatContext *_for } // Init the decoders, with or without reference counting av_dict_set(&opts, "refcounted_frames", "0", 0); - //av_dict_set(&opts, "threads", "auto", 0); + av_dict_set(&opts, "threads", "auto", 0); if ((ret = avcodec_open2(dec_ctx, dec, &opts)) < 0) { APPL_ERROR("Failed to open " << av_get_media_type_string(_type) << " codec"); return ret; diff --git a/zeus/Client.cpp b/zeus/Client.cpp index c4e962c..00abb09 100644 --- a/zeus/Client.cpp +++ b/zeus/Client.cpp @@ -49,10 +49,11 @@ bool zeus::Client::connectTo(const std::string& _address) { 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); + m_interfaceClient->setInterface(std::move(connection), false, _address); m_interfaceClient->connect(); - + /* ZEUS_WARNING("Request connect user " << _address); zeus::Future ret = call("connectToUser", _address, "zeus-client"); ret.wait(); @@ -68,6 +69,9 @@ bool zeus::Client::connectTo(const std::string& _address) { ZEUS_WARNING(" ==> Refuse connection"); } return ret.get(); + */ + // TODO: Check if connection is retruen OK or arror ... + return true; } bool zeus::Client::connect(const std::string& _address) { diff --git a/zeus/WebServer.cpp b/zeus/WebServer.cpp index 7ff2913..1af405c 100644 --- a/zeus/WebServer.cpp +++ b/zeus/WebServer.cpp @@ -44,7 +44,7 @@ zeus::WebServer::WebServer(enet::Tcp _connection, bool _isServer) : setInterface(std::move(_connection), _isServer); } -void zeus::WebServer::setInterface(enet::Tcp _connection, bool _isServer) { +void zeus::WebServer::setInterface(enet::Tcp _connection, bool _isServer, const std::string& _userName) { m_connection.setInterface(std::move(_connection), _isServer); m_connection.connect(this, &zeus::WebServer::onReceiveData); if (_isServer == true) { @@ -54,7 +54,7 @@ void zeus::WebServer::setInterface(enet::Tcp _connection, bool _isServer) { std::vector protocols; protocols.push_back("zeus/0.8"); protocols.push_back("zeus/1.0"); - m_connection.start("/stupidName", protocols); + m_connection.start("/" + _userName, protocols); } } @@ -177,8 +177,9 @@ bool zeus::WebServer::onReceiveUri(const std::string& _uri, const std::vector transit it ... + // Find element ==> transmit it ... _buffer->setTransactionId(itCall.second.getTransactionId()); _buffer->setClientId(_clientId); writeBinary(_buffer); diff --git a/zeus/WebServer.hpp b/zeus/WebServer.hpp index b776f53..b46aca6 100644 --- a/zeus/WebServer.hpp +++ b/zeus/WebServer.hpp @@ -110,6 +110,26 @@ namespace zeus { (*_class.*_func)(_value); }; } + public: + using ObserverRequestUri = std::function; //!< Define an Observer on the specific URI requested callback: function pointer (return true if the connection is accepted or not) + protected: + ObserverRequestUri m_observerRequestUri; + public: + /** + * @brief Connect on the URI requested. + * @param[in] _class shared_ptr Object on whe we need to call ==> the object is get in keeped in weak_ptr. + * @param[in] _func Function to call. + */ + template + void connectUri(CLASS_TYPE* _class, bool (CLASS_TYPE::*_func)(const std::string&)) { + m_observerRequestUri = [=](const std::string& _value){ + return (*_class.*_func)(_value); + }; + } + void connectUri(WebServer::ObserverRequestUri _func) { + m_observerRequestUri = _func; + } + public: /** * @brief @@ -134,7 +154,7 @@ namespace zeus { * @param[in] * @return */ - void setInterface(enet::Tcp _connection, bool _isServer); + void setInterface(enet::Tcp _connection, bool _isServer, const std::string& _userName=""); /** * @brief * @param[in]