[DEV] review entire model...

This commit is contained in:
Edouard DUPIN 2016-11-29 21:39:39 +01:00
parent be919abb1e
commit fa38f8d637
36 changed files with 1289 additions and 457 deletions

View File

@ -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',

View File

@ -73,10 +73,10 @@ int main(int _argc, const char *_argv[]) {
APPL_INFO(" ----------------------------------");
APPL_INFO(" -- Get service count");
APPL_INFO(" ----------------------------------");
zeus::Future<int32_t> retNbService = client1.call("getServiceCount");
zeus::Future<int32_t> retNbService = client1.call(ZEUS_NO_ID_OBJECT, ZEUS_ID_GATEWAY, "getServiceCount");
retNbService.wait();
APPL_INFO("Nb services = " << retNbService.get());
zeus::Future<std::vector<std::string>> retServiceList = client1.call("getServiceList");
zeus::Future<std::vector<std::string>> 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<std::vector<std::string>> retCall = remoteServicePicture.getAlbums().wait();

View File

@ -0,0 +1,79 @@
/** @file
* @author Edouard DUPIN
* @copyright 2016, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#include <appl/debug.hpp>
#include <appl/DirectInterface.hpp>
#include <zeus/Future.hpp>
#include <appl/GateWay.hpp>
#include <enet/TcpClient.hpp>
#include <zeus/AbstractFunction.hpp>
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<std::string> 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<zeus::Buffer> _value) {
appl::IOInterface::receive(_value);
}
void appl::DirectInterface::send(ememory::SharedPtr<zeus::Buffer> _value) {
m_interfaceWeb.writeBinary(_value);
}

View File

@ -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 <zeus/WebServer.hpp>
#include <appl/GateWay.hpp>
#include <appl/IOInterface.hpp>
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<zeus::Buffer> _data);
void send(ememory::SharedPtr<zeus::Buffer> _data);
bool requestURI(const std::string& _uri);
//void answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp);
zeus::WebServer* getInterface() {
return &m_interfaceWeb;
}
};
}

View File

@ -7,6 +7,8 @@
#include <appl/GateWay.hpp>
#include <appl/debug.hpp>
#include <enet/TcpServer.hpp>
#include <appl/DirectInterface.hpp>
#include <appl/RouterInterface.hpp>
namespace appl {
@ -61,18 +63,19 @@ namespace appl {
void appl::GateWay::newService(enet::Tcp _connection) {
APPL_WARNING("New TCP connection (service)");
ememory::SharedPtr<appl::ServiceInterface> tmp = ememory::makeShared<appl::ServiceInterface>(std::move(_connection), this);
tmp->start();
m_serviceList.push_back(tmp);
ememory::SharedPtr<appl::DirectInterface> tmp = ememory::makeShared<appl::DirectInterface>(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<appl::TcpServerInput>(this);
}
@ -90,7 +93,7 @@ void appl::GateWay::stop() {
m_routerClient.reset();
}
/*
ememory::SharedPtr<appl::ServiceInterface> appl::GateWay::get(const std::string& _serviceName) {
for (auto &it : m_serviceList) {
if (it == nullptr) {
@ -103,40 +106,51 @@ ememory::SharedPtr<appl::ServiceInterface> appl::GateWay::get(const std::string&
}
return nullptr;
}
*/
std::vector<std::string> appl::GateWay::getAllServiceName() {
std::vector<std::string> 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<zeus::Buffer>& _data) {
void appl::GateWay::send(ememory::SharedPtr<zeus::Buffer> _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();
}

View File

@ -4,15 +4,17 @@
* @license APACHE v2.0 (see license file)
*/
#pragma once
#include <appl/ServiceInterface.hpp>
#include <appl/RouterInterface.hpp>
#include <appl/IOInterface.hpp>
#include <eproperty/Value.hpp>
namespace appl {
class TcpServerInput;
class DirectInterface;
class RouterInterface;
class IOInterface;
class GateWay : public eproperty::Interface {
uint16_t m_idIncrement;
private:
std::vector<ememory::SharedPtr<appl::ServiceInterface>> m_serviceList; //!< List of all service availlable with their specific connection interface
ememory::SharedPtr<appl::RouterInterface> m_routerClient; //!< Interface with the Gateway Front End
ememory::SharedPtr<appl::TcpServerInput> m_interfaceNewService;
@ -23,14 +25,18 @@ namespace appl {
eproperty::Value<std::string> propertyServiceIp;
eproperty::Value<uint16_t> propertyServicePort;
eproperty::Value<uint16_t> propertyServiceMax;
public:
std::vector<ememory::SharedPtr<appl::DirectInterface>> m_listIODirect; //!< List of all service availlable with their specific connection interface
std::vector<ememory::SharedPtr<appl::IOInterface>> m_listIO;
public:
GateWay();
virtual ~GateWay();
void start();
void stop();
ememory::SharedPtr<appl::ServiceInterface> get(const std::string& _serviceName);
//ememory::SharedPtr<appl::ServiceInterface> get(const std::string& _serviceName);
std::vector<std::string> getAllServiceName();
void answer(uint64_t _userSessionId, const ememory::SharedPtr<zeus::Buffer>& _data);
void send(ememory::SharedPtr<zeus::Buffer> _data);
void newService(enet::Tcp _connection);
void cleanIO();
private:

View File

@ -0,0 +1,269 @@
/** @file
* @author Edouard DUPIN
* @copyright 2016, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#include <appl/debug.hpp>
#include <appl/IOInterface.hpp>
#include <zeus/Future.hpp>
#include <appl/GateWay.hpp>
#include <enet/TcpClient.hpp>
#include <zeus/AbstractFunction.hpp>
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<zeus::Buffer> _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<zeus::BufferCall> callObj = ememory::staticPointerCast<zeus::BufferCall>(_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<std::string>(0);
std::string clientTocken = callObj->getParameter<std::string>(1);
if (m_userService == nullptr) {
answerProtocolError(transactionId, "gateWay internal error 3");
return;
}
zeus::Future<bool> 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<std::string>(0);
zeus::Future<bool> 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<std::vector<std::string>> 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<std::string> currentServices = m_gatewayInterface->getAllServiceName();
zeus::Future<std::vector<std::string>> 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<std::string>(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<appl::ServiceInterface> srv = m_gatewayInterface->get(serviceName);
if (srv != nullptr) {
zeus::Future<bool> 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<int64_t>(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<bool> 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);
}
}

View File

@ -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 <zeus/WebServer.hpp>
#include <appl/GateWay.hpp>
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<zeus::Buffer> _value);
// Data must be send to the IO
virtual void send(ememory::SharedPtr<zeus::Buffer> _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;
};
}

View File

@ -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<bool> futLocalService = m_userService->m_interfaceClient.call(m_localIdUser, ZEUS_ID_SERVICE_ROOT, "_new", m_userConnectionName, "**Gateway**", std::vector<std::string>());
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<zeus::Buffer> _data) {
APPL_ERROR("Get call from the Service to the user ...");
void appl::clientSpecificInterface::send(ememory::SharedPtr<zeus::Buffer> _value) {
m_interfaceWeb->writeBinary(_value);
}
void appl::userSpecificInterface::onClientData(ememory::SharedPtr<zeus::Buffer> _value) {
#if 0
void appl::clientSpecificInterface::receive(ememory::SharedPtr<zeus::Buffer> _value) {
if (_value == nullptr) {
return;
}
@ -93,7 +71,7 @@ void appl::userSpecificInterface::onClientData(ememory::SharedPtr<zeus::Buffer>
}
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<zeus::Buffer>
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<zeus::Buffer>
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<zeus::Buffer>
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<zeus::Buffer>
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<zeus::Buffer>
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<zeus::Buffer>
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<zeus::Buffer>
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<appl::ServiceInterface> srv = m_gatewayInterface->get(serviceName);
@ -260,18 +238,18 @@ void appl::userSpecificInterface::onClientData(ememory::SharedPtr<zeus::Buffer>
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<zeus::Buffer>
int64_t localServiceID = callObj->getParameter<int64_t>(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<bool> 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<zeus::Buffer>
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<zeus::Buffer>
}
}
}
#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<zeus::Buffer> _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; iii<m_listUser.size(); ++iii) {
if (m_listUser[iii].m_routeurUID == clientId) {
localId = iii;
break;
}
}
if (localId == -1) {
m_listUser.push_back(userSpecificInterface(m_userConnectionName));
localId = m_listUser.size()-1;
bool ret = m_listUser[localId].start(_value->getTransactionId(), 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<zeus::Buffer>& _data) {
for (auto &it : m_listUser) {
if (it.checkId(_userSessionId) == false) {
continue;
}
it.returnMessage(_data);
m_listClients.push_back(ememory::makeShared<clientSpecificInterface>());
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<zeus::Buffer>& _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;

View File

@ -7,63 +7,40 @@
#include <zeus/WebServer.hpp>
#include <appl/GateWay.hpp>
#include <appl/ServiceInterface.hpp>
#include <appl/IOInterface.hpp>
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<ememory::SharedPtr<appl::ServiceInterface>> m_listConnectedService;
ememory::SharedPtr<appl::ServiceInterface> m_userService;
std::string m_userConnectionName;
std::string m_clientName;
std::vector<std::string> m_clientgroups;
std::vector<std::string> 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<zeus::Buffer> _value);
void returnMessage(ememory::SharedPtr<zeus::Buffer> _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<zeus::Buffer> _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<userSpecificInterface> m_listUser;
std::vector<ememory::SharedPtr<clientSpecificInterface>> 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<zeus::Buffer> _value);
bool isAlive();
void answer(uint64_t _userSessionId, const ememory::SharedPtr<zeus::Buffer>& _data);
void send(const ememory::SharedPtr<zeus::Buffer>& _data);
void clean();
};
}

View File

@ -7,7 +7,7 @@
#include <zeus/WebServer.hpp>
#include <ememory/memory.hpp>
#error remove ...
namespace appl {
class GateWay;
class RouterInterface;

View File

@ -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'
])

View File

@ -16,6 +16,7 @@
#include <thread>
#include <etk/stdTools.hpp>
#include <zeus/Service.hpp>
#include <zeus/Client.hpp>
#include <zeus/zeus.hpp>
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("===========================================================");

View File

@ -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<zeus::Buffer> _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<zeus::Buffer> 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<zeus::BufferCall> callObj = ememory::staticPointerCast<zeus::BufferCall>(_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<zeus::Buffer> _data) {
void appl::ClientInterface::send(ememory::SharedPtr<zeus::Buffer> _data) {
if (_data == nullptr) {
return;
}
m_interfaceClient.writeBinary(_data);
/*
if (_data->getType() == zeus::Buffer::typeMessage::ctrl) {
std::string value = static_cast<zeus::BufferCtrl*>(_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<zeus::Buffer> _data
return;
}
APPL_ERROR("Get call from the Service to the user ... " << _data);
*/
}

View File

@ -8,32 +8,27 @@
#include <zeus/WebServer.hpp>
#include <appl/Router.hpp>
#include <appl/GateWayInterface.hpp>
#include <ememory/memory.hpp>
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<appl::ClientInterface> {
private:
appl::Router* m_routerInterface;
zeus::WebServer m_interfaceClient;
bool requestURI(const std::string& _uri);
public:
ememory::SharedPtr<appl::GateWayInterface> 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<zeus::Buffer> _value);
void returnMessage(ememory::SharedPtr<zeus::Buffer> _data);
bool checkId(uint64_t _id) const {
void send(ememory::SharedPtr<zeus::Buffer> _data);
bool checkId(uint16_t _id) const {
return m_uid == _id;
}
bool isAlive();

View File

@ -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<zeus::Buffer> _data) {
_data->setClientId(_userSessionId);
void appl::GateWayInterface::send(ememory::SharedPtr<zeus::Buffer> _data) {
m_interfaceClient.writeBinary(_data);
}
uint16_t appl::GateWayInterface::addClient(ememory::SharedPtr<appl::ClientInterface> _value) {
m_clientConnected.push_back(_value);
return m_lastSourceID++;
}
void appl::GateWayInterface::rmClient(ememory::SharedPtr<appl::ClientInterface> _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<zeus::Buffer> _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<zeus::BufferCall> callObj = ememory::staticPointerCast<zeus::BufferCall>(_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<std::string>(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<zeus::BufferCall> callObj = ememory::staticPointerCast<zeus::BufferCall>(_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<std::string>(0));
m_interfaceClient.answerValue(transactionId, _value->getClientId(), _value->getServiceId(), false);
m_name = callObj->getParameter<std::string>(0);
m_interfaceClient.setInterfaceName("srv-" + m_name);
m_interfaceClient.answerValue(transactionId, _value->getDestination(), _value->getSource(), true);
return;
}
m_name = callObj->getParameter<std::string>(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");
}

View File

@ -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<ememory::SharedPtr<appl::ClientInterface>> 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<zeus::Buffer> _value);
public:
void SendData(uint64_t _userSessionId, ememory::SharedPtr<zeus::Buffer> _data);
uint16_t addClient(ememory::SharedPtr<appl::ClientInterface> _value);
void rmClient(ememory::SharedPtr<appl::ClientInterface> _value);
void send(ememory::SharedPtr<zeus::Buffer> _data);
const std::string& getName() {
return m_name;
}

View File

@ -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<appl::ClientInterface> tmp = ememory::makeShared<appl::ClientInterface>(std::move(_connection), this);
tmp->start(m_clientUID);
m_clientUID++;
tmp->start();
m_clientList.push_back(tmp);
}
@ -135,18 +134,6 @@ std::vector<std::string> appl::Router::getAllUserName() {
}
void appl::Router::answer(uint64_t _userSessionId, const ememory::SharedPtr<zeus::Buffer>& _data) {
for (auto &it : m_clientList) {
if (it == nullptr) {
continue;
}
if (it->checkId(_userSessionId) == false) {
continue;
}
it->returnMessage(_data);
return;
}
}
void appl::Router::cleanIO() {

View File

@ -36,7 +36,6 @@ namespace appl {
ememory::SharedPtr<appl::GateWayInterface> get(const std::string& _userName);
std::vector<std::string> getAllUserName();
void answer(uint64_t _userSessionId, const ememory::SharedPtr<zeus::Buffer>& _data);
void newClientGateWay(enet::Tcp _connection);
void newClient(enet::Tcp _connection);
void cleanIO();

View File

@ -38,7 +38,7 @@ namespace zeus {
ret = (*_pointer.*_func)(_obj->getParameter<ZEUS_TYPES>(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<ZEUS_TYPES>(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; iii<sizeof...(ZEUS_TYPES); ++iii) {
if (checkCompatibility(m_paramType[iii], _obj->getParameterType(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;

View File

@ -33,7 +33,7 @@ namespace zeus {
ret = _func(_obj->getParameter<ZEUS_TYPES>(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<ZEUS_TYPES>(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; iii<sizeof...(ZEUS_TYPES); ++iii) {
if (checkCompatibility(m_paramType[iii], _obj->getParameterType(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;

View File

@ -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> zeus::Buffer::create(const std::vector<uint8_t>
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> zeus::Buffer::create(const std::vector<uint8_t>
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> zeus::Buffer::create(const std::vector<uint8_t>
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> zeus::Buffer::create(const std::vector<uint8_t>
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);

View File

@ -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

View File

@ -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<zeus::BufferData> 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<zeus::BufferData> 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;

View File

@ -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<zeus::Buffer> _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<zeus::Buffer> _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<zeus::BufferCall> callObj = ememory::staticPointerCast<zeus::BufferCall>(_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<std::string>(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<zeus::Object> 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<bool> 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<bool> 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<zeus::ServiceRemoteBase> tmp = ememory::makeShared<zeus::ServiceRemoteBase>(m_interfaceClient, _name);
ememory::SharedPtr<zeus::ServiceRemoteBase> tmp = ememory::makeShared<zeus::ServiceRemoteBase>(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<zeus::WebServer>();
if (m_interfaceClient == nullptr) {
m_interfaceWeb = ememory::makeShared<zeus::WebServer>();
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<uint16_t> 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<bool> 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<bool> retIdentify = call("anonymous").wait();
zeus::Future<bool> 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<bool> retIdentify = call("anonymous").wait();
zeus::Future<bool> 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<bool> retIdentify = call("auth", _userPassword).wait();
zeus::Future<bool> 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<bool> retIdentify = call("identify", _clientName, _clientTocken).wait();
zeus::Future<bool> 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();
}
}

View File

@ -12,8 +12,10 @@
#include <zeus/Future.hpp>
#include <zeus/ServiceRemote.hpp>
#include <zeus/Object.hpp>
namespace zeus {
class Service;
/**
* @brief Client interface to acces on the remote service and gateway
*/
@ -23,10 +25,13 @@ namespace zeus {
eproperty::Value<std::string> propertyIp; //!< Ip of WebSocket TCP connection
eproperty::Value<uint16_t> 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<zeus::WebServer> m_interfaceClient; //!< Interface on the Websocket interface
ememory::SharedPtr<zeus::WebServer> m_interfaceWeb; //!< Interface on the Websocket interface
std::vector<ememory::WeakPtr<zeus::ServiceRemoteBase>> m_listConnectedService; //!< Connect only one time on each service, not needed more.
std::vector<ememory::SharedPtr<zeus::Service>> m_listProvicedService; //!< Connect only one time on each service, not needed more.
std::vector<ememory::SharedPtr<zeus::Object>> 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<ememory::SharedPtr<zeus::Object>, zeus::Client&, uint16_t objId)>;
std::map<std::string,factoryService> 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<zeus::Service>& _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<class... _ARGS>
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<zeus::BufferAnswer> 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();
};
}

View File

@ -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<zeus::FutureData>();
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::Buffer> zeus::FutureBase::getRaw() {
@ -36,29 +35,19 @@ ememory::SharedPtr<zeus::Buffer> zeus::FutureBase::getRaw() {
return m_data->m_returnData;
}
zeus::FutureBase::FutureBase(uint32_t _transactionId, ememory::SharedPtr<zeus::Buffer> _returnData, /*zeus::FutureData::ObserverFinish _callback, */uint32_t _clientId) {
zeus::FutureBase::FutureBase(uint32_t _transactionId, ememory::SharedPtr<zeus::Buffer> _returnData, uint32_t _source) {
m_data = ememory::makeShared<zeus::FutureData>();
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 {

View File

@ -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<zeus::Buffer> _returnData, uint32_t _clientId=0);
FutureBase(uint32_t _transactionId, ememory::SharedPtr<zeus::Buffer> _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

View File

@ -22,7 +22,7 @@ namespace zeus {
using Observer = std::function<bool(zeus::FutureBase)>; //!< 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<zeus::Buffer> m_returnData; //!< all buffer concatenate or last buffer if synchronous
Observer m_callbackThen; //!< observer callback When data arrive and NO error appear

110
zeus/Object.cpp Normal file
View File

@ -0,0 +1,110 @@
/** @file
* @author Edouard DUPIN
* @copyright 2016, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#include <zeus/Object.hpp>
#include <zeus/debug.hpp>
#include <etk/stdTools.hpp>
#include <enet/TcpClient.hpp>
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<zeus::Buffer> _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<zeus::Buffer> _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<zeus::BufferCall> callObj = ememory::staticPointerCast<zeus::BufferCall>(_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<std::string>(0);
std::string clientName = callObj->getParameter<std::string>(1);
std::vector<std::string> clientGroup = callObj->getParameter<std::vector<std::string>>(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;
}
}
}

194
zeus/Object.hpp Normal file
View File

@ -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 <zeus/WebServer.hpp>
#include <eproperty/Value.hpp>
#include <zeus/AbstractFunctionTypeDirect.hpp>
#include <zeus/AbstractFunctionTypeClass.hpp>
#include <zeus/debug.hpp>
#include <zeus/RemoteProcessCall.hpp>
#include <zeus/Future.hpp>
/**
* @brief Main zeus library namespace
*/
namespace zeus {
/**
* @brief
* @param[in]
* @return
*/
class Object : public zeus::RemoteProcessCall {
protected:
std::mutex m_mutex;
protected:
ememory::SharedPtr<zeus::WebServer> m_interfaceClient;
uint16_t m_ObjectId;
//std::vector<zeus::FutureBase> m_callMultiData;
public:
/**
* @brief
* @param[in]
* @return
*/
Object();
/**
* @brief
* @param[in]
* @return
*/
virtual ~Object();
private:
/**
* @brief
* @param[in]
* @return
*/
void receive(ememory::SharedPtr<zeus::Buffer> _value);
private:
/**
* @brief
* @param[in]
* @return
*/
void callBinary(ememory::SharedPtr<zeus::Buffer> _obj);
/**
* @brief
* @param[in]
* @return
*/
virtual void callBinary2(const std::string& _call, ememory::SharedPtr<zeus::BufferCall> _obj);
public:
/**
* @brief
* @param[in]
* @return
*/
// Add Local fuction (depend on this class)
template<class ZEUS_RETURN_VALUE,
class ZEUS_CLASS_TYPE,
class... ZEUS_FUNC_ARGS_TYPE>
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 ZEUS_TYPE_OBJECT>
class ObjectType : public zeus::Object {
private:
ZEUS_TYPE_OBJECT m_interface; // direct handle on the data;
public:
/**
* @brief
* @param[in]
* @return
*/
template<class ZEUS_RETURN_VALUE,
class ZEUS_CLASS_TYPE,
class... ZEUS_FUNC_ARGS_TYPE>
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<zeus::BufferCall> _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;
}
};
}

View File

@ -38,12 +38,12 @@ void zeus::Service::onClientData(ememory::SharedPtr<zeus::Buffer> _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<zeus::Buffer> _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<zeus::Buffer> _obj) {
if (_obj->getType() == zeus::Buffer::typeMessage::call) {
ZEUS_INFO("plop 5 ... ");
ememory::SharedPtr<zeus::BufferCall> callObj = ememory::staticPointerCast<zeus::BufferCall>(_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<zeus::Buffer> _obj) {
std::string userName = callObj->getParameter<std::string>(0);
std::string clientName = callObj->getParameter<std::string>(1);
std::vector<std::string> clientGroup = callObj->getParameter<std::vector<std::string>>(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;
}
}

View File

@ -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<std::string>& _groups) = 0;
virtual void clientConnect(uint16_t _sourceId, const std::string& _userName, const std::string& _clientName, const std::vector<std::string>& _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 ZEUS_TYPE_SERVICE>
class ServiceType : public zeus::Service {
private:
std::function<ememory::SharedPtr<ZEUS_TYPE_SERVICE>(ememory::SharedPtr<ClientProperty>, const std::string&)> m_factory;
public:
ServiceType(std::function<ememory::SharedPtr<ZEUS_TYPE_SERVICE>(ememory::SharedPtr<ClientProperty>, 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<uint64_t, std::pair<ememory::SharedPtr<ClientProperty>, ememory::SharedPtr<ZEUS_TYPE_SERVICE>>> m_interface;
ememory::SharedPtr<ClientProperty> 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<std::string>& _groups) {
/*
void clientConnect(uint16_t _sourceId, const std::string& _userName, const std::string& _clientName, const std::vector<std::string>& _groups) {
std::unique_lock<std::mutex> 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<ClientProperty> tmpProperty = ememory::makeShared<ClientProperty>(_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<std::mutex> 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<std::mutex> 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<std::string>& _clientGroups) {
/*
void clientSetGroup(uint16_t _sourceId, const std::vector<std::string>& _clientGroups) {
std::unique_lock<std::mutex> 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<zeus::BufferCall> _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;
}
};

View File

@ -94,7 +94,6 @@ namespace zeus {
*/
template<class... _ARGS>
zeus::FutureBase call(const std::string& _functionName, _ARGS&&... _args) {
if ( m_interface == nullptr
|| m_interface->m_interfaceClient == nullptr) {
ememory::SharedPtr<zeus::BufferAnswer> 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<class... _ARGS>
zeus::FutureBase callAction(const std::string& _functionName, _ARGS&&... _args, zeus::FutureData::ObserverFinish _callback) {
if ( m_interface == nullptr
|| m_interface->m_interfaceClient == nullptr) {
ememory::SharedPtr<zeus::BufferAnswer> 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);
}
*/
};

View File

@ -11,13 +11,13 @@
#include <zeus/BufferCtrl.hpp>
ememory::SharedPtr<zeus::BufferCall> zeus::createBaseCall(uint64_t _transactionId, const uint32_t& _clientId, const uint32_t& _serviceId, const std::string& _functionName) {
ememory::SharedPtr<zeus::BufferCall> zeus::createBaseCall(uint64_t _transactionId, const uint32_t& _source, const uint32_t& _destination, const std::string& _functionName) {
ememory::SharedPtr<zeus::BufferCall> 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<zeus::ActionAsyncClient> 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<zeus::ActionAsyncClient> _async) :
SendAsyncBinary(uint64_t _transactionId, const uint32_t& _source, const uint32_t& _destination, std::vector<zeus::ActionAsyncClient> _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<zeus::Buffer> _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<zeus::Buffer> _obj,
const uint32_t& _serviceId) {
const uint32_t& _destination) {
if (isActive() == false) {
ZEUS_ERROR("Send [STOP] ==> not connected (no TCP)");
ememory::SharedPtr<zeus::BufferAnswer> 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<zeus::Buffer> _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<zeus::Buffer> _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);
}

View File

@ -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<zeus::BufferCall> createBaseCall(uint64_t _transactionId, const uint32_t& _clientId, const uint32_t& _serviceId, const std::string& _functionName);
ememory::SharedPtr<zeus::BufferCall> 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<class... _ARGS>
ememory::SharedPtr<zeus::BufferCall> createCall(uint64_t _transactionId, const uint32_t& _clientId, const uint32_t& _serviceId, const std::string& _functionName, _ARGS&&... _args) {
ememory::SharedPtr<zeus::BufferCall> callElem = createBaseCall(_transactionId, _clientId, _serviceId, _functionName);
ememory::SharedPtr<zeus::BufferCall> createCall(uint64_t _transactionId, const uint32_t& _source, const uint32_t& _destination, const std::string& _functionName, _ARGS&&... _args) {
ememory::SharedPtr<zeus::BufferCall> callElem = createBaseCall(_transactionId, _source, _destination, _functionName);
if (callElem == nullptr) {
return nullptr;
}
@ -253,18 +258,19 @@ namespace zeus {
* @return
*/
template<class... _ARGS>
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<zeus::BufferCall> callElem = zeus::createCall(id, _clientId, _serviceId, _functionName, std::forward<_ARGS>(_args)...);
ememory::SharedPtr<zeus::BufferCall> 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<zeus::Buffer> _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<zeus::Buffer> _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<class ZEUS_ARG>
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<zeus::BufferAnswer> 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);
};
}