提交 f0a62f3b authored 作者: blu's avatar blu

refactor communitation archtecture to use evdamon only

上级 bce9f55b
......@@ -4,7 +4,8 @@
"files.associations": {
"chrono": "cpp",
"optional": "cpp",
"string": "cpp"
"string": "cpp",
"set": "cpp"
},
"C_Cpp.errorSquiggles": "Disabled"
}
\ No newline at end of file
......@@ -391,22 +391,22 @@ togo_end:
spdlog::error("failed to save new generated sn");
exit(1);
}else{
// replace sn
size_t idx = 0;
for(auto &j:_sn_tmpl) {
idx = 0;
while(true) {
idx = _config_default_tmpl.find(j, idx);
if(idx == string::npos) break;
_config_default_tmpl.replace(idx, j.size(), sn);
idx+=sn.size();
}
}
// replace camera addr, user, password, cloud-addr
spdlog::debug("new config: {}", _config_default_tmpl);
json j = json::parse(_config_default_tmpl);
return setLocalConfig(j);
// // replace sn
// size_t idx = 0;
// for(auto &j:_sn_tmpl) {
// idx = 0;
// while(true) {
// idx = _config_default_tmpl.find(j, idx);
// if(idx == string::npos) break;
// _config_default_tmpl.replace(idx, j.size(), sn);
// idx+=sn.size();
// }
// }
// // replace camera addr, user, password, cloud-addr
// spdlog::debug("new config: {}", _config_default_tmpl);
// json j = json::parse(_config_default_tmpl);
// return setLocalConfig(j);
}
}
......@@ -418,26 +418,6 @@ togo_end:
return setValue(info, LVDB_KEY_SN, fileName, _validateSn);
};
// int setSn(json &info) {
// std::ifstream i("file.json");
// json j;
// i >> j;
// // write prettified JSON to another file
// std::ofstream o("pretty.json");
// o << std::setw(4) << j << std::endl;
// return -1;
// }
// int getSn(json &info) {
// fstream file;
// file.open(LVDB_KEY_SN, ios::out|ios);
// if(snfile.e)
// json j;
// i >> j;
// // write prettified JSON to another file
// std::ofstream o("pretty.json");
// o << std::setw(4) << j << std::endl;
// }
// config
int _validateConfig(const json &config) {
if(config.count("data") == 0|| config["data"].size() == 0) {
......
......@@ -6,6 +6,7 @@ update: 2019/09/02
*/
#include <chrono>
#include <set>
#include "inc/tinythread.hpp"
#include "inc/httplib.h"
#include "inc/database.h"
......@@ -20,63 +21,85 @@ using namespace nlohmann;
//
class HttpSrv{
#define KEY_CONFIG_MAP "configmap"
private:
class HttpSrv {
#define KEY_CONFIG_MAP "configmap"
private:
Server svr;
// sn:module -> sn_of_evmgr
json configMap;
json config(json &newConfig){
json config(json &newConfig)
{
json ret;
int iret;
json oldConfigMap = this->configMap;
ret["code"] = 0;
ret["msg"] = "ok";
ret["time"] = chrono::duration_cast<chrono::seconds>(chrono::system_clock::now().time_since_epoch()).count();
spdlog::info(newConfig.dump());
try{
spdlog::info(newConfig.dump());
try {
if(newConfig.count("data") == 0 || newConfig["data"].size() == 0) {
ret["code"] = 1;
ret["msg"] = "evcloudsvc invalid config body received: " + newConfig.dump(4);
spdlog::error(ret["msg"].get<string>());
}else{
}
else {
json &data = newConfig["data"];
for(auto &[k, v]: data.items()) {
// TODO: confirm overwrite, take snapshot
if(this->configMap.count(k) != 0) {
spdlog::warn("evcloudsvc TODO: key {} already exist, take snapshot for safety", k);
}
// this is one evmgr
if(v.count("sn") == 0||v["sn"] != k) {
ret["code"] = 2;
ret["msg"] = "evcloudsvc invalid value for key " + k;
spdlog::error(ret["msg"].get<string>());
break;
}else{
}
else {
// find all modules
if(v.count("ipcs") == 0||v["ipcs"].size() == 0) {
spdlog::error("invalid ipcs in config body");
ret["code"] = 3;
break;
}else{
}
else {
json &ipcs = v["ipcs"];
for(auto &ipc : ipcs) {
if(ipc.count("modules") == 0||ipc["modules"].size() == 0) {
spdlog::error("invalid modules in ipcs config body");
ret["code"] = 4;
break;
}else{
}
else {
json &modules = ipc["modules"];
for(auto &[mn, ma]: modules.items()) {
for(auto &m:ma) {
if(m.count("sn") != 0 && m["sn"].size() != 0){
if(m.count("sn") != 0 && m["sn"].size() != 0) {
string modKey;
string sn = m["sn"];
//ml
if(mn == "evml" && m.count("type") != 0 && m["type"].size() != 0) {
modKey = m["sn"].get<string>() +":evml:" + m["type"].get<string>();
}else{
modKey = m["sn"].get<string>() + ":" + mn;
modKey = sn +":evml:" + m["type"].get<string>();
}
else {
modKey = sn + ":" + mn;
}
// modules
if(this->configMap["sn2mods"].count(sn) == 0) {
this->configMap["sn2mods"][sn] = json();
}
this->configMap["sn2mods"][sn].push_back(modKey);
// modkey -> sn_of_evmgr
this->configMap[modKey] = k;
}else{
this->configMap["mod2mgr"][modKey] = k;
}
else {
string msg = "evcloudsvc invalid config: " + data.dump(4);;
ret["code"] = -1;
ret["msg"] = msg;
......@@ -91,16 +114,18 @@ class HttpSrv{
}
} // for ipc
}
}
}
if(ret["code"] != 0) {
break;
}
}
}
// update evmgr config
json evmgrData;
evmgrData["data"] = data;
this->configMap[k] = k;
//save
iret = LVDB::setLocalConfig(evmgrData, k);
if(iret < 0) {
......@@ -115,128 +140,143 @@ class HttpSrv{
if(ret["code"] == 0) {
iret = LVDB::setValue(this->configMap, KEY_CONFIG_MAP);
if(iret >= 0) {
}else{
}
else {
ret["code"] = iret;
ret["msg"] = "failed to save configmap";
}
}else{
}
else {
this->configMap = oldConfigMap;
}
ret["data"] = newConfig["data"];
ret["data"] = newConfig["data"];
}
}catch(exception &e) {
}
catch(exception &e) {
ret.clear();
ret["code"] = -1;
ret["msg"] = e.what();
}
return ret;
}
protected:
public:
void run(){
protected:
public:
void run()
{
// load configmap
json cnfm;
LVDB::getValue(cnfm, KEY_CONFIG_MAP);
if(cnfm.size() != 0){
int ret = LVDB::getValue(cnfm, KEY_CONFIG_MAP);
if(ret < 0 || cnfm.size() == 0) {
this->configMap["sn2mods"] = json();
this->configMap["mod2mgr"] = json();
int iret = LVDB::setValue(this->configMap, KEY_CONFIG_MAP);
if(iret >= 0) {
}
else {
spdlog::error("evcloudsvc failed to save configmap");
exit(1);
}
}
else {
this->configMap = cnfm;
}
svr.Post("/register", [this](const Request& req, Response& res){
json ret;
try{
string sn = req.get_param_value("sn");
string module = req.get_param_value("module");
bool force = (req.get_param_value("force") == "true") ? true: false;
// svr.Post("/register", [this](const Request& req, Response& res){
// json ret;
// try{
// string sn = req.get_param_value("sn");
// string module = req.get_param_value("module");
// bool force = (req.get_param_value("force") == "true") ? true: false;
if(sn.empty()||module.empty()){
throw StrException("no para sn/module");
}
// if(sn.empty()||module.empty()){
// throw StrException("no para sn/module");
// }
auto cfg = json::parse(req.body);
string key, modname;
if(module == "evmgr") {
key = sn;
// trigger exception
(void)cfg.at("data").at(key);
}else {
if(modname == "evml") {
string
modname = "evml:" + module.substr(4, module.size());
}else{
modname = module;
}
modname = sn + ":" + modname;
if(this->configMap.count(modname) == 0){
spdlog::info("evcloudsvc no such edge module registred: {}, create new entry", key);
ret = this->config(cfg);
if(ret["code"] == 0) {
}else{
spdlog::error("failed to config: {}", ret.dump(4));
}
}else{
key = configMap[modname];
}
}
if(!key.empty()){
// TODO: calc md5
spdlog::info("evcloudsvc key: {}", key);
int r;
ret["code"] = 0;
ret["msg"] = "diff";
json data;
r = LVDB::getLocalConfig(data, key);
if(r < 0||force) {
spdlog::error("failed to get localconfig or force to updaste. create new");
ret = this->config(cfg);
}else{
json diff = json::diff(cfg, data);
spdlog::info("evcloudsvc diff: {}", diff.dump(4));
ret["data"] = diff;
}
}
}catch(exception &e) {
ret.clear();
ret["code"] = -1;
ret["msg"] = e.what();
}
// auto cfg = json::parse(req.body);
// string key, modname;
// if(module == "evmgr") {
// key = sn;
// // trigger exception
// (void)cfg.at("data").at(key);
// }else {
// if(modname == "evml") {
// string
// modname = "evml:" + module.substr(4, module.size());
res.set_content(ret.dump(), "text/json");
});
// }else{
// modname = module;
// }
// modname = sn + ":" + modname;
// if(this->configMap.count(modname) == 0){
// spdlog::info("evcloudsvc no such edge module registred: {}, create new entry", key);
// ret = this->config(cfg);
// if(ret["code"] == 0) {
// }else{
// spdlog::error("failed to config: {}", ret.dump(4));
// }
// }else{
// key = configMap[modname];
// }
// }
// if(!key.empty()){
// // TODO: calc md5
// spdlog::info("evcloudsvc key: {}", key);
// int r;
// ret["code"] = 0;
// ret["msg"] = "diff";
// json data;
// r = LVDB::getLocalConfig(data, key);
// if(r < 0||force) {
// spdlog::error("failed to get localconfig or force to updaste. create new");
// ret = this->config(cfg);
// }else{
// json diff = json::diff(cfg, data);
// spdlog::info("evcloudsvc diff: {}", diff.dump(4));
// ret["data"] = diff;
// }
// }
// }catch(exception &e) {
// ret.clear();
// ret["code"] = -1;
// ret["msg"] = e.what();
// }
// res.set_content(ret.dump(), "text/json");
svr.Get("/config", [this](const Request& req, Response& res){
// });
svr.Get("/config", [this](const Request& req, Response& res) {
json ret;
ret["code"] = 0;
ret["time"] = chrono::duration_cast<chrono::seconds>(chrono::system_clock::now().time_since_epoch()).count();
ret["msg"] = "ok";
string sn = req.get_param_value("sn");
string module = req.get_param_value("module");
if(sn.empty() || module.empty() || module.size()< 4){
ret["code"] = 1;
ret["msg"] = "evcloud bad req: no sn/module param";
spdlog::error(ret["msg"].get<string>());
}else{
try{
try {
if(!sn.empty() && !module.empty() && module.size()> 4) {
spdlog::info("evcloudsvc get module config with sn {}, module {}", sn, module);
string modname = module.substr(0,4);
string key;
if(module == "evmgr") {
key = sn;
}else {
}
else {
if(modname == "evml") {
modname = "evml:" + module.substr(4, module.size());
}else{
}
else {
modname = module;
}
key = this->configMap.at(sn + ":" + modname);
key = this->configMap["mod2mgr"].at(sn + ":" + modname);
spdlog::debug("key: ", key);
}
if(!key.empty()) {
json config;
int iret = LVDB::getLocalConfig(config, key);
......@@ -244,31 +284,80 @@ class HttpSrv{
ret["code"] = 1;
ret["msg"] = "evcloud failed to get config with key: " + key ;
spdlog::error(ret["msg"].get<string>());
}else{
}
else {
ret["data"] = config["data"];
ret["lastupdated"] = config["lastupdated"];
}
}else{
}
else {
ret["code"] = 1;
ret["msg"] = "no config for sn " + sn + ", module " + module;
}
}catch(exception &e){
ret["code"] = -1;
ret["msg"] = string("evcloudsvc exception: ") + e.what();
spdlog::error(ret["msg"].get<string>());
}
}
else if(!sn.empty() && module.empty()) {
spdlog::info("evcloudsvc get config for sn {}", sn);
if(this->configMap["sn2mods"].count(sn) != 0) {
auto mods = this->configMap["sn2mods"][sn];
set<string> s;
for(const string & elem : mods) {
s.insert(this->configMap["mod2mgr"][elem].get<string>());
spdlog::info("evcloudsvc {}->{}", elem, this->configMap["mod2mgr"][elem].get<string>());
}
json data;
for(auto &key : s) {
json cfg;
int iret = LVDB::getLocalConfig(cfg, key);
if(iret < 0) {
ret["code"] = 1;
ret["msg"] = "evcloud failed to get config with key: " + key ;
spdlog::error(ret["msg"].get<string>());
}
else {
for(auto &[k,v]: cfg["data"].items()) {
if(data.count(k) != 0) {
json diff = json::diff(data[k], v);
if(diff.size() != 0) {
string msg = "evcloudsvc inconsistent configuration for k,v, newv: " + k + ",\n" + data[k].dump(4) + "new v:\n" + v.dump(4);
ret["code"] = 3;
ret["msg"] = msg;
break;
}
}
else {
data[k] = v;
}
} // for each mgr
if(ret["code"] != 0) {
break;
}
}
} // for keys of mgr
ret["data"] = data;
}
}
}
catch(exception &e) {
ret["code"] = -1;
ret["msg"] = string("evcloudsvc exception: ") + e.what();
spdlog::error(ret["msg"].get<string>());
}
res.set_content(ret.dump(), "text/json");
});
svr.Post("/config", [this](const Request& req, Response& res){
svr.Post("/config", [this](const Request& req, Response& res) {
json ret;
string msg;
try{
try {
json cfg = json::parse(req.body);
ret = this->config(cfg);
}catch (exception &e) {
}
catch (exception &e) {
msg = string("evcloudsvc exception on POST /config: ") + e.what();
ret["msg"] = msg;
ret["code"]= -1;
......@@ -276,25 +365,26 @@ class HttpSrv{
res.set_content(ret.dump(), "text/json");
});
svr.Post("/reset", [](const Request& req, Response& res){
svr.Post("/reset", [](const Request& req, Response& res) {
});
svr.Get("/keys", [](const Request& req, Response& res){
svr.Get("/keys", [](const Request& req, Response& res) {
string fileName = req.get_param_value("filename");
auto v = LVDB::getKeys(fileName);
json ret = v;
res.set_content(ret.dump(), "text/json");
});
svr.Get("/value", [](const Request& req, Response& res){
svr.Get("/value", [](const Request& req, Response& res) {
string key = req.get_param_value("key");
string filename = req.get_param_value("filename");
json j;
int ret = LVDB::getValue(j, key, filename);
if(ret < 0) {
j["code"] = 1;
}else{
}
else {
j["code"] = 0;
}
res.set_content(j.dump(), "text/json");
......@@ -303,13 +393,15 @@ class HttpSrv{
svr.listen("0.0.0.0", 8089);
}
HttpSrv(){
HttpSrv()
{
};
~HttpSrv(){};
~HttpSrv() {};
};
int main() {
int main()
{
HttpSrv srv;
srv.run();
}
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论