[DEV] better integration of right and start dev of introspection of fuctions

This commit is contained in:
Edouard DUPIN 2016-05-29 23:59:19 +02:00
parent bdf4983fbe
commit 75de590480
8 changed files with 126 additions and 61 deletions

View File

@ -104,29 +104,31 @@ bool jus::FutureBase::isFinished() {
return m_data->m_isFinished; return m_data->m_isFinished;
} }
void jus::FutureBase::wait() { jus::FutureBase& jus::FutureBase::wait() {
while (isFinished() == false) { while (isFinished() == false) {
// TODO : Do it better ... like messaging/mutex_locked ... // TODO : Do it better ... like messaging/mutex_locked ...
usleep(10000); usleep(10000);
} }
return *this;
} }
bool jus::FutureBase::waitFor(std::chrono::microseconds _delta) { jus::FutureBase& jus::FutureBase::waitFor(std::chrono::microseconds _delta) {
std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now(); std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
while ( std::chrono::steady_clock::now() - start < _delta while ( std::chrono::steady_clock::now() - start < _delta
&& isFinished() == false) { && isFinished() == false) {
// TODO : Do it better ... like messaging/mutex_locked ... // TODO : Do it better ... like messaging/mutex_locked ...
usleep(10000); usleep(10000);
start = std::chrono::steady_clock::now();
} }
return isFinished(); return *this;
} }
bool jus::FutureBase::waitUntil(std::chrono::steady_clock::time_point _endTime) { jus::FutureBase& jus::FutureBase::waitUntil(std::chrono::steady_clock::time_point _endTime) {
while ( std::chrono::steady_clock::now() < _endTime while ( std::chrono::steady_clock::now() < _endTime
&& isFinished() == false) { && isFinished() == false) {
// TODO : Do it better ... like messaging/mutex_locked ... // TODO : Do it better ... like messaging/mutex_locked ...
usleep(10000); usleep(10000);
} }
return isFinished(); return *this;
} }

View File

@ -24,9 +24,9 @@ namespace jus {
std::string getErrorHelp(); std::string getErrorHelp();
bool isValid(); bool isValid();
bool isFinished(); bool isFinished();
void wait(); FutureBase& wait();
bool waitFor(std::chrono::microseconds _delta); FutureBase& waitFor(std::chrono::microseconds _delta = std::chrono::seconds(30));
bool waitUntil(std::chrono::steady_clock::time_point _endTime); FutureBase& waitUntil(std::chrono::steady_clock::time_point _endTime);
ejson::Object getRaw(); ejson::Object getRaw();
}; };
} }

View File

