try to create a launcher and a package group
This commit is contained in:
parent
940dc0458a
commit
9b7cff391d
@ -4,5 +4,7 @@ tools/service-user
|
|||||||
tools/service-picture
|
tools/service-picture
|
||||||
tools/service-video
|
tools/service-video
|
||||||
tools/player-video
|
tools/player-video
|
||||||
|
tools/package-base
|
||||||
|
tools/launcher
|
||||||
test/client
|
test/client
|
||||||
test/service1
|
test/service1
|
12
tools/launcher/appl/debug.cpp
Normal file
12
tools/launcher/appl/debug.cpp
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2016, Edouard DUPIN, all right reserved
|
||||||
|
* @license APACHE v2.0 (see license file)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <appl/debug.hpp>
|
||||||
|
|
||||||
|
int32_t appl::getLogId() {
|
||||||
|
static int32_t g_val = elog::registerInstance("zeus-launcher");
|
||||||
|
return g_val;
|
||||||
|
}
|
40
tools/launcher/appl/debug.hpp
Normal file
40
tools/launcher/appl/debug.hpp
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2016, Edouard DUPIN, all right reserved
|
||||||
|
* @license APACHE v2.0 (see license file)
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <elog/log.hpp>
|
||||||
|
|
||||||
|
namespace appl {
|
||||||
|
int32_t getLogId();
|
||||||
|
};
|
||||||
|
|
||||||
|
#define APPL_BASE(info,data) ELOG_BASE(appl::getLogId(),info,data)
|
||||||
|
|
||||||
|
#define APPL_PRINT(data) APPL_BASE(-1, data)
|
||||||
|
#define APPL_CRITICAL(data) APPL_BASE(1, data)
|
||||||
|
#define APPL_ERROR(data) APPL_BASE(2, data)
|
||||||
|
#define APPL_WARNING(data) APPL_BASE(3, data)
|
||||||
|
#ifdef DEBUG
|
||||||
|
#define APPL_INFO(data) APPL_BASE(4, data)
|
||||||
|
#define APPL_DEBUG(data) APPL_BASE(5, data)
|
||||||
|
#define APPL_VERBOSE(data) APPL_BASE(6, data)
|
||||||
|
#define APPL_TODO(data) APPL_BASE(4, "TODO : " << data)
|
||||||
|
#else
|
||||||
|
#define APPL_INFO(data) do { } while(false)
|
||||||
|
#define APPL_DEBUG(data) do { } while(false)
|
||||||
|
#define APPL_VERBOSE(data) do { } while(false)
|
||||||
|
#define APPL_TODO(data) do { } while(false)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define APPL_ASSERT(cond,data) \
|
||||||
|
do { \
|
||||||
|
if (!(cond)) { \
|
||||||
|
APPL_CRITICAL(data); \
|
||||||
|
assert(!#cond); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
94
tools/launcher/appl/main.cpp
Normal file
94
tools/launcher/appl/main.cpp
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||||
|
* @license APACHE v2.0 (see license file)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <appl/debug.hpp>
|
||||||
|
#include <etk/etk.hpp>
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <etk/os/FSNode.hpp>
|
||||||
|
#include <sstream>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
#include <etk/stdTools.hpp>
|
||||||
|
|
||||||
|
typedef bool (*SERVICE_IO_init_t)(std::string _basePath);
|
||||||
|
typedef bool (*SERVICE_IO_uninit_t)();
|
||||||
|
typedef bool (*SERVICE_IO_execute_t)(std::string _ip, uint16_t _port);
|
||||||
|
|
||||||
|
int main(int _argc, const char *_argv[]) {
|
||||||
|
etk::init(_argc, _argv);
|
||||||
|
// TODO : permit module to init libraries ... zeus::init(_argc, _argv);
|
||||||
|
std::string ip;
|
||||||
|
uint16_t port = 0;
|
||||||
|
std::string basePath;
|
||||||
|
std::vector<std::string> services;
|
||||||
|
for (int32_t iii=0; iii<_argc ; ++iii) {
|
||||||
|
std::string data = _argv[iii];
|
||||||
|
if (etk::start_with(data, "--ip=") == true) {
|
||||||
|
ip = std::string(&data[5]);
|
||||||
|
} else if (etk::start_with(data, "--port=") == true) {
|
||||||
|
port = etk::string_to_uint16_t(std::string(&data[7]));
|
||||||
|
} else if (etk::start_with(data, "--base-path=") == true) {
|
||||||
|
basePath = std::string(&data[12]);
|
||||||
|
} else if (etk::start_with(data, "--srv=") == true) {
|
||||||
|
services.push_back(std::string(&data[6]));
|
||||||
|
} else if ( data == "-h"
|
||||||
|
|| data == "--help") {
|
||||||
|
APPL_PRINT(etk::getApplicationName() << " - help : ");
|
||||||
|
APPL_PRINT(" " << _argv[0] << " [options]");
|
||||||
|
APPL_PRINT(" --base-path=XXX base path to search data (default: 'USERDATA:')");
|
||||||
|
APPL_PRINT(" --ip=XXX Server connection IP (default: 1.7.0.0.1)");
|
||||||
|
APPL_PRINT(" --port=XXX Server connection PORT (default: 1983)");
|
||||||
|
APPL_PRINT(" --srv=XXX service path");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (basePath.size() == 0) {
|
||||||
|
basePath = "USERDATA:";
|
||||||
|
APPL_PRINT("Use base path: " << basePath);
|
||||||
|
}
|
||||||
|
for (auto &it : services) {
|
||||||
|
void *handle;
|
||||||
|
handle = dlopen(it.c_str(), RTLD_LAZY);
|
||||||
|
if (!handle) {
|
||||||
|
APPL_ERROR("Can not load Lbrary:" << dlerror());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
char *error = nullptr;
|
||||||
|
SERVICE_IO_init_t SERVICE_IO_init;
|
||||||
|
SERVICE_IO_uninit_t SERVICE_IO_uninit;
|
||||||
|
SERVICE_IO_execute_t SERVICE_IO_execute;
|
||||||
|
SERVICE_IO_init = (SERVICE_IO_init_t)dlsym(handle, "SERVICE_IO_init");
|
||||||
|
error = dlerror();
|
||||||
|
if (error != nullptr) {
|
||||||
|
APPL_ERROR("Can not function SERVICE_IO_init :" << error);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
SERVICE_IO_uninit = (SERVICE_IO_uninit_t)dlsym(handle, "SERVICE_IO_uninit");
|
||||||
|
error = dlerror();
|
||||||
|
if (error != nullptr) {
|
||||||
|
APPL_ERROR("Can not function SERVICE_IO_uninit :" << error);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
SERVICE_IO_execute = (SERVICE_IO_execute_t)dlsym(handle, "SERVICE_IO_execute");
|
||||||
|
error = dlerror();
|
||||||
|
if (error != nullptr) {
|
||||||
|
APPL_ERROR("Can not function SERVICE_IO_execute:" << error);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
(*SERVICE_IO_init)(basePath);
|
||||||
|
// TODO: Remove the While true, ==> sevice must be spown by a user call, if a service die, the wall system will die ...
|
||||||
|
while (true) {
|
||||||
|
(*SERVICE_IO_execute)(ip, port);
|
||||||
|
}
|
||||||
|
APPL_INFO("Stop service ==> flush internal datas ...");
|
||||||
|
(*SERVICE_IO_uninit)();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
40
tools/launcher/lutin_zeus-launcher.py
Normal file
40
tools/launcher/lutin_zeus-launcher.py
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
import lutin.debug as debug
|
||||||
|
import lutin.tools as tools
|
||||||
|
|
||||||
|
|
||||||
|
def get_type():
|
||||||
|
return "BINARY"
|
||||||
|
|
||||||
|
def get_sub_type():
|
||||||
|
return "TOOLS"
|
||||||
|
|
||||||
|
def get_desc():
|
||||||
|
return "ZEUS launcher of service module"
|
||||||
|
|
||||||
|
def get_licence():
|
||||||
|
return "APACHE-2"
|
||||||
|
|
||||||
|
def get_compagny_type():
|
||||||
|
return "com"
|
||||||
|
|
||||||
|
def get_compagny_name():
|
||||||
|
return "atria-soft"
|
||||||
|
|
||||||
|
def get_maintainer():
|
||||||
|
return ["Mr DUPIN Edouard <yui.heero@gmail.com>"]
|
||||||
|
|
||||||
|
def configure(target, my_module):
|
||||||
|
my_module.add_path(".")
|
||||||
|
my_module.add_depend([
|
||||||
|
'etk',
|
||||||
|
'elog'
|
||||||
|
])
|
||||||
|
my_module.add_src_file([
|
||||||
|
'appl/debug.cpp',
|
||||||
|
'appl/main.cpp'
|
||||||
|
])
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|
36
tools/package-base/lutin_zeus-package-base.py
Normal file
36
tools/package-base/lutin_zeus-package-base.py
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
import lutin.debug as debug
|
||||||
|
import lutin.tools as tools
|
||||||
|
|
||||||
|
|
||||||
|
def get_type():
|
||||||
|
return "PACKAGE"
|
||||||
|
|
||||||
|
def get_desc():
|
||||||
|
return "ZEUS package group to set it usable"
|
||||||
|
|
||||||
|
def get_licence():
|
||||||
|
return "APACHE-2"
|
||||||
|
|
||||||
|
def get_compagny_type():
|
||||||
|
return "com"
|
||||||
|
|
||||||
|
def get_compagny_name():
|
||||||
|
return "atria-soft"
|
||||||
|
|
||||||
|
def get_maintainer():
|
||||||
|
return ["Mr DUPIN Edouard <yui.heero@gmail.com>"]
|
||||||
|
|
||||||
|
def configure(target, my_module):
|
||||||
|
my_module.add_depend([
|
||||||
|
'zeus-gateway-front-end',
|
||||||
|
'zeus-gateway-back-end',
|
||||||
|
'zeus-service-user',
|
||||||
|
'zeus-service-picture',
|
||||||
|
'zeus-service-video',
|
||||||
|
'zeus-launcher',
|
||||||
|
])
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -4,8 +4,8 @@ import lutin.tools as tools
|
|||||||
|
|
||||||
|
|
||||||
def get_type():
|
def get_type():
|
||||||
#return "LIBRARY_DYNAMIC"
|
return "LIBRARY_DYNAMIC"
|
||||||
return "BINARY"
|
#return "BINARY"
|
||||||
|
|
||||||
def get_sub_type():
|
def get_sub_type():
|
||||||
return "TOOLS"
|
return "TOOLS"
|
||||||
|
@ -16,84 +16,44 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include <etk/stdTools.hpp>
|
#include <etk/stdTools.hpp>
|
||||||
|
|
||||||
|
static std::mutex g_mutex;
|
||||||
|
static std::string g_basePath;
|
||||||
|
static std::string g_baseDBName = std::string(SERVICE_NAME) + "-database.json";
|
||||||
|
static ejson::Document g_database;
|
||||||
|
static std::map<uint64_t,std::string> m_listFile;
|
||||||
|
static uint64_t m_lastMaxId = 0;
|
||||||
|
|
||||||
|
static uint64_t createFileID() {
|
||||||
|
m_lastMaxId++;
|
||||||
|
return m_lastMaxId;
|
||||||
|
}
|
||||||
|
|
||||||
namespace appl {
|
namespace appl {
|
||||||
class User {
|
class VideoService {
|
||||||
private:
|
private:
|
||||||
std::mutex m_mutex;
|
ememory::SharedPtr<zeus::ClientProperty> m_client;
|
||||||
std::string m_userName;
|
|
||||||
std::string m_basePath;
|
|
||||||
ejson::Document m_database;
|
|
||||||
std::map<uint64_t,std::string> m_listFile;
|
|
||||||
uint64_t m_lastMaxId;
|
|
||||||
public:
|
public:
|
||||||
User(const std::string& _userName) :
|
VideoService() {
|
||||||
m_userName(_userName),
|
APPL_WARNING("New VideoService ...");
|
||||||
m_lastMaxId(1024) {
|
|
||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
|
||||||
APPL_WARNING("new USER: " << m_userName << " [START]");
|
|
||||||
m_basePath = std::string("USERDATA:") + m_userName + "/";
|
|
||||||
APPL_WARNING("new USER: " << m_userName);
|
|
||||||
bool ret = m_database.load(m_basePath + "database.json");
|
|
||||||
if (ret == false) {
|
|
||||||
APPL_WARNING(" ==> LOAD error");
|
|
||||||
}
|
|
||||||
// Load all files (image and video ...)
|
|
||||||
etk::FSNode node(m_basePath);
|
|
||||||
std::vector<etk::FSNode*> tmpList = node.folderGetSubList(false, false, true, false);
|
|
||||||
APPL_WARNING("Find " << tmpList.size() << " files");
|
|
||||||
for (auto &it : tmpList) {
|
|
||||||
if (it == nullptr) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ( etk::end_with(it->getNameFile(), ".svg", false) == true
|
|
||||||
|| etk::end_with(it->getNameFile(), ".bmp", false) == true
|
|
||||||
|| etk::end_with(it->getNameFile(), ".png", false) == true
|
|
||||||
|| etk::end_with(it->getNameFile(), ".jpg", false) == true
|
|
||||||
|| etk::end_with(it->getNameFile(), ".tga", false) == true
|
|
||||||
|| etk::end_with(it->getNameFile(), ".mp4", false) == true
|
|
||||||
|| etk::end_with(it->getNameFile(), ".avi", false) == true
|
|
||||||
|| etk::end_with(it->getNameFile(), ".mov", false) == true
|
|
||||||
|| etk::end_with(it->getNameFile(), ".mkv", false) == true) {
|
|
||||||
// TODO : Do it better (proto ..)
|
|
||||||
std::string idString = it->getNameFile();
|
|
||||||
idString.resize(idString.size()-4);
|
|
||||||
uint64_t id = 0;
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << std::hex << idString;
|
|
||||||
ss >> id;
|
|
||||||
if (id <= 1024) {
|
|
||||||
APPL_WARNING(" ==> REJECTED file " << it->getNameFile() << " with ID = " << id);
|
|
||||||
} else {
|
|
||||||
m_listFile.insert(std::make_pair(id, it->getNameFile()));
|
|
||||||
m_lastMaxId = std::max(m_lastMaxId,id);
|
|
||||||
APPL_WARNING(" ==> load file " << it->getNameFile() << " with ID = " << id);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
APPL_WARNING(" ==> REJECT file " << it->getNameFile());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
APPL_WARNING("new USER: " << m_userName << " [STOP]");
|
|
||||||
}
|
}
|
||||||
~User() {
|
VideoService(ememory::SharedPtr<zeus::ClientProperty> _client) :
|
||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
m_client(_client) {
|
||||||
APPL_WARNING("delete USER [START]");
|
APPL_WARNING("New VideoService ... for user: ");
|
||||||
APPL_DEBUG("Store User Info:");
|
|
||||||
bool ret = m_database.storeSafe(m_basePath + "database.json");
|
|
||||||
if (ret == false) {
|
|
||||||
APPL_WARNING(" ==> Store error");
|
|
||||||
}
|
|
||||||
APPL_WARNING("delete USER [STOP]");
|
|
||||||
}
|
}
|
||||||
// Return the list of root albums
|
~VideoService() {
|
||||||
|
APPL_WARNING("delete VideoService ...");
|
||||||
|
}
|
||||||
|
public:
|
||||||
std::vector<std::string> getAlbums() {
|
std::vector<std::string> getAlbums() {
|
||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
std::unique_lock<std::mutex> lock(g_mutex);
|
||||||
std::vector<std::string> out;
|
std::vector<std::string> out;
|
||||||
ejson::Array globalGroups = m_database["group-global"].toArray();
|
ejson::Array globalGroups = g_database["group-global"].toArray();
|
||||||
if (globalGroups.exist() == false) {
|
if (globalGroups.exist() == false) {
|
||||||
APPL_DEBUG("'group-global' ==> does not exist ==> No album");
|
APPL_DEBUG("'group-global' ==> does not exist ==> No album");
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
ejson::Object groups = m_database["groups"].toObject();
|
ejson::Object groups = g_database["groups"].toObject();
|
||||||
if (groups.exist() == false) {
|
if (groups.exist() == false) {
|
||||||
APPL_DEBUG("'group' ==> does not exist ==> No album");
|
APPL_DEBUG("'group' ==> does not exist ==> No album");
|
||||||
return out;
|
return out;
|
||||||
@ -109,7 +69,7 @@ namespace appl {
|
|||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
/*
|
/*
|
||||||
ejson::Object groups = m_database["groups"].toObject();
|
ejson::Object groups = g_database["groups"].toObject();
|
||||||
if (groups.exist() == false) {
|
if (groups.exist() == false) {
|
||||||
return std::vector<std::string>();
|
return std::vector<std::string>();
|
||||||
}
|
}
|
||||||
@ -118,10 +78,10 @@ namespace appl {
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
// Get the list of sub album
|
// Get the list of sub album
|
||||||
std::vector<std::string> getSubAlbums(const std::string& _album) {
|
std::vector<std::string> getSubAlbums(std::string _parrentAlbum) {
|
||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
std::unique_lock<std::mutex> lock(g_mutex);
|
||||||
std::vector<std::string> out;
|
std::vector<std::string> out;
|
||||||
ejson::Object groups = m_database["groups"].toObject();
|
ejson::Object groups = g_database["groups"].toObject();
|
||||||
if (groups.exist() == false) {
|
if (groups.exist() == false) {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
@ -134,7 +94,7 @@ namespace appl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
ejson::Object group = groups[_album].toObject();
|
ejson::Object group = groups[_parrentAlbum].toObject();
|
||||||
if (group.exist() == false) {
|
if (group.exist() == false) {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
@ -149,9 +109,9 @@ namespace appl {
|
|||||||
// TODO: Check right
|
// TODO: Check right
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
uint32_t getAlbumCount(const std::string& _album) {
|
uint32_t getAlbumCount(std::string _album) {
|
||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
std::unique_lock<std::mutex> lock(g_mutex);
|
||||||
ejson::Object groups = m_database["groups"].toObject();
|
ejson::Object groups = g_database["groups"].toObject();
|
||||||
if (groups.exist() == false) {
|
if (groups.exist() == false) {
|
||||||
// TODO : Throw an error ...
|
// TODO : Throw an error ...
|
||||||
return 0;
|
return 0;
|
||||||
@ -164,21 +124,12 @@ namespace appl {
|
|||||||
ejson::Array groupSubs = group["files"].toArray();
|
ejson::Array groupSubs = group["files"].toArray();
|
||||||
// TODO: Check right
|
// TODO: Check right
|
||||||
return groupSubs.size();
|
return groupSubs.size();
|
||||||
/*
|
|
||||||
for (auto it: groupSubs) {
|
|
||||||
uint64_t id = it.toNumber().getU64();
|
|
||||||
if (id == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
out.push_back(id);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
// Return the list of the album files
|
// Return the list of the album files
|
||||||
std::vector<std::string> getAlbumListVideo(const std::string& _album) {//, uint32_t _startId, uint32_t _stopId) {
|
std::vector<std::string> getAlbumListPicture(std::string _album) {
|
||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
std::unique_lock<std::mutex> lock(g_mutex);
|
||||||
std::vector<std::string> out;
|
std::vector<std::string> out;
|
||||||
ejson::Object groups = m_database["groups"].toObject();
|
ejson::Object groups = g_database["groups"].toObject();
|
||||||
if (groups.exist() == false) {
|
if (groups.exist() == false) {
|
||||||
// TODO : Throw an error ...
|
// TODO : Throw an error ...
|
||||||
return out;
|
return out;
|
||||||
@ -204,29 +155,29 @@ namespace appl {
|
|||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
// Return a File Data (might be a Video .tiff/.png/.jpg)
|
// Return a File Data (might be a picture .tiff/.png/.jpg)
|
||||||
zeus::FileServer getAlbumVideo(const std::string& _VideoName) {
|
zeus::FileServer getAlbumPicture(std::string _pictureName) {
|
||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
std::unique_lock<std::mutex> lock(g_mutex);
|
||||||
// TODO : Check right ...
|
// TODO : Check right ...
|
||||||
uint64_t id = etk::string_to_uint64_t(_VideoName);
|
uint64_t id = etk::string_to_uint64_t(_pictureName);
|
||||||
APPL_WARNING("try to get file : " << _VideoName << " with id=" << id);
|
APPL_WARNING("try to get file : " << _pictureName << " with id=" << id);
|
||||||
{
|
{
|
||||||
auto it = m_listFile.find(id);
|
auto it = m_listFile.find(id);
|
||||||
if (it != m_listFile.end()) {
|
if (it != m_listFile.end()) {
|
||||||
return zeus::FileServer(m_basePath + it->second);
|
return zeus::FileServer(g_basePath + it->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto &it : m_listFile) {
|
for (auto &it : m_listFile) {
|
||||||
APPL_WARNING("compare: " << it.first << " with " << id << " " << it.second);
|
APPL_WARNING("compare: " << it.first << " with " << id << " " << it.second);
|
||||||
if (it.first == id) {
|
if (it.first == id) {
|
||||||
return zeus::FileServer(m_basePath + it.second);
|
return zeus::FileServer(g_basePath + it.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
APPL_ERROR(" ==> Not find ...");
|
APPL_ERROR(" ==> Not find ...");
|
||||||
return zeus::FileServer();
|
return zeus::FileServer();
|
||||||
}
|
}
|
||||||
std::string addFile(const zeus::File& _dataFile) {
|
std::string addFile(zeus::File _dataFile) {
|
||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
std::unique_lock<std::mutex> lock(g_mutex);
|
||||||
// TODO : Check right ...
|
// TODO : Check right ...
|
||||||
APPL_ERROR(" ==> Receive FILE " << _dataFile.getMineType() << " size=" << _dataFile.getData().size());
|
APPL_ERROR(" ==> Receive FILE " << _dataFile.getMineType() << " size=" << _dataFile.getData().size());
|
||||||
uint64_t id = createFileID();
|
uint64_t id = createFileID();
|
||||||
@ -235,214 +186,237 @@ namespace appl {
|
|||||||
std::string filename = val.str();
|
std::string filename = val.str();
|
||||||
filename += ".";
|
filename += ".";
|
||||||
filename += zeus::getExtention(_dataFile.getMineType());
|
filename += zeus::getExtention(_dataFile.getMineType());
|
||||||
_dataFile.storeIn(m_basePath + filename);
|
_dataFile.storeIn(g_basePath + filename);
|
||||||
m_listFile.insert(std::make_pair(id, filename));
|
m_listFile.insert(std::make_pair(id, filename));
|
||||||
return etk::to_string(id);//zeus::FileServer();
|
return etk::to_string(id);//zeus::FileServer();
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
// Return a global UTC time
|
||||||
|
zeus::Time getAlbumPictureTime(std::string _pictureName) {
|
||||||
|
return m_user->getAlbumPictureTime(_pictureName);
|
||||||
|
}
|
||||||
|
// Return a Geolocalization information (latitude, longitude)
|
||||||
|
zeus::Geo getAlbumPictureGeoLocalization(std::string _pictureName) {
|
||||||
|
return m_user->getAlbumPictureGeoLocalization(_pictureName);
|
||||||
|
}
|
||||||
|
*/
|
||||||
bool removeFile(const std::string& _file) {
|
bool removeFile(const std::string& _file) {
|
||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
std::unique_lock<std::mutex> lock(g_mutex);
|
||||||
// TODO : Check right ...
|
// TODO : Check right ...
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string createAlbum(const std::string& _name) {
|
std::string createAlbum(const std::string& _name) {
|
||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
std::unique_lock<std::mutex> lock(g_mutex);
|
||||||
// TODO : Check right ...
|
// TODO : Check right ...
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
bool removeAlbum(const std::string& _name) {
|
bool removeAlbum(const std::string& _name) {
|
||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
std::unique_lock<std::mutex> lock(g_mutex);
|
||||||
// TODO : Check right ...
|
// TODO : Check right ...
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool setAlbumDescription(const std::string& _name, const std::string& _desc) {
|
bool setAlbumDescription(const std::string& _name, const std::string& _desc) {
|
||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
std::unique_lock<std::mutex> lock(g_mutex);
|
||||||
// TODO : Check right ...
|
// TODO : Check right ...
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::string getAlbumDescription(const std::string& _name) {
|
std::string getAlbumDescription(const std::string& _name) {
|
||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
std::unique_lock<std::mutex> lock(g_mutex);
|
||||||
// TODO : Check right ...
|
// TODO : Check right ...
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool addInAlbum(const std::string& _nameAlbum, const std::string& _nameElement) {
|
bool addInAlbum(const std::string& _nameAlbum, const std::string& _nameElement) {
|
||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
std::unique_lock<std::mutex> lock(g_mutex);
|
||||||
// TODO : Check right ...
|
// TODO : Check right ...
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool removeFromAlbum(const std::string& _nameAlbum, const std::string& _nameElement) {
|
bool removeFromAlbum(const std::string& _nameAlbum, const std::string& _nameElement) {
|
||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
std::unique_lock<std::mutex> lock(g_mutex);
|
||||||
// TODO : Check right ...
|
// TODO : Check right ...
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
// Return a global UTC time
|
// Return a global UTC time
|
||||||
zeus::Time getAlbumVideoTime(const std::string& _VideoName) {
|
zeus::Time getAlbumPictureTime(const std::string& _pictureName) {
|
||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
std::unique_lock<std::mutex> lock(g_mutex);
|
||||||
// TODO : Check right ...
|
// TODO : Check right ...
|
||||||
return zeus::Time();
|
return zeus::Time();
|
||||||
}
|
}
|
||||||
// Return a Geolocalization information (latitude, longitude)
|
// Return a Geolocalization information (latitude, longitude)
|
||||||
zeus::Geo getAlbumVideoGeoLocalization(const std::string& _VideoName) {
|
zeus::Geo getAlbumPictureGeoLocalization(const std::string& _pictureName) {
|
||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
std::unique_lock<std::mutex> lock(g_mutex);
|
||||||
// TODO : Check right ...
|
// TODO : Check right ...
|
||||||
return zeus::Geo();
|
return zeus::Geo();
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
private:
|
|
||||||
uint64_t createFileID() {
|
|
||||||
m_lastMaxId++;
|
|
||||||
return m_lastMaxId;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class UserManager {
|
|
||||||
private:
|
|
||||||
std::mutex m_mutex;
|
|
||||||
std::map<std::string, ememory::SharedPtr<appl::User>> m_listLoaded;
|
|
||||||
public:
|
|
||||||
UserManager() {
|
|
||||||
|
|
||||||
}
|
|
||||||
ememory::SharedPtr<appl::User> getUser(const std::string& _userName) {
|
|
||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
|
||||||
auto it = m_listLoaded.find(_userName);
|
|
||||||
if (it != m_listLoaded.end()) {
|
|
||||||
// User already loaded:
|
|
||||||
return it->second;
|
|
||||||
}
|
|
||||||
// load New User:
|
|
||||||
ememory::SharedPtr<appl::User> tmp(new appl::User(_userName));
|
|
||||||
m_listLoaded.insert(std::make_pair(_userName, tmp));
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
class VideoService {
|
|
||||||
private:
|
|
||||||
ememory::SharedPtr<appl::User> m_user;
|
|
||||||
private:
|
|
||||||
ememory::SharedPtr<zeus::ClientProperty> m_client;
|
|
||||||
public:
|
|
||||||
VideoService() {
|
|
||||||
APPL_WARNING("New VideoService ...");
|
|
||||||
}
|
|
||||||
VideoService(ememory::SharedPtr<appl::User> _user, ememory::SharedPtr<zeus::ClientProperty> _client) :
|
|
||||||
m_user(_user),
|
|
||||||
m_client(_client) {
|
|
||||||
APPL_WARNING("New VideoService ... for user: ");
|
|
||||||
}
|
|
||||||
~VideoService() {
|
|
||||||
APPL_WARNING("delete VideoService ...");
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
std::vector<std::string> getAlbums() {
|
|
||||||
return m_user->getAlbums();
|
|
||||||
}
|
|
||||||
// Get the list of sub album
|
|
||||||
std::vector<std::string> getSubAlbums(std::string _parrentAlbum) {
|
|
||||||
return m_user->getSubAlbums(_parrentAlbum);
|
|
||||||
}
|
|
||||||
uint32_t getAlbumCount(std::string _album) {
|
|
||||||
return m_user->getAlbumCount(_album);
|
|
||||||
}
|
|
||||||
// Return the list of the album files
|
|
||||||
std::vector<std::string> getAlbumListVideo(std::string _album) {
|
|
||||||
return m_user->getAlbumListVideo(_album);
|
|
||||||
}
|
|
||||||
// Return a File Data (might be a Video .tiff/.png/.jpg)
|
|
||||||
zeus::FileServer getAlbumVideo(std::string _VideoName) {
|
|
||||||
return m_user->getAlbumVideo(_VideoName);
|
|
||||||
}
|
|
||||||
std::string addFile(zeus::File _dataFile) {
|
|
||||||
return m_user->addFile(_dataFile);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
// Return a global UTC time
|
|
||||||
zeus::Time getAlbumVideoTime(std::string _VideoName) {
|
|
||||||
return m_user->getAlbumVideoTime(_VideoName);
|
|
||||||
}
|
|
||||||
// Return a Geolocalization information (latitude, longitude)
|
|
||||||
zeus::Geo getAlbumVideoGeoLocalization(std::string _VideoName) {
|
|
||||||
return m_user->getAlbumVideoGeoLocalization(_VideoName);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SERVICE_IO_init(std::string _basePath) {
|
||||||
|
g_basePath = _basePath;
|
||||||
|
std::unique_lock<std::mutex> lock(g_mutex);
|
||||||
|
APPL_WARNING("Load USER: " << g_basePath);
|
||||||
|
bool ret = g_database.load(g_basePath + g_baseDBName);
|
||||||
|
if (ret == false) {
|
||||||
|
APPL_WARNING(" ==> LOAD error");
|
||||||
|
}
|
||||||
|
// Load all files (image and video ...)
|
||||||
|
etk::FSNode node(g_basePath);
|
||||||
|
std::vector<etk::FSNode*> tmpList = node.folderGetSubList(false, false, true, false);
|
||||||
|
APPL_WARNING("Find " << tmpList.size() << " files");
|
||||||
|
for (auto &it : tmpList) {
|
||||||
|
if (it == nullptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( etk::end_with(it->getNameFile(), ".svg", false) == true
|
||||||
|
|| etk::end_with(it->getNameFile(), ".bmp", false) == true
|
||||||
|
|| etk::end_with(it->getNameFile(), ".png", false) == true
|
||||||
|
|| etk::end_with(it->getNameFile(), ".jpg", false) == true
|
||||||
|
|| etk::end_with(it->getNameFile(), ".tga", false) == true
|
||||||
|
|| etk::end_with(it->getNameFile(), ".mp4", false) == true
|
||||||
|
|| etk::end_with(it->getNameFile(), ".avi", false) == true
|
||||||
|
|| etk::end_with(it->getNameFile(), ".mov", false) == true
|
||||||
|
|| etk::end_with(it->getNameFile(), ".mkv", false) == true) {
|
||||||
|
// TODO : Do it better (proto ..)
|
||||||
|
std::string idString = it->getNameFile();
|
||||||
|
idString.resize(idString.size()-4);
|
||||||
|
uint64_t id = 0;
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << std::hex << idString;
|
||||||
|
ss >> id;
|
||||||
|
if (id <= 1024) {
|
||||||
|
APPL_WARNING(" ==> REJECTED file " << it->getNameFile() << " with ID = " << id);
|
||||||
|
} else {
|
||||||
|
m_listFile.insert(std::make_pair(id, it->getNameFile()));
|
||||||
|
m_lastMaxId = std::max(m_lastMaxId,id);
|
||||||
|
APPL_WARNING(" ==> load file " << it->getNameFile() << " with ID = " << id);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
APPL_WARNING(" ==> REJECT file " << it->getNameFile());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
APPL_WARNING("new USER: [STOP]");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SERVICE_IO_uninit() {
|
||||||
|
std::unique_lock<std::mutex> lock(g_mutex);
|
||||||
|
APPL_DEBUG("Store User Info:");
|
||||||
|
bool ret = g_database.storeSafe(g_basePath + g_baseDBName);
|
||||||
|
if (ret == false) {
|
||||||
|
APPL_WARNING(" ==> Store error");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
APPL_WARNING("delete USER [STOP]");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SERVICE_IO_execute(std::string _ip, uint16_t _port) {
|
||||||
|
APPL_INFO("===========================================================");
|
||||||
|
APPL_INFO("== ZEUS instanciate service: " << SERVICE_NAME << " [START]");
|
||||||
|
APPL_INFO("===========================================================");
|
||||||
|
zeus::ServiceType<appl::VideoService> serviceInterface([](ememory::SharedPtr<zeus::ClientProperty> _client){
|
||||||
|
return ememory::makeShared<appl::VideoService>(_client);
|
||||||
|
});
|
||||||
|
if (_ip != "") {
|
||||||
|
serviceInterface.propertyIp.set(_ip);
|
||||||
|
}
|
||||||
|
if (_port != 0) {
|
||||||
|
serviceInterface.propertyPort.set(_port);
|
||||||
|
}
|
||||||
|
serviceInterface.propertyNameService.set(SERVICE_NAME);
|
||||||
|
serviceInterface.setDescription("Picture Private Interface");
|
||||||
|
serviceInterface.setVersion("0.1.0");
|
||||||
|
serviceInterface.setType("PICTURE", 1);
|
||||||
|
serviceInterface.addAuthor("Heero Yui", "yui.heero@gmail.com");
|
||||||
|
|
||||||
|
serviceInterface.advertise("getAlbums", &appl::VideoService::getAlbums);
|
||||||
|
serviceInterface.advertise("getSubAlbums", &appl::VideoService::getSubAlbums);
|
||||||
|
serviceInterface.advertise("getAlbumCount", &appl::VideoService::getAlbumCount);
|
||||||
|
serviceInterface.advertise("getAlbumListPicture", &appl::VideoService::getAlbumListPicture);
|
||||||
|
serviceInterface.advertise("getAlbumPicture", &appl::VideoService::getAlbumPicture);
|
||||||
|
serviceInterface.advertise("addFile", &appl::VideoService::addFile);
|
||||||
|
/*
|
||||||
|
serviceInterface.advertise("getAlbumPicture", &appl::VideoService::getAlbumPicture);
|
||||||
|
serviceInterface.advertise("getAlbumPictureTime", &appl::VideoService::getAlbumPictureTime);
|
||||||
|
serviceInterface.advertise("getAlbumPictureGeoLocalization", &appl::VideoService::getAlbumPictureGeoLocalization);
|
||||||
|
*/
|
||||||
|
APPL_INFO("===========================================================");
|
||||||
|
APPL_INFO("== ZEUS service: " << *serviceInterface.propertyNameService << " [service instanciate]");
|
||||||
|
APPL_INFO("===========================================================");
|
||||||
|
if (serviceInterface.connect() == false) {
|
||||||
|
APPL_INFO("wait 5 second ...");
|
||||||
|
std::this_thread::sleep_for(std::chrono::seconds(5));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (serviceInterface.GateWayAlive() == false) {
|
||||||
|
APPL_INFO("===========================================================");
|
||||||
|
APPL_INFO("== ZEUS service: " << *serviceInterface.propertyNameService << " [STOP] Can not connect to the GateWay");
|
||||||
|
APPL_INFO("===========================================================");
|
||||||
|
APPL_INFO("wait 5 second ...");
|
||||||
|
std::this_thread::sleep_for(std::chrono::seconds(5));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int32_t iii=0;
|
||||||
|
while (serviceInterface.GateWayAlive() == true) {
|
||||||
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
|
serviceInterface.pingIsAlive();
|
||||||
|
/*
|
||||||
|
serviceInterface.store();
|
||||||
|
serviceInterface.clean();
|
||||||
|
*/
|
||||||
|
APPL_INFO("service in waiting ... " << iii << "/inf");
|
||||||
|
iii++;
|
||||||
|
}
|
||||||
|
serviceInterface.disconnect();
|
||||||
|
APPL_INFO("===========================================================");
|
||||||
|
APPL_INFO("== ZEUS service: " << *serviceInterface.propertyNameService << " [STOP] GateWay Stop");
|
||||||
|
APPL_INFO("===========================================================");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef APPL_BUILD_SHARED_LIBRARY
|
||||||
|
|
||||||
int main(int _argc, const char *_argv[]) {
|
int main(int _argc, const char *_argv[]) {
|
||||||
etk::init(_argc, _argv);
|
etk::init(_argc, _argv);
|
||||||
zeus::init(_argc, _argv);
|
zeus::init(_argc, _argv);
|
||||||
std::string ip;
|
std::string ip;
|
||||||
uint16_t port = 0;
|
uint16_t port = 0;
|
||||||
|
std::string basePath;
|
||||||
for (int32_t iii=0; iii<_argc ; ++iii) {
|
for (int32_t iii=0; iii<_argc ; ++iii) {
|
||||||
std::string data = _argv[iii];
|
std::string data = _argv[iii];
|
||||||
if (etk::start_with(data, "--ip=") == true) {
|
if (etk::start_with(data, "--ip=") == true) {
|
||||||
ip = std::string(&data[5]);
|
ip = std::string(&data[5]);
|
||||||
} else if (etk::start_with(data, "--port=") == true) {
|
} else if (etk::start_with(data, "--port=") == true) {
|
||||||
port = etk::string_to_uint16_t(std::string(&data[7]));
|
port = etk::string_to_uint16_t(std::string(&data[7]));
|
||||||
|
} else if (etk::start_with(data, "--base-path=") == true) {
|
||||||
|
basePath = std::string(&data[12]);
|
||||||
} else if ( data == "-h"
|
} else if ( data == "-h"
|
||||||
|| data == "--help") {
|
|| data == "--help") {
|
||||||
APPL_PRINT(etk::getApplicationName() << " - help : ");
|
APPL_PRINT(etk::getApplicationName() << " - help : ");
|
||||||
APPL_PRINT(" " << _argv[0] << " [options]");
|
APPL_PRINT(" " << _argv[0] << " [options]");
|
||||||
APPL_PRINT(" --ip=XXX Server connection IP (default: 1.7.0.0.1)");
|
APPL_PRINT(" --base-path=XXX base path to search data (default: 'USERDATA:')");
|
||||||
APPL_PRINT(" --port=XXX Server connection PORT (default: 1983)");
|
APPL_PRINT(" --ip=XXX Server connection IP (default: 1.7.0.0.1)");
|
||||||
|
APPL_PRINT(" --port=XXX Server connection PORT (default: 1983)");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (true) {
|
if (basePath.size() == 0) {
|
||||||
APPL_INFO("===========================================================");
|
basePath = "USERDATA:";
|
||||||
APPL_INFO("== ZEUS instanciate service: " << SERVICE_NAME << " [START]");
|
APPL_PRINT("Use base path: " << basePath);
|
||||||
APPL_INFO("===========================================================");
|
|
||||||
ememory::SharedPtr<appl::UserManager> userMng = ememory::makeShared<appl::UserManager>();
|
|
||||||
zeus::ServiceType<appl::VideoService, appl::UserManager> serviceInterface(userMng);
|
|
||||||
if (ip != "") {
|
|
||||||
serviceInterface.propertyIp.set(ip);
|
|
||||||
}
|
|
||||||
if (port != 0) {
|
|
||||||
serviceInterface.propertyPort.set(port);
|
|
||||||
}
|
|
||||||
serviceInterface.propertyNameService.set(SERVICE_NAME);
|
|
||||||
serviceInterface.setDescription("Video Private Interface");
|
|
||||||
serviceInterface.setVersion("0.1.0");
|
|
||||||
serviceInterface.setType("Video", 1);
|
|
||||||
serviceInterface.addAuthor("Heero Yui", "yui.heero@gmail.com");
|
|
||||||
|
|
||||||
serviceInterface.advertise("getAlbums", &appl::VideoService::getAlbums);
|
|
||||||
serviceInterface.advertise("getSubAlbums", &appl::VideoService::getSubAlbums);
|
|
||||||
serviceInterface.advertise("getAlbumCount", &appl::VideoService::getAlbumCount);
|
|
||||||
serviceInterface.advertise("getAlbumListVideo", &appl::VideoService::getAlbumListVideo);
|
|
||||||
serviceInterface.advertise("getAlbumVideo", &appl::VideoService::getAlbumVideo);
|
|
||||||
serviceInterface.advertise("addFile", &appl::VideoService::addFile);
|
|
||||||
APPL_INFO("===========================================================");
|
|
||||||
APPL_INFO("== ZEUS service: " << *serviceInterface.propertyNameService << " [service instanciate]");
|
|
||||||
APPL_INFO("===========================================================");
|
|
||||||
serviceInterface.connect();
|
|
||||||
if (serviceInterface.GateWayAlive() == false) {
|
|
||||||
APPL_INFO("===========================================================");
|
|
||||||
APPL_INFO("== ZEUS service: " << *serviceInterface.propertyNameService << " [STOP] Can not connect to the GateWay");
|
|
||||||
APPL_INFO("===========================================================");
|
|
||||||
APPL_INFO("wait 5 second ...");
|
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(5));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
int32_t iii=0;
|
|
||||||
while (serviceInterface.GateWayAlive() == true) {
|
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
|
||||||
serviceInterface.pingIsAlive();
|
|
||||||
/*
|
|
||||||
serviceInterface.store();
|
|
||||||
serviceInterface.clean();
|
|
||||||
*/
|
|
||||||
APPL_INFO("service in waiting ... " << iii << "/inf");
|
|
||||||
iii++;
|
|
||||||
}
|
|
||||||
serviceInterface.disconnect();
|
|
||||||
APPL_INFO("===========================================================");
|
|
||||||
APPL_INFO("== ZEUS service: " << *serviceInterface.propertyNameService << " [STOP] GateWay Stop");
|
|
||||||
APPL_INFO("===========================================================");
|
|
||||||
}
|
}
|
||||||
|
SERVICE_IO_init(basePath);
|
||||||
|
// TODO: Remove the While true, ==> sevice must be spown by a user call, if a service die, the wall system will die ...
|
||||||
|
while (true) {
|
||||||
|
SERVICE_IO_execute(ip, port);
|
||||||
|
}
|
||||||
|
APPL_INFO("Stop service ==> flush internal datas ...");
|
||||||
|
SERVICE_IO_uninit();
|
||||||
|
APPL_INFO("===========================================================");
|
||||||
|
APPL_INFO("== ZEUS service: " << SERVICE_NAME << " [END-APPLICATION]");
|
||||||
|
APPL_INFO("===========================================================");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user