[DEV] clean connect interface with the gateway

This commit is contained in:
Edouard DUPIN 2016-05-27 22:21:32 +02:00
parent 3ef98f5693
commit bdf4983fbe
17 changed files with 371 additions and 136 deletions

View File

@ -152,6 +152,12 @@ namespace jus {
}
ejson::Object jus::createCallJson(uint64_t _transactionId, const std::string& _functionName, ejson::Array _params) {
ejson::Object callElem = createBaseCall(_transactionId, _functionName);
callElem.add("param", _params);
return callElem;
}
ejson::Object jus::createBaseCall(uint64_t _transactionId, const std::string& _functionName, const std::string& _service) {
ejson::Object obj;
if (_service.size() != 0) {
@ -207,6 +213,26 @@ bool jus::AbstractFunction::checkCompatibility(const ParamType& _type, const ejs
|| createType<double>() == _type) {
return _params.isNumber();
}
if (createType<std::vector<std::string>>() == _type) {
return _params.isArray();
}
if ( createType<std::vector<bool>>() == _type
|| createType<std::vector<int64_t>>() == _type
|| createType<std::vector<int32_t>>() == _type
|| createType<std::vector<int16_t>>() == _type
|| createType<std::vector<int8_t>>() == _type
|| createType<std::vector<uint64_t>>() == _type
|| createType<std::vector<uint32_t>>() == _type
|| createType<std::vector<uint16_t>>() == _type
|| createType<std::vector<uint8_t>>() == _type
|| createType<std::vector<float>>() == _type
|| createType<std::vector<double>>() == _type) {
if (_params.isObject()) {
JUS_TODO("Special case of packaging of the data");
return false;
}
return _params.isArray();
}
if (createType<std::string>() == _type) {
return _params.isString();
}

View File

@ -52,6 +52,30 @@ namespace jus {
ejson::Object createBaseCall(uint64_t _transactionId, const std::string& _functionName, const std::string& _service="");
void createParam(ejson::Object& _obj);
template<class... _ARGS>
void createParam(ejson::Object& _obj, const char* _param, _ARGS&&... _args);
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::string& _param, _ARGS&&... _args);
template<class... _ARGS>
void createParam(ejson::Object& _obj, const bool& _param, _ARGS&&... _args);
template<class... _ARGS>
void createParam(ejson::Object& _obj, const int32_t& _param, _ARGS&&... _args);
template<class... _ARGS>
void createParam(ejson::Object& _obj, const double& _param, _ARGS&&... _args);
template<class... _ARGS>
void createParam(ejson::Object& _obj, const float& _param, _ARGS&&... _args);
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<std::string>& _param, _ARGS&&... _args);
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<bool>& _param, _ARGS&&... _args);
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<int32_t>& _param, _ARGS&&... _args);
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<double>& _param, _ARGS&&... _args);
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<float>& _param, _ARGS&&... _args);
template<class... _ARGS>
void createParam(ejson::Object& _obj, const char* _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
@ -188,7 +212,7 @@ namespace jus {
createParam(callElem, std::forward<_ARGS>(_args)...);
return callElem;
}
ejson::Object createCallJson(uint64_t _transactionId, const std::string& _functionName, ejson::Array _params);
}

View File

