2016-02-26 00:25:13 -06:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
|
|
|
|
/*
|
|
|
|
* This file is part of the LibreOffice project.
|
|
|
|
*
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
*/
|
|
|
|
|
loolwsd: include cleanup and organization
A source file (.cpp) must include its own header first.
This insures that the header is self-contained and
doesn't depend on arbitrary (and accidental) includes
before it to compile.
Furthermore, system headers should go next, followed by
C then C++ headers, then libraries (Poco, etc) and, finally,
project headers come last.
This makes sure that headers and included in the same dependency
order to avoid side-effects. For example, Poco should never rely on
anything from our project in the same way that a C header should
never rely on anything in C++, Poco, or project headers.
Also, includes ought to be sorted where possible, to improve
readability and avoid accidental duplicates (of which there
were a few).
Change-Id: I62cc1343e4a091d69195e37ed659dba20cfcb1ef
Reviewed-on: https://gerrit.libreoffice.org/25262
Reviewed-by: Ashod Nakashian <ashnakash@gmail.com>
Tested-by: Ashod Nakashian <ashnakash@gmail.com>
2016-05-21 09:23:07 -05:00
|
|
|
#include "config.h"
|
|
|
|
|
2016-02-26 00:25:13 -06:00
|
|
|
#include <cassert>
|
2016-03-05 14:39:35 -06:00
|
|
|
#include <mutex>
|
2016-02-26 00:25:13 -06:00
|
|
|
#include <sys/poll.h>
|
|
|
|
|
2016-03-21 04:06:54 -05:00
|
|
|
#include <Poco/Net/HTTPCookie.h>
|
|
|
|
#include <Poco/Net/HTTPRequest.h>
|
2016-02-26 00:25:13 -06:00
|
|
|
#include <Poco/Net/HTTPRequestHandler.h>
|
|
|
|
#include <Poco/Net/HTTPServerParams.h>
|
|
|
|
#include <Poco/Net/HTTPServerRequest.h>
|
|
|
|
#include <Poco/Net/HTTPServerResponse.h>
|
|
|
|
#include <Poco/Net/NetException.h>
|
2016-03-21 04:06:54 -05:00
|
|
|
#include <Poco/Net/SecureServerSocket.h>
|
2016-02-26 00:25:13 -06:00
|
|
|
#include <Poco/StringTokenizer.h>
|
2016-03-21 04:06:54 -05:00
|
|
|
#include <Poco/Util/ServerApplication.h>
|
2016-03-05 14:39:35 -06:00
|
|
|
#include <Poco/Util/Timer.h>
|
2016-02-26 00:25:13 -06:00
|
|
|
|
2016-07-19 11:44:29 -05:00
|
|
|
#include "Admin.hpp"
|
2016-02-26 00:25:13 -06:00
|
|
|
#include "AdminModel.hpp"
|
loolwsd: include cleanup and organization
A source file (.cpp) must include its own header first.
This insures that the header is self-contained and
doesn't depend on arbitrary (and accidental) includes
before it to compile.
Furthermore, system headers should go next, followed by
C then C++ headers, then libraries (Poco, etc) and, finally,
project headers come last.
This makes sure that headers and included in the same dependency
order to avoid side-effects. For example, Poco should never rely on
anything from our project in the same way that a C header should
never rely on anything in C++, Poco, or project headers.
Also, includes ought to be sorted where possible, to improve
readability and avoid accidental duplicates (of which there
were a few).
Change-Id: I62cc1343e4a091d69195e37ed659dba20cfcb1ef
Reviewed-on: https://gerrit.libreoffice.org/25262
Reviewed-by: Ashod Nakashian <ashnakash@gmail.com>
Tested-by: Ashod Nakashian <ashnakash@gmail.com>
2016-05-21 09:23:07 -05:00
|
|
|
#include "Auth.hpp"
|
2016-02-26 00:25:13 -06:00
|
|
|
#include "Common.hpp"
|
2016-04-06 13:14:03 -05:00
|
|
|
#include "FileServer.hpp"
|
loolwsd: include cleanup and organization
A source file (.cpp) must include its own header first.
This insures that the header is self-contained and
doesn't depend on arbitrary (and accidental) includes
before it to compile.
Furthermore, system headers should go next, followed by
C then C++ headers, then libraries (Poco, etc) and, finally,
project headers come last.
This makes sure that headers and included in the same dependency
order to avoid side-effects. For example, Poco should never rely on
anything from our project in the same way that a C header should
never rely on anything in C++, Poco, or project headers.
Also, includes ought to be sorted where possible, to improve
readability and avoid accidental duplicates (of which there
were a few).
Change-Id: I62cc1343e4a091d69195e37ed659dba20cfcb1ef
Reviewed-on: https://gerrit.libreoffice.org/25262
Reviewed-by: Ashod Nakashian <ashnakash@gmail.com>
Tested-by: Ashod Nakashian <ashnakash@gmail.com>
2016-05-21 09:23:07 -05:00
|
|
|
#include "IoUtil.hpp"
|
2016-11-24 08:56:06 -06:00
|
|
|
#include "Protocol.hpp"
|
|
|
|
#include "LOOLWebSocket.hpp"
|
2016-03-05 09:21:25 -06:00
|
|
|
#include "LOOLWSD.hpp"
|
loolwsd: include cleanup and organization
A source file (.cpp) must include its own header first.
This insures that the header is self-contained and
doesn't depend on arbitrary (and accidental) includes
before it to compile.
Furthermore, system headers should go next, followed by
C then C++ headers, then libraries (Poco, etc) and, finally,
project headers come last.
This makes sure that headers and included in the same dependency
order to avoid side-effects. For example, Poco should never rely on
anything from our project in the same way that a C header should
never rely on anything in C++, Poco, or project headers.
Also, includes ought to be sorted where possible, to improve
readability and avoid accidental duplicates (of which there
were a few).
Change-Id: I62cc1343e4a091d69195e37ed659dba20cfcb1ef
Reviewed-on: https://gerrit.libreoffice.org/25262
Reviewed-by: Ashod Nakashian <ashnakash@gmail.com>
Tested-by: Ashod Nakashian <ashnakash@gmail.com>
2016-05-21 09:23:07 -05:00
|
|
|
#include "Log.hpp"
|
|
|
|
#include "Storage.hpp"
|
|
|
|
#include "TileCache.hpp"
|
2016-04-18 08:29:17 -05:00
|
|
|
#include "Unit.hpp"
|
2016-02-26 00:25:13 -06:00
|
|
|
#include "Util.hpp"
|
|
|
|
|
2016-11-14 07:58:04 -06:00
|
|
|
#include "common/SigUtil.hpp"
|
|
|
|
|
2016-02-26 00:25:13 -06:00
|
|
|
using namespace LOOLProtocol;
|
|
|
|
|
2016-03-21 04:06:54 -05:00
|
|
|
using Poco::StringTokenizer;
|
2016-02-26 00:25:13 -06:00
|
|
|
using Poco::Net::HTTPRequestHandler;
|
|
|
|
using Poco::Net::HTTPResponse;
|
|
|
|
using Poco::Net::HTTPServerRequest;
|
|
|
|
using Poco::Net::HTTPServerResponse;
|
2016-07-28 07:28:40 -05:00
|
|
|
using Poco::Util::Application;
|
2016-02-26 00:25:13 -06:00
|
|
|
|
2016-05-03 02:10:21 -05:00
|
|
|
bool AdminRequestHandler::adminCommandHandler(const std::vector<char>& payload)
|
2016-02-26 00:25:13 -06:00
|
|
|
{
|
2016-05-03 02:10:21 -05:00
|
|
|
const std::string firstLine = getFirstLine(payload.data(), payload.size());
|
|
|
|
StringTokenizer tokens(firstLine, " ", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
|
|
|
|
Log::trace("Recv: " + firstLine);
|
|
|
|
|
|
|
|
if (tokens.count() < 1)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
std::unique_lock<std::mutex> modelLock(_admin->getLock());
|
|
|
|
AdminModel& model = _admin->getModel();
|
2016-03-20 05:59:32 -05:00
|
|
|
|
2016-08-20 09:04:20 -05:00
|
|
|
if (tokens.count() > 1 && tokens[0] == "auth")
|
|
|
|
{
|
2016-07-28 07:28:40 -05:00
|
|
|
std::string jwtToken;
|
|
|
|
LOOLProtocol::getTokenString(tokens[1], "jwt", jwtToken);
|
|
|
|
const auto& config = Application::instance().config();
|
|
|
|
const auto sslKeyPath = config.getString("ssl.key_file_path", "");
|
|
|
|
|
|
|
|
Log::info("Verifying JWT token: " + jwtToken);
|
|
|
|
JWTAuth authAgent(sslKeyPath, "admin", "admin", "admin");
|
|
|
|
if (authAgent.verify(jwtToken))
|
|
|
|
{
|
|
|
|
Log::trace("JWT token is valid");
|
|
|
|
_isAuthenticated = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sendTextFrame("InvalidAuthToken");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!_isAuthenticated)
|
|
|
|
{
|
|
|
|
sendTextFrame("NotAuthenticated");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else if (tokens[0] == "documents" ||
|
2016-08-20 09:04:20 -05:00
|
|
|
tokens[0] == "active_users_count" ||
|
|
|
|
tokens[0] == "active_docs_count" ||
|
|
|
|
tokens[0] == "mem_stats" ||
|
2016-11-13 22:55:18 -06:00
|
|
|
tokens[0] == "cpu_stats")
|
2016-05-03 02:10:21 -05:00
|
|
|
{
|
2016-07-19 12:45:10 -05:00
|
|
|
const std::string result = model.query(tokens[0]);
|
2016-08-20 09:04:20 -05:00
|
|
|
if (!result.empty())
|
|
|
|
{
|
|
|
|
sendTextFrame(tokens[0] + ' ' + result);
|
|
|
|
}
|
2016-05-03 02:10:21 -05:00
|
|
|
}
|
|
|
|
else if (tokens[0] == "subscribe" && tokens.count() > 1)
|
|
|
|
{
|
2016-07-12 08:56:17 -05:00
|
|
|
for (std::size_t i = 0; i < tokens.count() - 1; i++)
|
2016-02-26 00:25:13 -06:00
|
|
|
{
|
2016-05-03 02:10:21 -05:00
|
|
|
model.subscribe(_sessionId, tokens[i + 1]);
|
2016-03-20 05:59:32 -05:00
|
|
|
}
|
2016-05-03 02:10:21 -05:00
|
|
|
}
|
|
|
|
else if (tokens[0] == "unsubscribe" && tokens.count() > 1)
|
|
|
|
{
|
2016-07-12 08:56:17 -05:00
|
|
|
for (std::size_t i = 0; i < tokens.count() - 1; i++)
|
2016-03-20 05:59:32 -05:00
|
|
|
{
|
2016-05-03 02:10:21 -05:00
|
|
|
model.unsubscribe(_sessionId, tokens[i + 1]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (tokens[0] == "total_mem")
|
|
|
|
{
|
2016-08-20 09:04:20 -05:00
|
|
|
const auto totalMem = _admin->getTotalMemoryUsage(model);
|
|
|
|
sendTextFrame("total_mem " + std::to_string(totalMem));
|
2016-05-03 02:10:21 -05:00
|
|
|
}
|
|
|
|
else if (tokens[0] == "kill" && tokens.count() == 2)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
const auto pid = std::stoi(tokens[1]);
|
2016-11-13 15:12:01 -06:00
|
|
|
LOG_INF("Admin request to kill PID: " << pid);
|
2016-11-14 07:58:04 -06:00
|
|
|
SigUtil::killChild(pid);
|
2016-05-03 02:10:21 -05:00
|
|
|
}
|
2016-11-13 15:12:01 -06:00
|
|
|
catch (std::invalid_argument& exc)
|
2016-05-03 02:10:21 -05:00
|
|
|
{
|
2016-11-13 15:12:01 -06:00
|
|
|
LOG_WRN("Invalid PID to kill: " << tokens[1]);
|
2016-05-03 02:10:21 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (tokens[0] == "settings")
|
|
|
|
{
|
|
|
|
// for now, we have only these settings
|
|
|
|
std::ostringstream oss;
|
|
|
|
oss << tokens[0] << " "
|
|
|
|
<< "mem_stats_size=" << model.query("mem_stats_size") << " "
|
|
|
|
<< "mem_stats_interval=" << std::to_string(_admin->getMemStatsInterval()) << " "
|
|
|
|
<< "cpu_stats_size=" << model.query("cpu_stats_size") << " "
|
|
|
|
<< "cpu_stats_interval=" << std::to_string(_admin->getCpuStatsInterval());
|
|
|
|
|
|
|
|
std::string responseFrame = oss.str();
|
|
|
|
sendTextFrame(responseFrame);
|
|
|
|
}
|
2016-11-13 22:55:18 -06:00
|
|
|
else if (tokens[0] == "shutdown")
|
|
|
|
{
|
|
|
|
LOG_INF("Shutdown requested by admin.");
|
2016-11-19 09:22:53 -06:00
|
|
|
SigUtil::requestShutdown();
|
2016-11-13 22:55:18 -06:00
|
|
|
return false;
|
|
|
|
}
|
2016-05-03 02:10:21 -05:00
|
|
|
else if (tokens[0] == "set" && tokens.count() > 1)
|
|
|
|
{
|
|
|
|
for (unsigned i = 1; i < tokens.count(); i++)
|
|
|
|
{
|
|
|
|
StringTokenizer setting(tokens[i], "=", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
|
|
|
|
unsigned settingVal = 0;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
settingVal = std::stoi(setting[1]);
|
|
|
|
}
|
|
|
|
catch (const std::exception& exc)
|
|
|
|
{
|
|
|
|
Log::warn() << "Invalid setting value: "
|
|
|
|
<< setting[1] << " for "
|
|
|
|
<< setting[0] << Log::end;
|
|
|
|
return false;
|
|
|
|
}
|
2016-02-26 00:25:13 -06:00
|
|
|
|
2016-05-03 02:10:21 -05:00
|
|
|
if (setting[0] == "mem_stats_size")
|
|
|
|
{
|
|
|
|
if (settingVal != static_cast<unsigned>(std::stoi(model.query(setting[0]))))
|
2016-03-20 05:59:32 -05:00
|
|
|
{
|
2016-05-03 02:10:21 -05:00
|
|
|
model.setMemStatsSize(settingVal);
|
2016-03-20 05:59:32 -05:00
|
|
|
}
|
2016-05-03 02:10:21 -05:00
|
|
|
}
|
|
|
|
else if (setting[0] == "mem_stats_interval")
|
|
|
|
{
|
|
|
|
if (settingVal != _admin->getMemStatsInterval())
|
2016-03-20 05:59:32 -05:00
|
|
|
{
|
2016-05-03 02:10:21 -05:00
|
|
|
_admin->rescheduleMemTimer(settingVal);
|
|
|
|
model.clearMemStats();
|
|
|
|
model.notify("settings mem_stats_interval=" + std::to_string(settingVal));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (setting[0] == "cpu_stats_size")
|
|
|
|
{
|
|
|
|
if (settingVal != static_cast<unsigned>(std::stoi(model.query(setting[0]))))
|
|
|
|
{
|
|
|
|
model.setCpuStatsSize(settingVal);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (setting[0] == "cpu_stats_interval")
|
|
|
|
{
|
|
|
|
if (settingVal != _admin->getCpuStatsInterval())
|
|
|
|
{
|
|
|
|
_admin->rescheduleCpuTimer(settingVal);
|
|
|
|
model.clearCpuStats();
|
|
|
|
model.notify("settings cpu_stats_interval=" + std::to_string(settingVal));
|
2016-02-26 00:25:13 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-03-21 04:06:54 -05:00
|
|
|
}
|
2016-05-03 02:10:21 -05:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Handle admin requests.
|
|
|
|
void AdminRequestHandler::handleWSRequests(HTTPServerRequest& request, HTTPServerResponse& response, int sessionId)
|
|
|
|
{
|
2016-11-10 02:47:25 -06:00
|
|
|
_adminWs = std::make_shared<LOOLWebSocket>(request, response);
|
2016-05-03 02:10:21 -05:00
|
|
|
|
2016-03-20 05:59:32 -05:00
|
|
|
{
|
2016-05-03 02:10:21 -05:00
|
|
|
std::unique_lock<std::mutex> modelLock(_admin->getLock());
|
|
|
|
// Subscribe the websocket of any AdminModel updates
|
|
|
|
AdminModel& model = _admin->getModel();
|
|
|
|
_sessionId = sessionId;
|
|
|
|
model.subscribe(_sessionId, _adminWs);
|
2016-03-20 05:59:32 -05:00
|
|
|
}
|
2016-05-03 02:10:21 -05:00
|
|
|
|
2016-11-13 21:23:04 -06:00
|
|
|
IoUtil::SocketProcessor(_adminWs, "admin",
|
2016-05-03 02:10:21 -05:00
|
|
|
[this](const std::vector<char>& payload)
|
|
|
|
{
|
|
|
|
return adminCommandHandler(payload);
|
|
|
|
},
|
|
|
|
[]() { },
|
2016-06-15 08:31:41 -05:00
|
|
|
[]() { return TerminationFlag.load(); });
|
2016-05-03 02:10:21 -05:00
|
|
|
|
2016-09-22 00:59:23 -05:00
|
|
|
Log::debug() << "Finishing Admin Session " << Util::encodeId(sessionId) << Log::end;
|
2016-03-20 05:59:32 -05:00
|
|
|
}
|
2016-03-21 04:06:54 -05:00
|
|
|
|
2016-03-20 05:59:32 -05:00
|
|
|
AdminRequestHandler::AdminRequestHandler(Admin* adminManager)
|
2016-07-28 07:28:40 -05:00
|
|
|
: _admin(adminManager),
|
2016-09-26 01:44:40 -05:00
|
|
|
_sessionId(0),
|
2016-07-28 07:28:40 -05:00
|
|
|
_isAuthenticated(false)
|
2016-08-20 09:04:20 -05:00
|
|
|
{
|
|
|
|
}
|
2016-03-21 04:06:54 -05:00
|
|
|
|
2016-05-03 02:10:21 -05:00
|
|
|
void AdminRequestHandler::sendTextFrame(const std::string& message)
|
2016-04-19 02:27:28 -05:00
|
|
|
{
|
2016-04-18 08:29:17 -05:00
|
|
|
UnitWSD::get().onAdminQueryMessage(message);
|
2016-05-03 02:10:21 -05:00
|
|
|
_adminWs->sendFrame(message.data(), message.size());
|
2016-04-19 02:27:28 -05:00
|
|
|
}
|
|
|
|
|
2016-03-20 05:59:32 -05:00
|
|
|
void AdminRequestHandler::handleRequest(HTTPServerRequest& request, HTTPServerResponse& response)
|
|
|
|
{
|
|
|
|
// Different session id pool for admin sessions (?)
|
2016-05-03 02:10:21 -05:00
|
|
|
const auto sessionId = Util::decodeId(LOOLWSD::GenSessionId());
|
2016-03-21 04:06:54 -05:00
|
|
|
|
2016-05-03 02:10:21 -05:00
|
|
|
Util::setThreadName("admin_ws_" + std::to_string(sessionId));
|
2016-03-21 04:06:54 -05:00
|
|
|
|
2016-04-07 07:51:49 -05:00
|
|
|
Log::debug("Thread started.");
|
2016-02-26 00:25:13 -06:00
|
|
|
|
2016-03-20 05:59:32 -05:00
|
|
|
try
|
|
|
|
{
|
|
|
|
std::string requestURI = request.getURI();
|
|
|
|
StringTokenizer pathTokens(requestURI, "/", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
|
2016-03-21 04:06:54 -05:00
|
|
|
|
2016-03-20 05:59:32 -05:00
|
|
|
if (request.find("Upgrade") != request.end() && Poco::icompare(request["Upgrade"], "websocket") == 0)
|
2016-03-21 04:06:54 -05:00
|
|
|
{
|
2016-05-03 02:10:21 -05:00
|
|
|
handleWSRequests(request, response, sessionId);
|
2016-03-21 04:06:54 -05:00
|
|
|
}
|
2016-02-26 00:25:13 -06:00
|
|
|
}
|
2016-03-20 05:59:32 -05:00
|
|
|
catch(const Poco::Net::NotAuthenticatedException& exc)
|
2016-02-26 00:25:13 -06:00
|
|
|
{
|
2016-04-08 06:30:48 -05:00
|
|
|
Log::info("Admin::NotAuthenticated");
|
2016-03-20 05:59:32 -05:00
|
|
|
response.set("WWW-Authenticate", "Basic realm=\"online\"");
|
2016-04-16 11:28:55 -05:00
|
|
|
response.setStatusAndReason(HTTPResponse::HTTP_UNAUTHORIZED);
|
2016-03-20 05:59:32 -05:00
|
|
|
response.setContentLength(0);
|
|
|
|
response.send();
|
2016-02-26 00:25:13 -06:00
|
|
|
}
|
2016-03-20 05:59:32 -05:00
|
|
|
catch (const std::exception& exc)
|
|
|
|
{
|
2016-04-16 11:28:55 -05:00
|
|
|
Log::info(std::string("Admin::handleRequest: Exception: ") + exc.what());
|
2016-03-20 05:59:32 -05:00
|
|
|
response.setStatusAndReason(HTTPResponse::HTTP_BAD_REQUEST);
|
|
|
|
response.setContentLength(0);
|
|
|
|
response.send();
|
|
|
|
}
|
2016-08-20 09:04:20 -05:00
|
|
|
|
2016-04-07 07:51:49 -05:00
|
|
|
Log::debug("Thread finished.");
|
2016-03-20 05:59:32 -05:00
|
|
|
}
|
2016-02-26 00:25:13 -06:00
|
|
|
|
|
|
|
/// An admin command processor.
|
2016-04-06 07:43:44 -05:00
|
|
|
Admin::Admin() :
|
2016-09-26 01:44:40 -05:00
|
|
|
_model(AdminModel()),
|
|
|
|
_forKitPid(0)
|
2016-02-26 00:25:13 -06:00
|
|
|
{
|
2016-04-13 03:14:54 -05:00
|
|
|
Log::info("Admin ctor.");
|
|
|
|
|
|
|
|
_memStatsTask = new MemoryStats(this);
|
|
|
|
_memStatsTimer.schedule(_memStatsTask, _memStatsTaskInterval, _memStatsTaskInterval);
|
|
|
|
|
|
|
|
_cpuStatsTask = new CpuStats(this);
|
|
|
|
_cpuStatsTimer.schedule(_cpuStatsTask, _cpuStatsTaskInterval, _cpuStatsTaskInterval);
|
2016-02-26 00:25:13 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
Admin::~Admin()
|
|
|
|
{
|
|
|
|
Log::info("~Admin dtor.");
|
2016-04-13 03:14:54 -05:00
|
|
|
|
|
|
|
_memStatsTask->cancel();
|
|
|
|
_cpuStatsTask->cancel();
|
2016-02-26 00:25:13 -06:00
|
|
|
}
|
|
|
|
|
2016-04-17 21:11:10 -05:00
|
|
|
void Admin::addDoc(const std::string& docKey, Poco::Process::PID pid, const std::string& filename, const std::string& sessionId)
|
2016-02-26 00:25:13 -06:00
|
|
|
{
|
2016-04-13 03:16:57 -05:00
|
|
|
std::unique_lock<std::mutex> modelLock(_modelMutex);
|
2016-04-15 04:00:22 -05:00
|
|
|
_model.addDocument(docKey, pid, filename, sessionId);
|
2016-04-14 15:29:31 -05:00
|
|
|
}
|
|
|
|
|
2016-04-17 21:11:10 -05:00
|
|
|
void Admin::rmDoc(const std::string& docKey, const std::string& sessionId)
|
2016-04-14 15:29:31 -05:00
|
|
|
{
|
|
|
|
std::unique_lock<std::mutex> modelLock(_modelMutex);
|
2016-04-15 04:00:22 -05:00
|
|
|
_model.removeDocument(docKey, sessionId);
|
2016-02-26 00:25:13 -06:00
|
|
|
}
|
|
|
|
|
2016-04-17 21:32:58 -05:00
|
|
|
void Admin::rmDoc(const std::string& docKey)
|
|
|
|
{
|
|
|
|
std::unique_lock<std::mutex> modelLock(_modelMutex);
|
2016-10-22 09:24:27 -05:00
|
|
|
Log::info("Removing complete doc [" + docKey + "] from Admin.");
|
2016-04-17 21:32:58 -05:00
|
|
|
_model.removeDocument(docKey);
|
|
|
|
}
|
|
|
|
|
2016-03-05 14:39:35 -06:00
|
|
|
void MemoryStats::run()
|
|
|
|
{
|
2016-04-06 07:43:44 -05:00
|
|
|
std::unique_lock<std::mutex> modelLock(_admin->getLock());
|
2016-03-05 14:39:35 -06:00
|
|
|
AdminModel& model = _admin->getModel();
|
2016-04-29 20:59:13 -05:00
|
|
|
const auto totalMem = _admin->getTotalMemoryUsage(model);
|
2016-03-05 14:39:35 -06:00
|
|
|
|
2016-04-29 20:59:13 -05:00
|
|
|
if (totalMem != _lastTotalMemory)
|
|
|
|
{
|
|
|
|
Log::trace("Total memory used: " + std::to_string(totalMem));
|
|
|
|
}
|
|
|
|
|
|
|
|
_lastTotalMemory = totalMem;
|
2016-03-05 14:39:35 -06:00
|
|
|
model.addMemStats(totalMem);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CpuStats::run()
|
|
|
|
{
|
|
|
|
//TODO: Implement me
|
2016-04-06 07:43:44 -05:00
|
|
|
//std::unique_lock<std::mutex> modelLock(_admin->getLock());
|
2016-03-05 14:39:35 -06:00
|
|
|
//model.addCpuStats(totalMem);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Admin::rescheduleMemTimer(unsigned interval)
|
|
|
|
{
|
|
|
|
_memStatsTask->cancel();
|
|
|
|
_memStatsTaskInterval = interval;
|
|
|
|
_memStatsTask = new MemoryStats(this);
|
|
|
|
_memStatsTimer.schedule(_memStatsTask, _memStatsTaskInterval, _memStatsTaskInterval);
|
|
|
|
Log::info("Memory stats interval changed - New interval: " + std::to_string(interval));
|
|
|
|
}
|
|
|
|
|
|
|
|
void Admin::rescheduleCpuTimer(unsigned interval)
|
|
|
|
{
|
|
|
|
_cpuStatsTask->cancel();
|
|
|
|
_cpuStatsTaskInterval = interval;
|
|
|
|
_cpuStatsTask = new CpuStats(this);
|
|
|
|
_cpuStatsTimer.schedule(_cpuStatsTask, _cpuStatsTaskInterval, _cpuStatsTaskInterval);
|
|
|
|
Log::info("CPU stats interval changed - New interval: " + std::to_string(interval));
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned Admin::getTotalMemoryUsage(AdminModel& model)
|
|
|
|
{
|
2016-04-07 03:27:43 -05:00
|
|
|
unsigned totalMem = Util::getMemoryUsage(_forKitPid);
|
2016-03-05 14:39:35 -06:00
|
|
|
totalMem += model.getTotalMemoryUsage();
|
|
|
|
totalMem += Util::getMemoryUsage(Poco::Process::id());
|
|
|
|
|
|
|
|
return totalMem;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned Admin::getMemStatsInterval()
|
|
|
|
{
|
|
|
|
return _memStatsTaskInterval;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned Admin::getCpuStatsInterval()
|
|
|
|
{
|
|
|
|
return _cpuStatsTaskInterval;
|
|
|
|
}
|
|
|
|
|
2016-03-03 12:01:37 -06:00
|
|
|
AdminModel& Admin::getModel()
|
|
|
|
{
|
|
|
|
return _model;
|
|
|
|
}
|
|
|
|
|
2016-12-05 14:11:07 -06:00
|
|
|
void Admin::updateLastActivityTime(const std::string& docKey)
|
|
|
|
{
|
|
|
|
_model.updateLastActivityTime(docKey);
|
|
|
|
}
|
|
|
|
|
2016-02-26 00:25:13 -06:00
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|