[DEV] start to send data to the server

This commit is contained in:
Edouard DUPIN 2016-06-03 23:45:01 +02:00
parent cf72ad71fb
commit 6d985f7d2f
17 changed files with 392 additions and 266 deletions

29
database.json_picture Normal file
View File

@ -0,0 +1,29 @@
{
"default-view": { },
"right-group": [ "public" ],
"right-user": [ ],
"group-global": [ "photo", "drawing" ],
"groups": {
"photo": {
"right-herited": false,
"right-group": [ "famille" ],
"right-user": [ "camille#atria-soft.com" ],
"sub": [ "2015", "2016" ],
"files": [ 22641, 34695 ]
},
"drawing": {
"right-herited": true,
"files": [ 33913, 262464 ]
},
"2015": {
"right-herited": true,
"sub": [ ],
"files": [ 33913 ]
},
"2016": {
"right-herited": true,
"sub": [ ],
"files": [ 33913, 262464 ]
}
}
}

View File

@ -5,6 +5,8 @@
*/
#include <jus/AbstractFunction.h>
#include <jus/debug.h>
#include <etk/os/FSNode.h>
#include <ejson/base64.h>
namespace jus {
template<> bool convertJsonTo<bool>(const ejson::Value& _value) {
return _value.toBoolean().get();
@ -62,61 +64,78 @@ namespace jus {
out.setMineType(obj["mine-type"].toString().get());
out.preSetDataSize(obj["size"].toNumber().getU64());
//out.add("type", ejson::String("file"));
// TODO : Add extended datas ...
uint64_t offset = 0;
for (auto it : obj["data"].toArray()) {
ejson::String valData = it.toString();
if (valData.get().size() != 0) {
std::vector<uint8_t> tmpData = ejson::base64::decode(valData.get());
out.setData(offset, tmpData);
offset += tmpData.size();
}
}
return out;
}
template<> ejson::Value convertToJson<bool>(const bool& _value) {
// ----------------------------------------------------------------------------------------------------
template<> ejson::Value convertToJson<bool>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const bool& _value) {
return ejson::Boolean(_value);
}
template<> ejson::Value convertToJson<std::vector<bool>>(const std::vector<bool>& _value) {
template<> ejson::Value convertToJson<std::vector<bool>>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const std::vector<bool>& _value) {
ejson::Array out;
for (const auto &it : _value) {
out.add(ejson::Boolean(it));
}
return out;
}
template<> ejson::Value convertToJson<float>(const float& _value) {
template<> ejson::Value convertToJson<float>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const float& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<double>(const double& _value) {
template<> ejson::Value convertToJson<double>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const double& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<int64_t>(const int64_t& _value) {
template<> ejson::Value convertToJson<int64_t>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const int64_t& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<int32_t>(const int32_t& _value) {
template<> ejson::Value convertToJson<int32_t>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const int32_t& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<int16_t>(const int16_t& _value) {
template<> ejson::Value convertToJson<int16_t>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const int16_t& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<int8_t>(const int8_t& _value) {
template<> ejson::Value convertToJson<int8_t>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const int8_t& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<uint64_t>(const uint64_t& _value) {
template<> ejson::Value convertToJson<uint64_t>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const uint64_t& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<uint32_t>(const uint32_t& _value) {
template<> ejson::Value convertToJson<uint32_t>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const uint32_t& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<uint16_t>(const uint16_t& _value) {
template<> ejson::Value convertToJson<uint16_t>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const uint16_t& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<uint8_t>(const uint8_t& _value) {
template<> ejson::Value convertToJson<uint8_t>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const uint8_t& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<std::string>(const std::string& _value) {
template<> ejson::Value convertToJson<std::string>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const std::string& _value) {
return ejson::String(_value);
}
template<> ejson::Value convertToJson<std::vector<std::string>>(const std::vector<std::string>& _value) {
template<> ejson::Value convertToJson<char*>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, char* const & _value) {
if (_value == nullptr) {
return ejson::String();
}
return ejson::String(_value);
}
template<> ejson::Value convertToJson<std::vector<std::string>>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const std::vector<std::string>& _value) {
ejson::Array out;
for (auto &it : _value) {
out.add(ejson::String(it));
}
return out;
}
template<> ejson::Value convertToJson<jus::FileServer>(const jus::FileServer& _value) {
template<> ejson::Value convertToJson<jus::FileServer>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const jus::FileServer& _value) {
ejson::Array out;
/*
for (auto &it : _value) {
@ -125,15 +144,63 @@ namespace jus {
*/
return out;
}
template<> ejson::Value convertToJson<jus::File>(const jus::File& _value) {
class SenderJusFile {
private:
jus::File m_data;
uint64_t m_size;
uint64_t m_offset;
int32_t m_paramID;
public:
SenderJusFile(jus::File _data, int32_t _paramID) :
m_data(_data),
m_size(m_data.getData().size()),
m_offset(0),
m_paramID(_paramID) {
}
~SenderJusFile() {
}
bool operator() (TcpString* _interface, const std::string& _service, uint64_t _transactionId, uint64_t _part) {
ejson::Object answer;
if (_service != "") {
answer.add("service", ejson::String(_service));
}
answer.add("id", ejson::Number(_transactionId));
answer.add("part", ejson::Number(_part));
if (m_paramID >= 0) {
answer.add("param-id", ejson::Number(m_paramID));
}
int32_t tmpSize = 1023;
if (m_size < 1023) {
tmpSize = m_size;
}
uint8_t tmpData[1023];
answer.add("data", ejson::String(ejson::base64::encode(&m_data.getData()[m_offset], tmpSize)));
m_offset += tmpSize;
m_size -= tmpSize;
JUS_INFO("data: " << answer.generateHumanString());
_interface->write(answer.generateMachineString());
if (m_size <= 0) {
return true;
}
return false;
}
};
template<> ejson::Value convertToJson<jus::File>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const jus::File& _value) {
ejson::Object out;
out.add("type", ejson::String("file"));
out.add("mine-type", ejson::String(_value.getMineType()));
out.add("size", ejson::Number(_value.getData().size()));
// TODO : Add extended datas ...
if (_value.getData().size() != 0) {
_asyncAction.push_back(SenderJusFile(_value, _paramId));
}
return out;
}
// ----------------------------------------------------------------------------------------------------
template<> bool convertStringTo<bool>(const std::string& _value) {
return etk::string_to_bool(_value);
}
@ -199,7 +266,7 @@ ejson::Object jus::createBaseCall(uint64_t _transactionId, const std::string& _f
obj.add("id", ejson::Number(_transactionId));
return obj;
}
void jus::createParam(ejson::Object& _obj) {
void jus::createParam(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, ejson::Object& _obj) {
// Finish recursive parse ...
}

View File

@ -60,6 +60,9 @@ namespace jus {
virtual std::string executeString(const std::vector<std::string>& _params, void* _class=nullptr) = 0;
};
// define basic async call element ...
using ActionAsyncClient = std::function<bool(TcpString* _interface, const std::string& _service, uint64_t _transactionId, uint64_t _part)>;
template<class JUS_TYPE>
JUS_TYPE convertStringTo(const std::string& _value);
@ -67,181 +70,51 @@ namespace jus {
JUS_TYPE convertJsonTo(const ejson::Value& _value);
template<class JUS_TYPE>
ejson::Value convertToJson(const JUS_TYPE& _value);
ejson::Value convertToJson(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const JUS_TYPE& _value);
//ejson::Value convertToJson(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const char* _value);
ejson::Object createBaseCall(uint64_t _transactionId, const std::string& _functionName, const std::string& _service="");
void createParam(ejson::Object& _obj);
void createParam(std::vector<ActionAsyncClient>& _asyncAction,
int32_t _paramId,
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 jus::File& _param, _ARGS&&... _args);
template<class... _ARGS>
void createParam(ejson::Object& _obj, const char* _param, _ARGS&&... _args) {
template<class JUS_TYPE, class... _ARGS>
void createParam(std::vector<ActionAsyncClient>& _asyncAction,
int32_t _paramId,
ejson::Object& _obj,
const JUS_TYPE& _param,
_ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array());
}
ejson::Array array = _obj["param"].toArray();
if (_param == nullptr) {
array.add(ejson::String());
} else {
array.add(ejson::String(_param));
}
createParam(_obj, std::forward<_ARGS>(_args)...);
array.add(convertToJson<JUS_TYPE>(_asyncAction, _paramId, _param));
_paramId++;
createParam(_asyncAction, _paramId, _obj, std::forward<_ARGS>(_args)...);
}
// convert const char in std::string ...
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::string& _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array());
}
ejson::Array array = _obj["param"].toArray();
array.add(ejson::String(_param));
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const bool& _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array());
}
ejson::Array array = _obj["param"].toArray();
array.add(ejson::Boolean(_param));
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const int32_t& _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array());
}
ejson::Array array = _obj["param"].toArray();
array.add(ejson::Number(_param));
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const double& _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array());
}
ejson::Array array = _obj["param"].toArray();
array.add(ejson::Number(_param));
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const float& _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array());
}
ejson::Array array = _obj["param"].toArray();
array.add(ejson::Number(_param));
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<std::string>& _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array());
}
ejson::Array array = _obj["param"].toArray();
ejson::Array array2;
for (auto& it : _param) {
array2.add(ejson::String(it));
}
array.add(array2);
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<bool>& _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array());
}
ejson::Array array = _obj["param"].toArray();
ejson::Array array2;
for (const auto& it : _param) {
array2.add(ejson::Boolean(it));
}
array.add(array2);
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<int32_t>& _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array());
}
ejson::Array array = _obj["param"].toArray();
ejson::Array array2;
for (auto& it : _param) {
array2.add(ejson::Number(it));
}
array.add(array2);
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<double>& _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array());
}
ejson::Array array = _obj["param"].toArray();
ejson::Array array2;
for (auto& it : _param) {
array2.add(ejson::Number(it));
}
array.add(array2);
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<float>& _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array());
}
ejson::Array array = _obj["param"].toArray();
ejson::Array array2;
for (auto& it : _param) {
array2.add(ejson::Number(it));
}
array.add(array2);
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const jus::File& _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array());
}
ejson::Array array = _obj["param"].toArray();
array.add(convertToJson<jus::File>(_param));
createParam(_obj, std::forward<_ARGS>(_args)...);
void createParam(std::vector<ActionAsyncClient>& _asyncAction,
int32_t _paramId,
ejson::Object& _obj,
const char* _param,
_ARGS&&... _args) {
createParam(_asyncAction, _paramId, _obj, std::string(_param), std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
ejson::Object createCall(uint64_t _transactionId, const std::string& _functionName, _ARGS&&... _args) {
ejson::Object createCall(std::vector<ActionAsyncClient>& _asyncAction, uint64_t _transactionId, const std::string& _functionName, _ARGS&&... _args) {
ejson::Object callElem = createBaseCall(_transactionId, _functionName);
createParam(callElem, std::forward<_ARGS>(_args)...);
createParam(_asyncAction, 0, callElem, std::forward<_ARGS>(_args)...);
return callElem;
}
template<class... _ARGS>
ejson::Object createCallService(uint64_t _transactionId, const std::string& _serviceName, const std::string& _functionName, _ARGS&&... _args) {
ejson::Object createCallService(std::vector<ActionAsyncClient>& _asyncAction, uint64_t _transactionId, const std::string& _serviceName, const std::string& _functionName, _ARGS&&... _args) {
ejson::Object callElem = createBaseCall(_transactionId, _functionName, _serviceName);
createParam(callElem, std::forward<_ARGS>(_args)...);
createParam(_asyncAction, 0, callElem, std::forward<_ARGS>(_args)...);
return callElem;
}
ejson::Object createCallJson(uint64_t _transactionId, const std::string& _functionName, ejson::Array _params);

View File

@ -23,19 +23,23 @@ namespace jus {
JUS_CLASS_TYPE* _pointer,
JUS_RETURN (JUS_CLASS_TYPE::*_func)(JUS_TYPES...),
const ejson::Array& _params) {
std::vector<ActionAsyncClient> asyncAction;
#if defined(__clang__)
// clang generate a basic warning:
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
int32_t idParam = 0;
ejson::Value ret = convertToJson((*_pointer.*_func)((convertJsonTo<JUS_TYPES>(_params[idParam++]))...));
ejson::Value ret = convertToJson(asyncAction, -1, (*_pointer.*_func)((convertJsonTo<JUS_TYPES>(_params[idParam++]))...));
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
ejson::Value ret = convertToJson((*_pointer.*_func)(convertJsonTo<JUS_TYPES>(_params[idParam--])...));
ejson::Value ret = convertToJson(asyncAction, -1, (*_pointer.*_func)(convertJsonTo<JUS_TYPES>(_params[idParam--])...));
#else
#error Must be implemented ...
ejson::Value ret = ejson::Null();
return;
#endif
if (asyncAction.size() != 0) {
JUS_ERROR("Missing send async messages");
}
ejson::Object answer;
answer.add("id", ejson::Number(_transactionId));
answer.add("client-id", ejson::Number(_clientId));

View File

@ -164,7 +164,53 @@ uint64_t jus::Client::getId() {
return m_id++;
}
jus::FutureBase jus::Client::callJson(uint64_t _transactionId, const ejson::Object& _obj, jus::FutureData::ObserverFinish _callback) {
class SendAsync {
private:
std::vector<jus::ActionAsyncClient> m_async;
uint64_t m_transactionId;
std::string m_service;
uint32_t m_partId;
public:
SendAsync(uint64_t _transactionId, const std::string& _service, const std::vector<jus::ActionAsyncClient>& _async) :
m_async(_async),
m_transactionId(_transactionId),
m_service(_service),
m_partId(1) {
}
bool operator() (jus::TcpString* _interface){
auto it = m_async.begin();
while (it != m_async.end()) {
bool ret = (*it)(_interface, m_service, m_transactionId, m_partId);
if (ret == true) {
// Remove it ...
it = m_async.erase(it);
} else {
++it;
}
m_partId++;
}
if (m_async.size() == 0) {
ejson::Object obj;
if (m_service != "") {
obj.add("service", ejson::String(m_service));
}
obj.add("id", ejson::Number(m_transactionId));
obj.add("part", ejson::Number(m_partId));
obj.add("finish", ejson::Boolean(true));
JUS_DEBUG("Send JSON '" << obj.generateHumanString() << "'");
_interface->write(obj.generateMachineString());
return true;
}
return false;
}
};
jus::FutureBase jus::Client::callJson(uint64_t _transactionId,
ejson::Object _obj,
const std::vector<ActionAsyncClient>& _async,
jus::FutureData::ObserverFinish _callback,
const std::string& _service) {
JUS_VERBOSE("Send JSON [START] ");
if (m_interfaceClient.isActive() == false) {
ejson::Object obj;
@ -177,8 +223,15 @@ jus::FutureBase jus::Client::callJson(uint64_t _transactionId, const ejson::Obje
std::unique_lock<std::mutex> lock(m_mutex);
m_pendingCall.push_back(tmpFuture);
}
if (_async.size() != 0) {
_obj.add("part", ejson::Number(0));
}
JUS_DEBUG("Send JSON '" << _obj.generateHumanString() << "'");
m_interfaceClient.write(_obj.generateMachineString());
if (_async.size() != 0) {
m_interfaceClient.addAsync(SendAsync(_transactionId, _service, _async));
}
JUS_VERBOSE("Send JSON [STOP]");
return tmpFuture;
}

View File

@ -43,20 +43,26 @@ namespace jus {
private:
void onClientData(std::string _value);
std::string asyncRead();
jus::FutureBase callJson(uint64_t _transactionId, const ejson::Object& _obj, jus::FutureData::ObserverFinish _callback=nullptr);
jus::FutureBase callJson(uint64_t _transactionId,
ejson::Object _obj,
const std::vector<ActionAsyncClient>& _async,
jus::FutureData::ObserverFinish _callback=nullptr,
const std::string& _service="");
public:
uint64_t getId();
template<class... _ARGS>
jus::FutureBase call(const std::string& _functionName, _ARGS&&... _args) {
uint64_t id = getId();
ejson::Object callElem = jus::createCall(id, _functionName, std::forward<_ARGS>(_args)...);
return callJson(id, callElem);
std::vector<ActionAsyncClient> asyncAction;
ejson::Object callElem = jus::createCall(asyncAction, id, _functionName, std::forward<_ARGS>(_args)...);
return callJson(id, callElem, asyncAction);
}
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);
std::vector<ActionAsyncClient> asyncAction;
ejson::Object callElem = jus::createCall(asyncAction, id, _functionName, std::forward<_ARGS>(_args)...);
return callJson(id, callElem, asyncAction, _callback);
}
private:
void onPropertyChangeIp();

View File

@ -4,8 +4,11 @@
* @license APACHE v2.0 (see license file)
*/
#include <jus/File.h>
#include <jus/debug.h>
#include <etk/types.h>
#include <etk/stdTools.h>
#include <jus/mineType.h>
#include <etk/os/FSNode.h>
@ -14,7 +17,14 @@ jus::File::File() {
}
jus::File::File(const std::string& _filename) {
m_data = etk::FSNodeReadAllDataType<uint8_t>(_filename);
std::string extention = std::string(_filename.begin()+_filename.size() -3, _filename.end());
JUS_WARNING("send file: '" << _filename << "' with extention: '" << extention << "'");
m_mineType = jus::getMineType(extention);
}
void jus::File::storeIn(const std::string& _filename) const {
etk::FSNodeWriteAllDataType(_filename, m_data);
}
jus::File::File(const std::string& _mineType, std::vector<uint8_t> _data):

View File

@ -15,6 +15,7 @@ namespace jus {
File();
File(const std::string& _filename);
File(const std::string& _mineType, std::vector<uint8_t> _data);
void storeIn(const std::string& _filename) const;
const std::string& getMineType() const {
return m_mineType;
}

View File

@ -219,9 +219,10 @@ void jus::FutureCall::appendData(const ejson::Object& _callValue) {
if (param.valueExist("data") == false) {
param.add("data", ejson::Array());
}
// add data in the array
param["data"].toArray().add(_callValue["data"]);
// add data in the array (only if we have local data ...
if (_callValue.valueExist("data") == true) {
param["data"].toArray().add(_callValue["data"]);
}
if (_callValue.valueExist("finish") == true) {
if (_callValue["finish"].toBoolean().get() == true) {
m_isFinished = true;

View File

@ -83,7 +83,7 @@ void jus::GateWayClient::returnBool(int32_t _transactionId, bool _value) {
void jus::GateWayClient::onClientData(std::string _value) {
JUS_DEBUG("On data: " << _value);
ejson::Object data(_value);
int32_t transactionId = data["id"].toNumber().get();
uint64_t transactionId = data["id"].toNumber().getU64();
if (transactionId == 0) {
JUS_ERROR("Protocol error ==>missing id");
protocolError("missing parameter: 'id'");
@ -274,7 +274,12 @@ void jus::GateWayClient::onClientData(std::string _value) {
linkService.add("event", ejson::String("new"));
linkService.add("user", ejson::String(m_userConnectionName));
linkService.add("client", ejson::String(m_clientName));
linkService.add("groups", convertToJson(m_clientgroups));
// TODO ==> remove events ...
std::vector<ActionAsyncClient> asyncAction;
linkService.add("groups", convertToJson(asyncAction, 0, m_clientgroups));
if (asyncAction.size() != 0) {
JUS_ERROR("Missing send async messages");
}
srv->SendData(m_uid, linkService);
m_listConnectedService.push_back(srv);
answer.add("return", ejson::Boolean(true));
@ -351,7 +356,43 @@ void jus::GateWayClient::onClientData(std::string _value) {
JUS_DEBUG("answer: " << answer.generateHumanString());
m_interfaceClient.write(answer.generateMachineString());
} else {
bool finish = false;
if (data.valueExist("finish") == true) {
finish = data["finish"].toBoolean().get();
}
int64_t partTmp = -1;
if (data.valueExist("part") == true) {
uint64_t part = data["part"].toNumber().getU64();
partTmp = part;
if (part != 0) {
// subMessage ... ==> try to forward message:
std::unique_lock<std::mutex> lock(m_mutex);
for (auto &itCall : m_pendingCall) {
JUS_INFO(" compare : " << itCall.first << " =?= " << transactionId);
if (itCall.first == transactionId) {
// Find element ==> transit it ...
if (*it == nullptr) {
// TODO ...
} else {
ejson::Object obj;
obj.add("id", ejson::Number(itCall.second.getTransactionId()));
obj.add("param-id", data["param-id"]);
obj.add("part", ejson::Number(part));
obj.add("data", data["data"]);
if (finish == true) {
obj.add("finish", ejson::Boolean(true));
}
(*it)->SendData(m_uid, obj);
}
return;
}
}
JUS_ERROR("Can not transfer part of a message ...");
return;
}
}
callActionForward(m_uid,
transactionId,
*it,
data["call"].toString().get(),
data["param"].toArray(),
@ -359,7 +400,7 @@ void jus::GateWayClient::onClientData(std::string _value) {
ejson::Object tmpp = _ret.getRaw();
JUS_VERBOSE(" ==> transmit : " << tmpp["id"].toNumber().getU64() << " -> " << data["id"].toNumber().getU64());
JUS_VERBOSE(" msg=" << tmpp.generateMachineString());
tmpp["id"].toNumber().set(data["id"].toNumber().getU64());
tmpp["id"].toNumber().set(transactionId);
JUS_DEBUG("transmit=" << tmpp.generateMachineString());
m_interfaceClient.write(tmpp.generateMachineString());
if (tmpp.valueExist("part") == true) {
@ -370,16 +411,31 @@ void jus::GateWayClient::onClientData(std::string _value) {
return false;
}
return true;
});
},
partTmp,
finish);
}
}
}
}
jus::FutureBase jus::GateWayClient::callActionForward(uint64_t _callerId, ememory::SharedPtr<jus::GateWayService> _srv, const std::string& _functionName, ejson::Array _params, jus::FutureData::ObserverFinish _callback) {
jus::FutureBase jus::GateWayClient::callActionForward(uint64_t _callerId,
uint64_t _clientTransactionId,
ememory::SharedPtr<jus::GateWayService> _srv,
const std::string& _functionName,
ejson::Array _params,
jus::FutureData::ObserverFinish _callback,
int64_t _part,
bool _finish) {
uint64_t id = getId();
ejson::Object callElem = jus::createCallJson(id, _functionName, _params);
jus::FutureBase ret = callJson(_callerId, _srv, id, callElem, _callback);
if (_part != -1) {
callElem.add("part", ejson::Number(uint64_t(_part)));
}
if (_finish == true) {
callElem.add("finish", ejson::Boolean(true));
}
jus::FutureBase ret = callJson(_callerId, _srv, _clientTransactionId, id, callElem, _callback);
ret.setSynchronous();
return ret;
}
@ -388,7 +444,7 @@ 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::FutureBase jus::GateWayClient::callJson(uint64_t _callerId, ememory::SharedPtr<jus::GateWayService> _srv, uint64_t _clientTransactionId, uint64_t _transactionId, const ejson::Object& _obj, jus::FutureData::ObserverFinish _callback) {
JUS_VERBOSE("Send JSON [START] ");
if (_srv == nullptr) {
ejson::Object obj;
@ -399,7 +455,7 @@ jus::FutureBase jus::GateWayClient::callJson(uint64_t _callerId, ememory::Shared
jus::FutureBase tmpFuture(_transactionId, _callback);
{
std::unique_lock<std::mutex> lock(m_mutex);
m_pendingCall.push_back(tmpFuture);
m_pendingCall.push_back(std::make_pair(_clientTransactionId, tmpFuture));
}
_srv->SendData(_callerId, _obj);
JUS_VERBOSE("Send JSON [STOP]");
@ -416,10 +472,10 @@ void jus::GateWayClient::returnMessage(ejson::Object _data) {
JUS_ERROR("Get a Protocol error ...");
std::unique_lock<std::mutex> lock(m_mutex);
for (auto &it : m_pendingCall) {
if (it.isValid() == false) {
if (it.second.isValid() == false) {
continue;
}
it.setAnswer(_data);
it.second.setAnswer(_data);
}
m_pendingCall.clear();
} else {
@ -431,16 +487,16 @@ void jus::GateWayClient::returnMessage(ejson::Object _data) {
std::unique_lock<std::mutex> lock(m_mutex);
auto it = m_pendingCall.begin();
while (it != m_pendingCall.end()) {
if (it->isValid() == false) {
if (it->second.isValid() == false) {
it = m_pendingCall.erase(it);
continue;
}
if (it->getTransactionId() != tid) {
if (it->second.getTransactionId() != tid) {
++it;
continue;
}
// TODO : Do it better ...
future = *it;
future = it->second;
break;
}
}
@ -453,11 +509,11 @@ void jus::GateWayClient::returnMessage(ejson::Object _data) {
std::unique_lock<std::mutex> lock(m_mutex);
auto it = m_pendingCall.begin();
while (it != m_pendingCall.end()) {
if (it->isValid() == false) {
if (it->second.isValid() == false) {
it = m_pendingCall.erase(it);
continue;
}
if (it->getTransactionId() != tid) {
if (it->second.getTransactionId() != tid) {
++it;
continue;
}

View File

@ -57,24 +57,39 @@ namespace jus {
private:
std::mutex m_mutex;
std::vector<jus::FutureBase> m_pendingCall;
std::vector<std::pair<uint64_t, 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);
jus::FutureBase callJson(uint64_t _callerId, ememory::SharedPtr<jus::GateWayService> _srv, uint64_t _clientTransactionId, 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);
std::vector<ActionAsyncClient> asyncAction;
ejson::Object callElem = jus::createCall(asyncAction, id, _functionName, std::forward<_ARGS>(_args)...);
if (asyncAction.size() != 0) {
JUS_ERROR("Missing send async messages");
}
return callJson(_callerId, _srv, 0, 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);
std::vector<ActionAsyncClient> asyncAction;
ejson::Object callElem = jus::createCall(asyncAction, id, _functionName, std::forward<_ARGS>(_args)...);
if (asyncAction.size() != 0) {
JUS_ERROR("Missing send async messages");
}
return callJson(_callerId, _srv, 0, 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);
jus::FutureBase callActionForward(uint64_t _callerId,
uint64_t _clientTransactionId,
ememory::SharedPtr<jus::GateWayService> _srv,
const std::string& _functionName,
ejson::Array _params,
jus::FutureData::ObserverFinish _callback,
int64_t _part,
bool _finish);
};
}

View File

@ -43,8 +43,10 @@ void jus::Service::onClientData(std::string _value) {
while (it != m_callMultiData.end()) {
if ( it->getTransactionId() == tmpID
&& it->getClientId() == clientId) {
JUS_WARNING("Append data ... " << tmpID);
it->appendData(request);
if (it->isFinished() == true) {
JUS_WARNING("CALL Function ...");
callJson(tmpID, it->getRaw());
it = m_callMultiData.erase(it);
}

View File

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

View File

@ -25,20 +25,22 @@ namespace jus {
~ServiceRemote();
bool exist();
private:
jus::FutureBase callJson(uint64_t _transactionId, const ejson::Object& _obj, jus::FutureData::ObserverFinish _callback=nullptr);
jus::FutureBase callJson(uint64_t _transactionId, const ejson::Object& _obj, const std::vector<ActionAsyncClient>& _async, jus::FutureData::ObserverFinish _callback=nullptr);
uint64_t getId();
public:
template<class... _ARGS>
jus::FutureBase call(const std::string& _functionName, _ARGS&&... _args) {
uint64_t id = getId();
ejson::Object callElem = jus::createCallService(id, m_name, _functionName, std::forward<_ARGS>(_args)...);
return callJson(id, callElem);
std::vector<ActionAsyncClient> asyncActionToDo;
ejson::Object callElem = jus::createCallService(asyncActionToDo, id, m_name, _functionName, std::forward<_ARGS>(_args)...);
return callJson(id, callElem, asyncActionToDo);
}
template<class... _ARGS>
jus::FutureBase callAction(const std::string& _functionName, _ARGS&&... _args, jus::FutureData::ObserverFinish _callback) {
uint64_t id = getId();
ejson::Object callElem = jus::createCallService(id, m_name, _functionName, std::forward<_ARGS>(_args)...);
return callJson(id, callElem, _callback);
std::vector<ActionAsyncClient> asyncActionToDo;
ejson::Object callElem = jus::createCallService(asyncActionToDo, id, m_name, _functionName, std::forward<_ARGS>(_args)...);
return callJson(id, callElem, asyncActionToDo, _callback);
}
};
}

View File

@ -56,7 +56,7 @@ namespace jus {
return m_lastSend;
}
private:
using ActionAsync = std::function<bool(TcpString* _interface)>;
using ActionAsync = std::function<bool(TcpString* _interface)>;
std::mutex m_threadAsyncMutex;
std::thread* m_threadAsync;
bool m_threadAsyncRunning;

View File

@ -86,61 +86,63 @@ int main(int _argc, const char *_argv[]) {
APPL_INFO("serviceTest1.mul = " << retCall);
}
*/
APPL_INFO(" ----------------------------------");
APPL_INFO(" -- Get service system-user");
APPL_INFO(" ----------------------------------");
jus::ServiceRemote remoteServiceUser = client1.getService("system-user");
if (remoteServiceUser.exist() == true) {
jus::Future<std::vector<std::string>> retCall = remoteServiceUser.call("getGroups", "clientTest1#atria-soft.com");
retCall.wait();
APPL_INFO("system-user.getGroups() = " << retCall.get());
jus::Future<std::string> retDesc = remoteServiceUser.call("sys.getDescription");
jus::Future<std::string> retVersion = remoteServiceUser.call("sys.getVersion");
jus::Future<std::string> retType = remoteServiceUser.call("sys.getType");
jus::Future<std::vector<std::string>> retExtention = remoteServiceUser.call("srv.getExtention");
jus::Future<std::vector<std::string>> retMaintainer = remoteServiceUser.call("sys.getAuthors");
retDesc.wait();
retVersion.wait();
retType.wait();
retExtention.wait();
retMaintainer.wait();
APPL_INFO("Service: system-user");
APPL_INFO(" version : " << retVersion.get());
APPL_INFO(" type : " << retType.get());
APPL_INFO(" Extention : " << retExtention.get().size());
for (auto &it : retExtention.get()) {
APPL_INFO(" - " << it);
}
APPL_INFO(" maintainer: " << retMaintainer.get().size());
for (auto &it : retMaintainer.get()) {
APPL_INFO(" - " << it);
}
APPL_INFO(" description:");
APPL_INFO(" " << retDesc.get());
APPL_INFO(" Function List:");
jus::Future<std::vector<std::string>> retFuctions = remoteServiceUser.call("sys.getFunctions").wait();
for (auto it : retFuctions.get()) {
std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
jus::Future<std::string> retFunctionPrototype = remoteServiceUser.call("sys.getFunctionPrototype", it);
jus::Future<std::string> retFunctionHelp = remoteServiceUser.call("sys.getFunctionDescription", it);
retFunctionPrototype.wait();
retFunctionHelp.wait();
std::chrono::steady_clock::time_point stop = std::chrono::steady_clock::now();
APPL_INFO(" - " << retFunctionPrototype.get());
APPL_INFO(" " << retFunctionHelp.get());
APPL_INFO(" IO1=" << int64_t(retFunctionPrototype.getTransmitionTime().count()/1000)/1000.0 << " ms");
APPL_INFO(" IO2=" << int64_t(retFunctionHelp.getTransmitionTime().count()/1000)/1000.0 << " ms");
APPL_INFO(" IO*=" << int64_t((stop-start).count()/1000)/1000.0 << " ms");
if (false) {
APPL_INFO(" ----------------------------------");
APPL_INFO(" -- Get service system-user");
APPL_INFO(" ----------------------------------");
jus::ServiceRemote remoteServiceUser = client1.getService("system-user");
if (remoteServiceUser.exist() == true) {
jus::Future<std::vector<std::string>> retCall = remoteServiceUser.call("getGroups", "clientTest1#atria-soft.com");
retCall.wait();
APPL_INFO("system-user.getGroups() = " << retCall.get());
jus::Future<std::string> retDesc = remoteServiceUser.call("sys.getDescription");
jus::Future<std::string> retVersion = remoteServiceUser.call("sys.getVersion");
jus::Future<std::string> retType = remoteServiceUser.call("sys.getType");
jus::Future<std::vector<std::string>> retExtention = remoteServiceUser.call("srv.getExtention");
jus::Future<std::vector<std::string>> retMaintainer = remoteServiceUser.call("sys.getAuthors");
retDesc.wait();
retVersion.wait();
retType.wait();
retExtention.wait();
retMaintainer.wait();
APPL_INFO("Service: system-user");
APPL_INFO(" version : " << retVersion.get());
APPL_INFO(" type : " << retType.get());
APPL_INFO(" Extention : " << retExtention.get().size());
for (auto &it : retExtention.get()) {
APPL_INFO(" - " << it);
}
APPL_INFO(" maintainer: " << retMaintainer.get().size());
for (auto &it : retMaintainer.get()) {
APPL_INFO(" - " << it);
}
APPL_INFO(" description:");
APPL_INFO(" " << retDesc.get());
APPL_INFO(" Function List:");
jus::Future<std::vector<std::string>> retFuctions = remoteServiceUser.call("sys.getFunctions").wait();
for (auto it : retFuctions.get()) {
std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
jus::Future<std::string> retFunctionPrototype = remoteServiceUser.call("sys.getFunctionPrototype", it);
jus::Future<std::string> retFunctionHelp = remoteServiceUser.call("sys.getFunctionDescription", it);
retFunctionPrototype.wait();
retFunctionHelp.wait();
std::chrono::steady_clock::time_point stop = std::chrono::steady_clock::now();
APPL_INFO(" - " << retFunctionPrototype.get());
APPL_INFO(" " << retFunctionHelp.get());
APPL_INFO(" IO1=" << int64_t(retFunctionPrototype.getTransmitionTime().count()/1000)/1000.0 << " ms");
APPL_INFO(" IO2=" << int64_t(retFunctionHelp.getTransmitionTime().count()/1000)/1000.0 << " ms");
APPL_INFO(" IO*=" << int64_t((stop-start).count()/1000)/1000.0 << " ms");
}
}
}
APPL_INFO(" ----------------------------------");
APPL_INFO(" -- Get service picture");
APPL_INFO(" ----------------------------------");
jus::ServiceRemote remoteServicePicture = client1.getService("picture");
if (remoteServicePicture.exist() == true) {
/*
jus::Future<std::vector<std::string>> retCall = remoteServicePicture.call("getAlbums").wait();
APPL_INFO(" album list: ");
for (auto &it : retCall.get()) {
@ -179,7 +181,8 @@ int main(int _argc, const char *_argv[]) {
}
}
}
jus::File tmp("image/jpg", {0,5,2,6,7,5,8,4,5,2,1,5,65,5,2,6,85,4,6,6,54,65,88,64,14,6,4,64,51,3,16,4});
*/
jus::File tmp("./photo_2016_33913.bmp");//"image/jpg", {0,5,2,6,7,5,8,4,5,2,1,5,65,5,2,6,85,4,6,6,54,65,88,64,14,6,4,64,51,3,16,4});
jus::FutureBase retSendImage = remoteServicePicture.call("addFile", tmp).wait();
}

View File

@ -235,7 +235,8 @@ namespace appl {
}
}
*/
APPL_ERROR(" ==> Receive FILE " << _dataFile.getMineType());
APPL_ERROR(" ==> Receive FILE " << _dataFile.getMineType() << " size=" << _dataFile.getData().size());
_dataFile.storeIn("plopppp.bmp");
return "54654654654654";//jus::FileServer();
}
/*