@ -22,12 +22,25 @@ jus::Client::~Client() {
}
void jus::Client::onClientData(std::string _value) {
JUS_DEBUG("Get answer : " << _value);
ejson::Object obj(_value);
jus::FutureBase future;
{
uint64_t tid = obj["id"].toNumber().get();
if (tid == 0) {
if (obj["error"].toString().get() == "PROTOCOL-ERROR") {
JUS_ERROR("Get a Protocol error ...");
std::unique_lock<std::mutex> lock(m_mutex);
for (auto &it : m_pendingCall) {
if (it.isValid() == false) {
continue;
}
it.setAnswer(obj);
}
m_pendingCall.clear();
} else {
JUS_ERROR("call with no ID ==> error ...");
}
return;
}
std::unique_lock<std::mutex> lock(m_mutex);
@ -136,15 +149,15 @@ uint64_t jus::Client::getId() {
return m_id++;
}
jus::FutureBase jus::Client::callJson(uint64_t _transactionId, const ejson::Object& _obj) {
jus::FutureBase jus::Client::callJson(uint64_t _transactionId, const ejson::Object& _obj, jus::FutureData::ObserverFinish _callback) {
JUS_VERBOSE("Send JSON [START] ");
if (m_interfaceClient.isActive() == false) {
ejson::Object obj;
obj.add("error", ejson::String("NOT-CONNECTED"));
obj.add("error-help", ejson::String("Client interface not connected (no TCP)"));
return jus::FutureBase(_transactionId, true, obj);
return jus::FutureBase(_transactionId, true, obj, _callback);
}
jus::FutureBase tmpFuture(_transactionId);
jus::FutureBase tmpFuture(_transactionId, _callback);
{
std::unique_lock<std::mutex> lock(m_mutex);
m_pendingCall.push_back(tmpFuture);

View File

@ -43,7 +43,7 @@ namespace jus {
private:
void onClientData(std::string _value);
std::string asyncRead();
jus::FutureBase callJson(uint64_t _transactionId, const ejson::Object& _obj);
jus::FutureBase callJson(uint64_t _transactionId, const ejson::Object& _obj, jus::FutureData::ObserverFinish _callback=nullptr);
public:
uint64_t getId();
template<class... _ARGS>
@ -52,6 +52,12 @@ namespace jus {
ejson::Object callElem = jus::createCall(id, _functionName, std::forward<_ARGS>(_args)...);
return callJson(id, callElem);
}
template<class... _ARGS>
jus::FutureBase callAction(const std::string& _functionName, _ARGS&&... _args, jus::FutureData::ObserverFinish _callback) {
uint64_t id = getId();
ejson::Object callElem = jus::createCall(id, _functionName, std::forward<_ARGS>(_args)...);
return callJson(id, callElem, _callback);
}
private:
void onPropertyChangeIp();
void onPropertyChangePort();

View File

@ -16,16 +16,24 @@ jus::FutureBase::FutureBase() {
m_data = nullptr;
}
jus::FutureBase::FutureBase(uint64_t _transactionId) {
jus::FutureBase::FutureBase(uint64_t _transactionId, jus::FutureData::ObserverFinish _callback) {
m_data = std::make_shared<jus::FutureData>();
if (m_data == nullptr) {
return;
}
m_data->m_transactionId = _transactionId;
m_data->m_isFinished = false;
m_data->m_callbackFinish = _callback;
}
jus::FutureBase::FutureBase(uint64_t _transactionId, bool _isFinished, ejson::Object _returnData) {
ejson::Object jus::FutureBase::getRaw() {
if (m_data == nullptr) {
return ejson::Object();
}
return m_data->m_returnData;
}
jus::FutureBase::FutureBase(uint64_t _transactionId, bool _isFinished, ejson::Object _returnData, jus::FutureData::ObserverFinish _callback) {
m_data = std::make_shared<jus::FutureData>();
if (m_data == nullptr) {
return;
@ -33,6 +41,11 @@ jus::FutureBase::FutureBase(uint64_t _transactionId, bool _isFinished, ejson::Ob
m_data->m_transactionId = _transactionId;
m_data->m_isFinished = _isFinished;
m_data->m_returnData = _returnData;
m_data->m_callbackFinish = _callback;
if ( m_data->m_isFinished == true
&& m_data->m_callbackFinish != nullptr) {
m_data->m_callbackFinish(*this);
}
}
jus::FutureBase jus::FutureBase::operator= (const jus::FutureBase& _base) {
@ -47,6 +60,9 @@ void jus::FutureBase::setAnswer(const ejson::Object& _returnValue) {
}
m_data->m_returnData = _returnValue;
m_data->m_isFinished = true;
if (m_data->m_callbackFinish != nullptr) {
m_data->m_callbackFinish(*this);
}
}
uint64_t jus::FutureBase::getTransactionId() {

View File

@ -14,8 +14,8 @@ namespace jus {
public:
FutureBase(const jus::FutureBase& _base);
FutureBase();
FutureBase(uint64_t _transactionId);
FutureBase(uint64_t _transactionId, bool _isFinished, ejson::Object _returnData);
FutureBase(uint64_t _transactionId, jus::FutureData::ObserverFinish _callback=nullptr);
FutureBase(uint64_t _transactionId, bool _isFinished, ejson::Object _returnData, jus::FutureData::ObserverFinish _callback=nullptr);
jus::FutureBase operator= (const jus::FutureBase& _base);
void setAnswer(const ejson::Object& _returnValue);
uint64_t getTransactionId();
@ -27,6 +27,7 @@ namespace jus {
void wait();
bool waitFor(std::chrono::microseconds _delta);
bool waitUntil(std::chrono::steady_clock::time_point _endTime);
ejson::Object getRaw();
};
}

View File

@ -9,11 +9,15 @@
#include <ejson/ejson.h>
namespace jus {
class FutureBase;
class FutureData {
public:
using ObserverFinish = std::function<void(jus::FutureBase)>; //!< Define an Observer: function pointer
public:
uint64_t m_transactionId;
bool m_isFinished;
ejson::Object m_returnData;
ObserverFinish m_callbackFinish;
};
}

View File

@ -117,6 +117,18 @@ ememory::SharedPtr<jus::GateWayService> jus::GateWay::get(const std::string& _se
return nullptr;
}
std::vector<std::string> jus::GateWay::getAllServiceName() {
std::vector<std::string> out;
for (auto &it : m_serviceList) {
if (it == nullptr) {
continue;
}
out.push_back(it->getName());
}
return out;
}
void jus::GateWay::answer(uint64_t _userSessionId, ejson::Object _data) {
for (auto &it : m_clientList) {
if (it == nullptr) {

View File

@ -32,6 +32,7 @@ namespace jus {
void start();
void stop();
ememory::SharedPtr<jus::GateWayService> get(const std::string& _serviceName);
std::vector<std::string> getAllServiceName();
void answer(uint64_t _userSessionId, ejson::Object _data);
void newService(enet::Tcp _connection);
void newClient(enet::Tcp _connection);

View File

@ -16,7 +16,7 @@ jus::GateWayClient::GateWayClient(enet::Tcp _connection, jus::GateWay* _gatewayI
m_state(jus::GateWayClient::state::unconnect),
m_gatewayInterface(_gatewayInterface),
m_interfaceClient(std::move(_connection)),
m_transactionLocalId(-1) {
m_transactionLocalId(1) {
JUS_INFO("----------------");
JUS_INFO("-- NEW Client --");
JUS_INFO("----------------");
@ -131,73 +131,89 @@ void jus::GateWayClient::onClientData(std::string _value) {
}
case jus::GateWayClient::state::userIdentify:
{
std::string call = data["call"].toString().get();
if (call == "identify") {
std::string callFunction = data["call"].toString().get();
m_clientServices.clear();
m_clientgroups.clear();
m_clientName.clear();
if ( callFunction != "identify"
&& callFunction != "auth"
&& callFunction != "anonymous") {
protocolError("Client must call: identify/auth/anonymous");
return;
}
if (callFunction == "identify") {
std::string clientName = data["param"].toArray()[0].toString().get();
std::string clientTocken = data["param"].toArray()[1].toString().get();
ejson::Object gwCall;
int32_t tmpID = m_transactionLocalId--;
gwCall.add("id", ejson::Number(tmpID));
gwCall.add("call", ejson::String("checkTocken"));
ejson::Array gwParam;
gwParam.add(ejson::String(clientName));
gwParam.add(ejson::String(clientTocken));
gwCall.add("param", gwParam);
{
std::unique_lock<std::mutex> lock(m_mutex);
m_actions.push_back(std::make_pair(tmpID,
[=](ejson::Object& _data) {
JUS_ERROR(" ==> Tocken ckeck return ...");
if (_data["return"].toBoolean().get() == true) {
if (m_userService == nullptr) {
protocolError("gateWay internal error 3");
return;
}
jus::Future<bool> fut = call(m_uid2, m_userService, "checkTocken", clientName, clientTocken);
fut.wait(); // TODO: Set timeout ...
if (fut.hasError() == true) {
JUS_ERROR("Get error from the service ...");
returnBool(transactionId, false);
protocolError("connection refused 1");
return;
} else if (fut.get() == false) {
returnBool(transactionId, false);
protocolError("connection refused 2");
return;
}
m_clientName = clientName;
m_clientgroups.clear();
ejson::Object gwCall;
int32_t tmpID = m_transactionLocalId--;
gwCall.add("id", ejson::Number(tmpID));
gwCall.add("call", ejson::String("getGroups"));
ejson::Array gwParam;
gwParam.add(ejson::String(clientName));
gwCall.add("param", gwParam);
{
std::unique_lock<std::mutex> lock(m_mutex);
m_actions.push_back(std::make_pair(tmpID,
[=](ejson::Object& _data) {
JUS_ERROR(" ==> group get return ...");
if (_data["return"].isArray() == false) {
returnBool(transactionId, false);
} else {
m_clientgroups = convertJsonTo<std::vector<std::string>>(_data["return"]);
returnBool(transactionId, true);
}
}));
}
if (m_userService != nullptr) {
m_userService->SendData(m_uid2, gwCall);
} else {
protocolError("gateWay internal error 3");
}
} else {
returnBool(transactionId, false);
}
}));
}
if (m_userService != nullptr) {
m_userService->SendData(m_uid2, gwCall);
} else {
protocolError("gateWay internal error 3");
}
return;
}
if (call == "auth") {
if (callFunction == "auth") {
std::string password = data["param"].toArray()[0].toString().get();
protocolError("Not implemented");
jus::Future<bool> fut = call(m_uid2, m_userService, "auth", password);
fut.wait(); // TODO: Set timeout ...
if (fut.hasError() == true) {
JUS_ERROR("Get error from the service ...");
returnBool(transactionId, false);
protocolError("connection refused 1");
return;
} else if (fut.get() == false) {
returnBool(transactionId, false);
protocolError("connection refused 2");
return;
}
if (call == "anonymous") {
protocolError("Not implemented");
m_clientName = m_userConnectionName;
}
if (callFunction == "anonymous") {
m_clientName = "";
}
// --------------------------------
// -- Get groups:
// --------------------------------
jus::Future<std::vector<std::string>> futGroup = call(m_uid2, m_userService, "getGroups", m_clientName);
futGroup.wait(); // TODO: Set timeout ...
if (futGroup.hasError() == true) {
JUS_ERROR("Get error from the service ...");
returnBool(transactionId, false);
protocolError("grouping error");
return;
}
protocolError("Client must call: identify/auth/anonymous");
m_clientgroups = futGroup.get();
// --------------------------------
// -- Get services:
// --------------------------------
std::vector<std::string> currentServices = m_gatewayInterface->getAllServiceName();
jus::Future<std::vector<std::string>> futServices = call(m_uid2, m_userService, "filterServices", m_clientName, currentServices);
futServices.wait(); // TODO: Set timeout ...
if (futServices.hasError() == true) {
JUS_ERROR("Get error from the service ...");
returnBool(transactionId, false);
protocolError("service filtering error");
return;
}
m_clientServices = futServices.get();
JUS_WARNING("Connection of: '" << m_clientName << "' to '" << m_userConnectionName << "'");
JUS_WARNING(" groups: " << etk::to_string(m_clientgroups));
JUS_WARNING(" services: " << etk::to_string(m_clientServices));
returnBool(transactionId, true);
m_state = jus::GateWayClient::state::clientIdentify;
return;
}
break;
@ -206,18 +222,18 @@ void jus::GateWayClient::onClientData(std::string _value) {
std::string service = data["service"].toString().get();
// Thsi is 2 default service for the cient interface that manage the authorisation of view:
if (service == "") {
std::string call = data["call"].toString().get();
std::string callFunction = data["call"].toString().get();
ejson::Object answer;
//answer.add("from-service", ejson::String(""));
answer.add("id", data["id"]);
if (call == "getServiceCount") {
if (callFunction == "getServiceCount") {
// TODO : Do it better:
answer.add("return", ejson::Number(2));
JUS_DEBUG("answer: " << answer.generateHumanString());
m_interfaceClient.write(answer.generateMachineString());
return;
}
if (call == "getServiceList") {
if (callFunction == "getServiceList") {
ejson::Array listService;
listService.add(ejson::String("ServiceManager/v0.1.0"));
listService.add(ejson::String("getServiceInformation/v0.1.0"));
@ -226,7 +242,7 @@ void jus::GateWayClient::onClientData(std::string _value) {
m_interfaceClient.write(answer.generateMachineString());
return;
}
if (call == "link") {
if (callFunction == "link") {
// first param:
std::string serviceName = data["param"].toArray()[0].toString().get();
// Check if service already link:
@ -265,7 +281,7 @@ void jus::GateWayClient::onClientData(std::string _value) {
m_interfaceClient.write(answer.generateMachineString());
return;
}
if (call == "unlink") {
if (callFunction == "unlink") {
// first param:
std::string serviceName = data["param"].toArray()[0].toString().get();
// Check if service already link:
@ -294,7 +310,7 @@ void jus::GateWayClient::onClientData(std::string _value) {
m_interfaceClient.write(answer.generateMachineString());
return;
}
JUS_ERROR("Function does not exist ... '" << call << "'");
JUS_ERROR("Function does not exist ... '" << callFunction << "'");
answer.add("error", ejson::String("CALL-UNEXISTING"));
JUS_DEBUG("answer: " << answer.generateHumanString());
m_interfaceClient.write(answer.generateMachineString());
@ -323,8 +339,19 @@ void jus::GateWayClient::onClientData(std::string _value) {
m_interfaceClient.write(answer.generateMachineString());
} else {
JUS_ERROR("Add in link the name of the user in parameter ...");
data.remove("service");
{
//data.remove("service");
//transactionId
callActionForward(m_uid,
*it,
data["call"].toString().get(),
data["param"].toArray(),
[=](jus::FutureBase _ret) {
ejson::Object tmpp = _ret.getRaw();
tmpp["id"] = data["id"];
JUS_DEBUG(" ==> transmit");
m_interfaceClient.write(tmpp.generateMachineString());
});
/*
std::unique_lock<std::mutex> lock(m_mutex);
m_actions.push_back(std::make_pair(transactionId,
[=](ejson::Object& _data) {
@ -333,41 +360,82 @@ void jus::GateWayClient::onClientData(std::string _value) {
}));
}
(*it)->SendData(m_uid, data);
*/
}
}
}
}
void jus::GateWayClient::returnMessage(ejson::Object _data) {
JUS_DEBUG("answer: " << _data.generateHumanString());
int32_t id = _data["id"].toNumber().get();
if (id == 0) {
JUS_ERROR("gateway reject transaction ... ==> No 'id' or 'id' == 0");
return;
jus::FutureBase jus::GateWayClient::callActionForward(uint64_t _callerId, ememory::SharedPtr<jus::GateWayService> _srv, const std::string& _functionName, ejson::Array _params, jus::FutureData::ObserverFinish _callback) {
uint64_t id = getId();
ejson::Object callElem = jus::createCallJson(id, _functionName, _params);
return callJson(_callerId, _srv, id, callElem, _callback);
}
uint64_t jus::GateWayClient::getId() {
return m_transactionLocalId++;
}
jus::FutureBase jus::GateWayClient::callJson(uint64_t _callerId, ememory::SharedPtr<jus::GateWayService> _srv, uint64_t _transactionId, const ejson::Object& _obj, jus::FutureData::ObserverFinish _callback) {
JUS_VERBOSE("Send JSON [START] ");
if (_srv == nullptr) {
ejson::Object obj;
obj.add("error", ejson::String("NOT-CONNECTED"));
obj.add("error-help", ejson::String("Client interface not connected (no TCP)"));
return jus::FutureBase(_transactionId, true, obj, _callback);
}
jus::GateWayClient::Observer obs;
ejson::Object localData;
jus::FutureBase tmpFuture(_transactionId, _callback);
{
std::unique_lock<std::mutex> lock(m_mutex);
auto it = m_actions.begin();
while (it != m_actions.end()) {
if (it->first != id) {
m_pendingCall.push_back(tmpFuture);
}
_srv->SendData(_callerId, _obj);
JUS_VERBOSE("Send JSON [STOP]");
return tmpFuture;
}
void jus::GateWayClient::returnMessage(ejson::Object _data) {
jus::FutureBase future;
{
uint64_t tid = _data["id"].toNumber().get();
if (tid == 0) {
if (_data["error"].toString().get() == "PROTOCOL-ERROR") {
JUS_ERROR("Get a Protocol error ...");
std::unique_lock<std::mutex> lock(m_mutex);
for (auto &it : m_pendingCall) {
if (it.isValid() == false) {
continue;
}
it.setAnswer(_data);
}
m_pendingCall.clear();
} else {
JUS_ERROR("call with no ID ==> error ...");
}
return;
}
std::unique_lock<std::mutex> lock(m_mutex);
auto it = m_pendingCall.begin();
while (it != m_pendingCall.end()) {
if (it->isValid() == false) {
it = m_pendingCall.erase(it);
continue;
}
if (it->getTransactionId() != tid) {
++it;
continue;
}
obs = (*it).second;
m_actions.erase(it);
future = *it;
it = m_pendingCall.erase(it);
break;
}
if (obs == nullptr) {
JUS_ERROR("gateway reject transaction ... (not find answer)" << _data.generateHumanString());
}
if (future.isValid() == false) {
JUS_WARNING("Action to do ...");
return;
}
}
obs(_data);
if (id >= 0) {
m_interfaceClient.write(_data.generateMachineString());
} else {
JUS_WARNING("Action to do ...");
}
future.setAnswer(_data);
}

View File

@ -9,6 +9,8 @@
#include <ememory/memory.h>
#include <esignal/Signal.h>
#include <jus/GateWayService.h>
#include <jus/Future.h>
#include <jus/AbstractFunction.h>
@ -16,7 +18,6 @@ namespace jus {
class GateWay;
class GateWayClient {
private:
using Observer = std::function<void(ejson::Object& _data)>;
enum class state {
unconnect, // starting sate
connect, // just get a TCP connection
@ -39,9 +40,7 @@ namespace jus {
std::string m_userConnectionName;
std::string m_clientName;
std::vector<std::string> m_clientgroups;
std::mutex m_mutex;
std::vector<std::pair<int32_t, Observer>> m_actions;
int32_t m_transactionLocalId;
std::vector<std::string> m_clientServices;
public:
GateWayClient(enet::Tcp _connection, jus::GateWay* _gatewayInterface);
virtual ~GateWayClient();
@ -54,6 +53,28 @@ namespace jus {
|| m_uid2 == _id;
}
bool isAlive();
private:
std::mutex m_mutex;
std::vector<jus::FutureBase> m_pendingCall;
int32_t m_transactionLocalId;
jus::FutureBase callJson(uint64_t _callerId, ememory::SharedPtr<jus::GateWayService> _srv, uint64_t _transactionId, const ejson::Object& _obj, jus::FutureData::ObserverFinish _callback=nullptr);
uint64_t getId();
public:
template<class... _ARGS>
jus::FutureBase call(uint64_t _callerId, ememory::SharedPtr<jus::GateWayService> _srv, const std::string& _functionName, _ARGS&&... _args) {
uint64_t id = getId();
ejson::Object callElem = jus::createCall(id, _functionName, std::forward<_ARGS>(_args)...);
return callJson(_callerId, _srv, id, callElem);
}
template<class... _ARGS>
jus::FutureBase callAction(uint64_t _callerId, ememory::SharedPtr<jus::GateWayService> _srv, const std::string& _functionName, _ARGS&&... _args, jus::FutureData::ObserverFinish _callback) {
uint64_t id = getId();
ejson::Object callElem = jus::createCall(id, _functionName, std::forward<_ARGS>(_args)...);
return callJson(_callerId, _srv, id, callElem, _callback);
}
jus::FutureBase callActionForward(uint64_t _callerId, ememory::SharedPtr<jus::GateWayService> _srv, const std::string& _functionName, ejson::Array _params, jus::FutureData::ObserverFinish _callback);
};
}

View File

@ -38,8 +38,8 @@ void jus::GateWayService::stop() {
m_interfaceClient.disconnect();
}
void jus::GateWayService::SendData(int32_t _userSessionId, ejson::Object _data) {
_data.add("client-id", ejson::String(etk::to_string(_userSessionId)));
void jus::GateWayService::SendData(uint64_t _userSessionId, ejson::Object _data) {
_data.add("client-id", ejson::Number(_userSessionId));
JUS_DEBUG("Send Service: " << _data.generateHumanString());
m_interfaceClient.write(_data.generateMachineString());
}
@ -76,7 +76,7 @@ void jus::GateWayService::onServiceData(std::string _value) {
JUS_ERROR("Service interface ==> wrong service answer ==> missing 'client-id'");
return;
}
uint64_t userSessionId = etk::string_to_uint64_t(data["client-id"].toString().get());
uint64_t userSessionId = data["client-id"].toNumber().getU64();
data.remove("client-id");
data.remove("action");
m_gatewayInterface->answer(userSessionId, data);

View File

@ -26,7 +26,7 @@ namespace jus {
void stop();
void onServiceData(std::string _value);
public:
void SendData(int32_t _userSessionId, ejson::Object _data);
void SendData(uint64_t _userSessionId, ejson::Object _data);
const std::string& getName() {
return m_name;
}

View File

@ -84,11 +84,11 @@ ejson::Value jus::Service::callJson(const ejson::Object& _obj) {
// Gateway just aswer a keep alive information ...
// Nothing to do ...
} else if (event == "new") {
uint64_t clientId = etk::string_to_uint64_t(_obj["client-id"].toString().get());
uint64_t clientId = _obj["client-id"].toNumber().getU64();
std::string userName = _obj["user"].toString().get();
clientConnect(clientId, userName);
} else if (event == "delete") {
uint64_t clientId = etk::string_to_uint64_t(_obj["client-id"].toString().get());
uint64_t clientId = _obj["client-id"].toNumber().getU64();
clientDisconnect(clientId);
} else {
JUS_ERROR("Unknow event: '" << event << "'");
@ -96,9 +96,9 @@ ejson::Value jus::Service::callJson(const ejson::Object& _obj) {
return ejson::Null();
}
if (_obj.valueExist("call") == true) {
uint64_t clientId = etk::string_to_uint64_t(_obj["client-id"].toString().get());
uint64_t clientId = _obj["client-id"].toNumber().getU64();
ejson::Object tmpp = callJson2(clientId, _obj);
tmpp.add("client-id", ejson::String(etk::to_string(clientId)));
tmpp.add("client-id", ejson::Number(clientId));
return tmpp;
}
ejson::Object tmpp;

View File

@ -28,7 +28,7 @@ uint64_t jus::ServiceRemote::getId() {
return m_clientInterface->getId();
}
jus::FutureBase jus::ServiceRemote::callJson(uint64_t _transactionId, const ejson::Object& _obj) {
return m_clientInterface->callJson(_transactionId, _obj);
jus::FutureBase jus::ServiceRemote::callJson(uint64_t _transactionId, const ejson::Object& _obj, jus::FutureData::ObserverFinish _callback) {
return m_clientInterface->callJson(_transactionId, _obj, _callback);
}

View File

@ -25,7 +25,7 @@ namespace jus {
~ServiceRemote();
bool exist();
private:
jus::FutureBase callJson(uint64_t _transactionId, const ejson::Object& _obj);
jus::FutureBase callJson(uint64_t _transactionId, const ejson::Object& _obj, jus::FutureData::ObserverFinish _callback=nullptr);
uint64_t getId();
public:
template<class... _ARGS>
@ -34,6 +34,12 @@ namespace jus {
ejson::Object callElem = jus::createCall(id, _functionName, std::forward<_ARGS>(_args)...);
return callJson(id, callElem);
}
template<class... _ARGS>
jus::FutureBase callAction(const std::string& _functionName, _ARGS&&... _args, jus::FutureData::ObserverFinish _callback) {
uint64_t id = getId();
ejson::Object callElem = jus::createCall(id, _functionName, std::forward<_ARGS>(_args)...);
return callJson(id, callElem, _callback);
}
};
}

View File

@ -54,6 +54,9 @@ namespace appl {
// No specificity for this client (in case it have no special right)
return out;
}
if (client["tocken"].toString().get() != "") {
out.push_back("connected");
}
// TODO: check banishing ...
ejson::Array groups = client["group"].toArray();
for (auto it : groups) {
@ -81,6 +84,24 @@ namespace appl {
}
return false;
}
bool checkAuth(const std::string& _password) {
std::unique_lock<std::mutex> lock(m_mutex);
std::string pass = m_database["password"].toString().get();
if (pass == "") {
// pb password
return false;
}
if (pass == _password) {
return true;
}
return false;
}
std::vector<std::string> filterServices(const std::string& _clientName, std::vector<std::string> _inputList) {
std::unique_lock<std::mutex> lock(m_mutex);
std::vector<std::string> out;
// TODO: ...
return out;
}
};
class UserManager {
@ -137,41 +158,29 @@ namespace appl {
}
return out;
}
std::vector<std::string> getServices(std::string _clientName) {
std::vector<std::string> out;
if (m_user == nullptr) {
return out;
}
if (_clientName == m_user->getName()) {
out.push_back(SERVICE_NAME);
}
return out;
}
bool checkTocken(std::string _clientName, std::string _tocken) {
return m_user->checkTocken(_clientName, _tocken);
}
bool checkAuth(std::string _password) {
return m_user->checkAuth(_password);
}
std::vector<std::string> filterServices(std::string _clientName, std::vector<std::string> _currentList) {
return m_user->filterServices(_clientName, _currentList);
}
};
}
int main(int _argc, const char *_argv[]) {
etk::init(_argc, _argv);
appl::UserManager userMng;
jus::ServiceType<appl::SystemService, appl::UserManager> serviceInterface(userMng);
serviceInterface.setDescription("user interface management");
serviceInterface.setVersion("0.1.0");
serviceInterface.addAuthor("Heero Yui", "yui.heero@gmail.com");
serviceInterface.advertise("getGroups", &appl::SystemService::getGroups);
serviceInterface.setLastFuncDesc("Get list of group availlable for a client name");
serviceInterface.addLastFuncParam("clientName", "Name of the client");
serviceInterface.advertise("checkTocken", &appl::SystemService::checkTocken);
serviceInterface.advertise("getServices", &appl::SystemService::getServices);
std::string ip;
uint16_t port = 0;
for (int32_t iii=0; iii<_argc ; ++iii) {
std::string data = _argv[iii];
if (etk::start_with(data, "--ip=") == true) {
serviceInterface.propertyIp.set(std::string(&data[5]));
ip = std::string(&data[5]);
} else if (etk::start_with(data, "--port=") == true) {
serviceInterface.propertyPort.set(etk::string_to_uint16_t(std::string(&data[7])));
port = etk::string_to_uint16_t(std::string(&data[7]));
} else if ( data == "-h"
|| data == "--help") {
APPL_PRINT(etk::getApplicationName() << " - help : ");
@ -183,7 +192,35 @@ int main(int _argc, const char *_argv[]) {
}
while (true) {
APPL_INFO("===========================================================");
APPL_INFO("== JUS service: " << SERVICE_NAME << " [START]");
APPL_INFO("== JUS instanciate service: " << SERVICE_NAME << " [START]");
APPL_INFO("===========================================================");
appl::UserManager userMng;
jus::ServiceType<appl::SystemService, appl::UserManager> serviceInterface(userMng);
if (ip != "") {
serviceInterface.propertyIp.set(ip);
}
if (port != 0) {
serviceInterface.propertyPort.set(port);
}
serviceInterface.setDescription("user interface management");
serviceInterface.setVersion("0.1.0");
serviceInterface.addAuthor("Heero Yui", "yui.heero@gmail.com");
serviceInterface.advertise("checkTocken", &appl::SystemService::checkTocken);
serviceInterface.setLastFuncDesc("Check if a user tocken is correct or not");
serviceInterface.addLastFuncParam("clientName", "Name of the client");
serviceInterface.addLastFuncParam("tocken", "String containing the Tocken");
serviceInterface.advertise("checkAuth", &appl::SystemService::checkAuth);
serviceInterface.setLastFuncDesc("Check the password of the curent user");
serviceInterface.addLastFuncParam("password", "client/user password");
serviceInterface.advertise("getGroups", &appl::SystemService::getGroups);
serviceInterface.setLastFuncDesc("Get list of group availlable for a client name");
serviceInterface.addLastFuncParam("clientName", "Name of the client");
serviceInterface.advertise("filterServices", &appl::SystemService::filterServices);
serviceInterface.setLastFuncDesc("Filter a list of service with the cuurent profile of the user (restrict area)");
serviceInterface.addLastFuncParam("clientName", "Name of the client");
serviceInterface.addLastFuncParam("currentList", "Vector of name of the services");
APPL_INFO("===========================================================");
APPL_INFO("== JUS service: " << SERVICE_NAME << " [service instanciate]");
APPL_INFO("===========================================================");
serviceInterface.connect(SERVICE_NAME);
if (serviceInterface.GateWayAlive() == false) {