[DEV] clean connect interface with the gateway
This commit is contained in:
parent
3ef98f5693
commit
bdf4983fbe
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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() {
|
||||
|
@ -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();
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user