@ -118,6 +118,8 @@ void jus::GateWayClient::onClientData(std::string _value) {
ejson::Object linkService; ejson::Object linkService;
linkService.add("event", ejson::String("new")); linkService.add("event", ejson::String("new"));
linkService.add("user", ejson::String(m_userConnectionName)); linkService.add("user", ejson::String(m_userConnectionName));
linkService.add("client", ejson::String("**Gateway**"));
linkService.add("groups", ejson::Array());
m_userService->SendData(m_uid2, linkService); m_userService->SendData(m_uid2, linkService);
m_state = jus::GateWayClient::state::userIdentify; m_state = jus::GateWayClient::state::userIdentify;
returnBool(transactionId, true); returnBool(transactionId, true);
@ -165,7 +167,7 @@ void jus::GateWayClient::onClientData(std::string _value) {
} }
if (callFunction == "auth") { if (callFunction == "auth") {
std::string password = data["param"].toArray()[0].toString().get(); std::string password = data["param"].toArray()[0].toString().get();
jus::Future<bool> fut = call(m_uid2, m_userService, "auth", password); jus::Future<bool> fut = call(m_uid2, m_userService, "checkAuth", password);
fut.wait(); // TODO: Set timeout ... fut.wait(); // TODO: Set timeout ...
if (fut.hasError() == true) { if (fut.hasError() == true) {
JUS_ERROR("Get error from the service ..."); JUS_ERROR("Get error from the service ...");
@ -219,24 +221,24 @@ void jus::GateWayClient::onClientData(std::string _value) {
break; break;
case jus::GateWayClient::state::clientIdentify: case jus::GateWayClient::state::clientIdentify:
{ {
std::string service = data["service"].toString().get(); // This is 2 default service for the cient interface that manage the authorisation of view:
// Thsi is 2 default service for the cient interface that manage the authorisation of view: if (data.valueExist("service") == false) {
if (service == "") {
std::string callFunction = data["call"].toString().get(); std::string callFunction = data["call"].toString().get();
ejson::Object answer; ejson::Object answer;
//answer.add("from-service", ejson::String("")); //answer.add("from-service", ejson::String(""));
answer.add("id", data["id"]); answer.add("id", data["id"]);
if (callFunction == "getServiceCount") { if (callFunction == "getServiceCount") {
// TODO : Do it better: answer.add("return", ejson::Number(m_clientServices.size()));
answer.add("return", ejson::Number(2));
JUS_DEBUG("answer: " << answer.generateHumanString()); JUS_DEBUG("answer: " << answer.generateHumanString());
m_interfaceClient.write(answer.generateMachineString()); m_interfaceClient.write(answer.generateMachineString());
return; return;
} }
if (callFunction == "getServiceList") { if (callFunction == "getServiceList") {
ejson::Array listService; ejson::Array listService;
listService.add(ejson::String("ServiceManager/v0.1.0")); for (auto &it : m_clientServices) {
listService.add(ejson::String("getServiceInformation/v0.1.0")); listService.add(ejson::String(it));
}
//listService.add(ejson::String("ServiceManager/v0.1.0"));
answer.add("return", listService); answer.add("return", listService);
JUS_DEBUG("answer: " << answer.generateHumanString()); JUS_DEBUG("answer: " << answer.generateHumanString());
m_interfaceClient.write(answer.generateMachineString()); m_interfaceClient.write(answer.generateMachineString());
@ -252,14 +254,20 @@ void jus::GateWayClient::onClientData(std::string _value) {
++it; ++it;
continue; continue;
} }
if ((*it)->getName() != service) { if ((*it)->getName() != serviceName) {
++it; ++it;
continue; continue;
} }
break; break;
} }
if (it == m_listConnectedService.end()) { if (it == m_listConnectedService.end()) {
// TODO : check if we have authorisation to connect service // check if service is connectable ...
if (std::find(m_clientServices.begin(), m_clientServices.end(), serviceName) == m_clientServices.end()) {
answer.add("return", ejson::Boolean(false));
JUS_DEBUG("answer: (NOT authorized service) " << answer.generateHumanString());
m_interfaceClient.write(answer.generateMachineString());
return;
}
ememory::SharedPtr<jus::GateWayService> srv = m_gatewayInterface->get(serviceName); ememory::SharedPtr<jus::GateWayService> srv = m_gatewayInterface->get(serviceName);
if (srv != nullptr) { if (srv != nullptr) {
ejson::Object linkService; ejson::Object linkService;
@ -291,7 +299,7 @@ void jus::GateWayClient::onClientData(std::string _value) {
++it; ++it;
continue; continue;
} }
if ((*it)->getName() != service) { if ((*it)->getName() != serviceName) {
++it; ++it;
continue; continue;
} }
@ -316,6 +324,11 @@ void jus::GateWayClient::onClientData(std::string _value) {
m_interfaceClient.write(answer.generateMachineString()); m_interfaceClient.write(answer.generateMachineString());
return; return;
} }
std::string service = data["service"].toString().get();
if (service == "") {
protocolError("call with \"service\"=\"\" ==> not permited");
return;
}
auto it = m_listConnectedService.begin(); auto it = m_listConnectedService.begin();
while (it != m_listConnectedService.end()) { while (it != m_listConnectedService.end()) {
if (*it == nullptr) { if (*it == nullptr) {
@ -347,20 +360,12 @@ void jus::GateWayClient::onClientData(std::string _value) {
data["param"].toArray(), data["param"].toArray(),
[=](jus::FutureBase _ret) { [=](jus::FutureBase _ret) {
ejson::Object tmpp = _ret.getRaw(); ejson::Object tmpp = _ret.getRaw();
tmpp["id"] = data["id"]; JUS_VERBOSE(" ==> transmit : " << tmpp["id"].toNumber().getU64() << " -> " << data["id"].toNumber().getU64());
JUS_DEBUG(" ==> transmit"); JUS_VERBOSE(" msg=" << tmpp.generateMachineString());
tmpp["id"].toNumber().set(data["id"].toNumber().getU64());
JUS_VERBOSE(" msg=" << tmpp.generateMachineString());
m_interfaceClient.write(tmpp.generateMachineString()); m_interfaceClient.write(tmpp.generateMachineString());
}); });
/*
std::unique_lock<std::mutex> lock(m_mutex);
m_actions.push_back(std::make_pair(transactionId,
[=](ejson::Object& _data) {
JUS_DEBUG(" ==> transmit");
m_interfaceClient.write(_data.generateMachineString());
}));
}
(*it)->SendData(m_uid, data);
*/
} }
} }
} }

View File

@ -86,7 +86,9 @@ ejson::Value jus::Service::callJson(const ejson::Object& _obj) {
} else if (event == "new") { } else if (event == "new") {
uint64_t clientId = _obj["client-id"].toNumber().getU64(); uint64_t clientId = _obj["client-id"].toNumber().getU64();
std::string userName = _obj["user"].toString().get(); std::string userName = _obj["user"].toString().get();
clientConnect(clientId, userName); std::string clientName = _obj["client"].toString().get();
std::vector<std::string> clientGroup = convertJsonTo<std::vector<std::string>>(_obj["groups"]);
clientConnect(clientId, userName, clientName, clientGroup);
} else if (event == "delete") { } else if (event == "delete") {
uint64_t clientId = _obj["client-id"].toNumber().getU64(); uint64_t clientId = _obj["client-id"].toNumber().getU64();
clientDisconnect(clientId); clientDisconnect(clientId);
@ -95,13 +97,18 @@ ejson::Value jus::Service::callJson(const ejson::Object& _obj) {
} }
return ejson::Null(); return ejson::Null();
} }
ejson::Object tmpp;
if (_obj.valueExist("call") == true) { if (_obj.valueExist("call") == true) {
uint64_t clientId = _obj["client-id"].toNumber().getU64(); uint64_t clientId = _obj["client-id"].toNumber().getU64();
ejson::Object tmpp = callJson2(clientId, _obj); std::string call = _obj["call"].toString().get();
if (etk::start_with(call, "srv.") == true) {
tmpp.add("error", ejson::String("NOT-IMPLEMENTED-ACTION **"));
} else {
tmpp = callJson2(clientId, _obj);
}
tmpp.add("client-id", ejson::Number(clientId)); tmpp.add("client-id", ejson::Number(clientId));
return tmpp; return tmpp;
} }
ejson::Object tmpp;
tmpp.add("error", ejson::String("NOT-IMPLEMENTED-ACTION")); tmpp.add("error", ejson::String("NOT-IMPLEMENTED-ACTION"));
return tmpp; return tmpp;
} }

View File

@ -16,7 +16,11 @@
namespace jus { namespace jus {
class ClientProperty { class ClientProperty {
public: public:
ClientProperty() {} ClientProperty(const std::string& _clientName="", const std::vector<std::string>& _groups = std::vector<std::string>()) :
m_name(_clientName),
m_groups(_groups) {
}
private: private:
std::string m_name; std::string m_name;
public: public:
@ -68,7 +72,7 @@ namespace jus {
* @param[in] _userName User name of the client to connect * @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 * @todo Set a relur like ==> service not availlable / service close / service maintenance / service right reject
*/ */
virtual void clientConnect(size_t _clientSessionID, const std::string& _userName) = 0; virtual void clientConnect(size_t _clientSessionID, const std::string& _userName, const std::string& _clientName, const std::vector<std::string>& _groups) = 0;
virtual void clientDisconnect(size_t _clientSessionID) = 0; virtual void clientDisconnect(size_t _clientSessionID) = 0;
// Genenric function call: // Genenric function call:
ejson::Value callJson(const ejson::Object& _obj); ejson::Value callJson(const ejson::Object& _obj);
@ -104,10 +108,12 @@ namespace jus {
m_getUserInterface(_interface) { m_getUserInterface(_interface) {
} }
void clientConnect(uint64_t _clientSessionID, const std::string& _userName) { void clientConnect(uint64_t _clientSessionID, const std::string& _userName, const std::string& _clientName, const std::vector<std::string>& _groups) {
std::unique_lock<std::mutex> lock(m_mutex); std::unique_lock<std::mutex> lock(m_mutex);
JUS_DEBUG("connect: " << _clientSessionID << " to '" << _userName << "'"); JUS_DEBUG("connect: " << _clientSessionID << " to '" << _userName << "'");
ememory::SharedPtr<ClientProperty> tmpProperty = std::make_shared<ClientProperty>(); JUS_DEBUG(" client name='" << _clientName << "'");
JUS_DEBUG(" groups=" << etk::to_string(_groups));
ememory::SharedPtr<ClientProperty> tmpProperty = std::make_shared<ClientProperty>(_clientName, _groups);
ememory::SharedPtr<JUS_TYPE_SERVICE> tmpSrv = std::make_shared<JUS_TYPE_SERVICE>(m_getUserInterface.getUser(_userName), tmpProperty); ememory::SharedPtr<JUS_TYPE_SERVICE> tmpSrv = std::make_shared<JUS_TYPE_SERVICE>(m_getUserInterface.getUser(_userName), tmpProperty);
m_interface.insert(std::make_pair(_clientSessionID, std::make_pair(tmpProperty, tmpSrv))); m_interface.insert(std::make_pair(_clientSessionID, std::make_pair(tmpProperty, tmpSrv)));
} }

View File

@ -31,13 +31,13 @@ namespace jus {
template<class... _ARGS> template<class... _ARGS>
jus::FutureBase call(const std::string& _functionName, _ARGS&&... _args) { jus::FutureBase call(const std::string& _functionName, _ARGS&&... _args) {
uint64_t id = getId(); uint64_t id = getId();
ejson::Object callElem = jus::createCall(id, _functionName, std::forward<_ARGS>(_args)...); ejson::Object callElem = jus::createCallService(id, m_name, _functionName, std::forward<_ARGS>(_args)...);
return callJson(id, callElem); return callJson(id, callElem);
} }
template<class... _ARGS> template<class... _ARGS>
jus::FutureBase callAction(const std::string& _functionName, _ARGS&&... _args, jus::FutureData::ObserverFinish _callback) { jus::FutureBase callAction(const std::string& _functionName, _ARGS&&... _args, jus::FutureData::ObserverFinish _callback) {
uint64_t id = getId(); uint64_t id = getId();
ejson::Object callElem = jus::createCall(id, _functionName, std::forward<_ARGS>(_args)...); ejson::Object callElem = jus::createCallService(id, m_name, _functionName, std::forward<_ARGS>(_args)...);
return callJson(id, callElem, _callback); return callJson(id, callElem, _callback);
} }
}; };

View File

@ -34,43 +34,84 @@ int main(int _argc, const char *_argv[]) {
APPL_INFO("== JUS test client start =="); APPL_INFO("== JUS test client start ==");
APPL_INFO("=================================="); APPL_INFO("==================================");
client1.connect("test1#atria-soft.com"); client1.connect("test1#atria-soft.com");
// Connect that is not us if (false) {
//client1.identify("clientTest1#atria-soft.com", "QSDQSDGQSF54HSXWVCSQDJ654URTDJ654NBXCDFDGAEZ51968");
jus::Future<bool> retIdentify = client1.call("identify", "clientTest1#atria-soft.com", "QSDQSDGQSF54HSXWVCSQDJ654URTDJ654NBXCDFDGAEZ51968"); jus::Future<bool> retIdentify = client1.call("identify", "clientTest1#atria-soft.com", "QSDQSDGQSF54HSXWVCSQDJ654URTDJ654NBXCDFDGAEZ51968");
retIdentify.wait(); retIdentify.wait();
//bool retIdentify = client1.call_b("identify", "clientTest1#atria-soft.com", "QSDQSDGQSF54HSXWVCSQDJ654URTDJ654NBXCDFDGAEZ51968"); if (retIdentify.get() == false) {
APPL_ERROR(" ==> NOT Connected with 'clientTest1#atria-soft.com'");
return -1;
} else {
APPL_INFO(" ==> Connected with 'clientTest1#atria-soft.com'");
}
} else if (true) {
jus::Future<bool> retIdentify = client1.call("auth", "coucou");
retIdentify.wait();
if (retIdentify.get() == false) {
APPL_ERROR(" ==> NOT Authentify with 'test1#atria-soft.com'");
return -1;
} else {
APPL_INFO(" ==> Authentify with 'test1#atria-soft.com'");
}
} else {
jus::Future<bool> retIdentify = client1.call("anonymous");
retIdentify.wait();
if (retIdentify.get() == false) {
APPL_ERROR(" ==> NOT Connected with 'anonymous'");
return -1;
} else {
APPL_INFO(" ==> Connected with 'anonymous'");
}
}
// Connect to ourself: // Connect to ourself:
//client1.authentificate("coucou"); //client1.authentificate("coucou");
//bool retAuthentify = client1.call_b("authentify", "coucou"); //bool retAuthentify = client1.call_b("authentify", "coucou");
APPL_INFO(" ----------------------------------"); APPL_INFO(" ----------------------------------");
APPL_INFO(" -- Get service count --"); APPL_INFO(" -- Get service count");
APPL_INFO(" ----------------------------------"); APPL_INFO(" ----------------------------------");
/* jus::Future<int32_t> retNbService = client1.call("getServiceCount");
std::vector<double> tmp; retNbService.wait();
tmp.push_back(1); APPL_INFO("Nb services = " << retNbService.get());
tmp.push_back(22); jus::Future<std::vector<std::string>> retServiceList = client1.call("getServiceList");
tmp.push_back(333); retServiceList.wait();
tmp.push_back(4444);
int32_t val = client1.call_i("getServiceCount", tmp, "coucou", false);
APPL_INFO("Nb services = " << val);
std::vector<std::string> val2 = client1.call_vs("getServiceList");
APPL_INFO("List services:"); APPL_INFO("List services:");
for (auto &it: val2) { for (auto &it: retServiceList.get()) {
APPL_INFO(" - " << it); APPL_INFO(" - " << it);
} }
/*
jus::ServiceRemote localService = client1.getService("serviceTest1"); jus::ServiceRemote localService = client1.getService("serviceTest1");
if (localService.exist() == true) { if (localService.exist() == true) {
double retCall = localService.call_d("mul", 13.1, 2.0); double retCall = localService.call_d("mul", 13.1, 2.0);
APPL_INFO("serviceTest1.mul = " << retCall); APPL_INFO("serviceTest1.mul = " << retCall);
} }
*/ */
APPL_INFO(" ----------------------------------");
APPL_INFO(" -- Get service system-user");
APPL_INFO(" ----------------------------------");
jus::ServiceRemote remoteServiceUser = client1.getService("system-user"); jus::ServiceRemote remoteServiceUser = client1.getService("system-user");
if (remoteServiceUser.exist() == true) { if (remoteServiceUser.exist() == true) {
jus::Future<std::vector<std::string>> retCall = client1.call("getClientGroups", "clientTest1#atria-soft.com"); jus::Future<std::vector<std::string>> retCall = remoteServiceUser.call("getGroups", "clientTest1#atria-soft.com");
retCall.wait(); retCall.wait();
APPL_INFO("system-user.getGroups() = " << retCall.get());
jus::Future<std::string> retVersion = remoteServiceUser.call("srv.getVersion");
jus::Future<std::string> retType = remoteServiceUser.call("srv.getType");
jus::Future<std::vector<std::string>> retExtention = remoteServiceUser.call("srv.getExtention");
jus::Future<std::vector<std::string>> retMaintainer = remoteServiceUser.call("srv.getMaintainer");
jus::Future<std::vector<std::string>> retFuctions = remoteServiceUser.call("srv.getFunctions");
jus::Future<std::vector<std::string>> retFunctionSignature = remoteServiceUser.call("srv.getFunctionSignature", "filterServices");
jus::Future<std::string> retFunctionPrototype = remoteServiceUser.call("srv.getFunctionPrototype", "filterServices");
jus::Future<std::string> retFunctionHelp = remoteServiceUser.call("srv.getFunctionHelp", "filterServices");
retVersion.wait();
retType.wait();
retExtention.wait();
retMaintainer.wait();
retFuctions.wait();
retFunctionSignature.wait();
retFunctionPrototype.wait();
retFunctionHelp.wait();
APPL_INFO("system-user.getClientGroups() = " << retCall.get()); APPL_INFO("system-user.getClientGroups() = " << retCall.get());
} }
int32_t iii=0; int32_t iii=0;
while (iii < 3) { while (iii < 3) {
@ -80,7 +121,7 @@ int main(int _argc, const char *_argv[]) {
} }
client1.disconnect(); client1.disconnect();
APPL_INFO("=================================="); APPL_INFO("==================================");
APPL_INFO("== JUS test client stop =="); APPL_INFO("== JUS test client stop");
APPL_INFO("=================================="); APPL_INFO("==================================");
return 0; return 0;
} }

View File

@ -98,8 +98,12 @@ namespace appl {
} }
std::vector<std::string> filterServices(const std::string& _clientName, std::vector<std::string> _inputList) { std::vector<std::string> filterServices(const std::string& _clientName, std::vector<std::string> _inputList) {
std::unique_lock<std::mutex> lock(m_mutex); std::unique_lock<std::mutex> lock(m_mutex);
// When connected to our session ==> we have no control access ...
if (_clientName == m_userName) {
return _inputList;
}
std::vector<std::string> out; std::vector<std::string> out;
// TODO: ... APPL_TODO("Filter service list ==> not implemented...");
return out; return out;
} }
}; };