2012-03-09 03:06:09 +00:00
|
|
|
|
#include <Poco/Net/HTTPServerRequest.h>
|
|
|
|
|
|
|
|
|
|
#include <Yandex/ApplicationServerExt.h>
|
|
|
|
|
|
|
|
|
|
#include <DB/Interpreters/loadMetadata.h>
|
|
|
|
|
#include <DB/Storages/StorageSystemNumbers.h>
|
2012-05-08 11:19:00 +00:00
|
|
|
|
#include <DB/Storages/StorageSystemTables.h>
|
2012-06-18 07:49:19 +00:00
|
|
|
|
#include <DB/Storages/StorageSystemDatabases.h>
|
2012-03-09 03:06:09 +00:00
|
|
|
|
#include <DB/Storages/StorageSystemOne.h>
|
|
|
|
|
|
|
|
|
|
#include "Server.h"
|
2012-03-09 15:46:52 +00:00
|
|
|
|
#include "HTTPHandler.h"
|
2012-12-14 11:21:07 +00:00
|
|
|
|
#include "OLAPHTTPHandler.h"
|
2012-03-09 15:46:52 +00:00
|
|
|
|
#include "TCPHandler.h"
|
2012-03-09 03:06:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
/// Отвечает "Ok.\n", если получен любой GET запрос. Используется для проверки живости.
|
|
|
|
|
class PingRequestHandler : public Poco::Net::HTTPRequestHandler
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
PingRequestHandler()
|
|
|
|
|
{
|
|
|
|
|
LOG_TRACE((&Logger::get("PingRequestHandler")), "Ping request.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void handleRequest(Poco::Net::HTTPServerRequest & request, Poco::Net::HTTPServerResponse & response)
|
|
|
|
|
{
|
|
|
|
|
response.send() << "Ok." << std::endl;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2012-12-14 11:21:07 +00:00
|
|
|
|
template<typename HandlerType>
|
|
|
|
|
class HTTPRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory
|
2012-03-09 03:06:09 +00:00
|
|
|
|
{
|
2012-12-14 11:21:07 +00:00
|
|
|
|
private:
|
|
|
|
|
Server & server;
|
|
|
|
|
Logger * log;
|
|
|
|
|
std::string name;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
HTTPRequestHandlerFactory(Server & server_, const std::string & name_)
|
|
|
|
|
: server(server_), log(&Logger::get(name_)), name(name_) {}
|
|
|
|
|
|
|
|
|
|
Poco::Net::HTTPRequestHandler * createRequestHandler(const Poco::Net::HTTPServerRequest & request)
|
|
|
|
|
{
|
|
|
|
|
LOG_TRACE(log, "HTTP Request for " << name << ". "
|
|
|
|
|
<< "Method: " << request.getMethod()
|
|
|
|
|
<< ", Address: " << request.clientAddress().toString()
|
|
|
|
|
<< ", User-Agent: " << (request.has("User-Agent") ? request.get("User-Agent") : "none"));
|
|
|
|
|
|
|
|
|
|
if (request.getURI().find('?') != std::string::npos || request.getMethod() == Poco::Net::HTTPRequest::HTTP_POST)
|
|
|
|
|
return new HandlerType(server);
|
|
|
|
|
else if (request.getMethod() == Poco::Net::HTTPRequest::HTTP_GET)
|
|
|
|
|
return new PingRequestHandler();
|
|
|
|
|
else
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
};
|
2012-03-09 03:06:09 +00:00
|
|
|
|
|
|
|
|
|
|
2012-12-14 11:21:07 +00:00
|
|
|
|
class TCPConnectionFactory : public Poco::Net::TCPServerConnectionFactory
|
2012-03-09 15:46:52 +00:00
|
|
|
|
{
|
2012-12-14 11:21:07 +00:00
|
|
|
|
private:
|
|
|
|
|
Server & server;
|
|
|
|
|
Logger * log;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
TCPConnectionFactory(Server & server_) : server(server_), log(&Logger::get("TCPConnectionFactory")) {}
|
2012-03-09 15:46:52 +00:00
|
|
|
|
|
2012-12-14 11:21:07 +00:00
|
|
|
|
Poco::Net::TCPServerConnection * createConnection(const Poco::Net::StreamSocket & socket)
|
|
|
|
|
{
|
2013-01-28 18:20:20 +00:00
|
|
|
|
LOG_TRACE(log, "TCP Request. " << "Address: " << socket.peerAddress().toString());
|
2012-12-14 11:21:07 +00:00
|
|
|
|
|
|
|
|
|
return new TCPHandler(server, socket);
|
|
|
|
|
}
|
|
|
|
|
};
|
2012-03-09 15:46:52 +00:00
|
|
|
|
|
|
|
|
|
|
2012-03-09 03:06:09 +00:00
|
|
|
|
int Server::main(const std::vector<std::string> & args)
|
|
|
|
|
{
|
2012-06-24 23:35:13 +00:00
|
|
|
|
Logger * log = &logger();
|
|
|
|
|
|
2012-03-09 03:06:09 +00:00
|
|
|
|
/// Заранее инициализируем DateLUT, чтобы первая инициализация потом не влияла на измеряемую скорость выполнения.
|
2012-06-24 23:25:07 +00:00
|
|
|
|
LOG_DEBUG(log, "Initializing DateLUT.");
|
2013-08-11 03:40:14 +00:00
|
|
|
|
DateLUTSingleton::instance();
|
2012-06-24 23:25:07 +00:00
|
|
|
|
LOG_TRACE(log, "Initialized DateLUT.");
|
2012-03-09 03:56:12 +00:00
|
|
|
|
|
|
|
|
|
/** Контекст содержит всё, что влияет на обработку запроса:
|
|
|
|
|
* настройки, набор функций, типов данных, агрегатных функций, баз данных...
|
|
|
|
|
*/
|
2012-08-02 17:33:31 +00:00
|
|
|
|
global_context.setGlobalContext(global_context);
|
|
|
|
|
global_context.setPath(config.getString("path"));
|
2012-03-09 03:06:09 +00:00
|
|
|
|
|
2013-08-10 07:46:45 +00:00
|
|
|
|
/// Загружаем пользователей.
|
|
|
|
|
global_context.initUsersFromConfig();
|
|
|
|
|
|
2013-08-12 00:36:18 +00:00
|
|
|
|
/// Загружаем квоты.
|
|
|
|
|
global_context.initQuotasFromConfig();
|
|
|
|
|
|
2012-10-22 20:08:28 +00:00
|
|
|
|
/// Загружаем настройки.
|
2013-02-17 19:54:32 +00:00
|
|
|
|
Settings & settings = global_context.getSettingsRef();
|
|
|
|
|
settings.setProfile(config.getString("default_profile", "default"));
|
2012-10-22 20:08:28 +00:00
|
|
|
|
|
|
|
|
|
LOG_INFO(log, "Loading metadata.");
|
|
|
|
|
loadMetadata(global_context);
|
|
|
|
|
LOG_DEBUG(log, "Loaded metadata.");
|
|
|
|
|
|
|
|
|
|
/// Создаём системные таблицы.
|
|
|
|
|
global_context.addDatabase("system");
|
2012-03-09 03:06:09 +00:00
|
|
|
|
|
2013-02-06 11:27:56 +00:00
|
|
|
|
global_context.addTable("system", "one", StorageSystemOne::create("one"));
|
|
|
|
|
global_context.addTable("system", "numbers", StorageSystemNumbers::create("numbers"));
|
|
|
|
|
global_context.addTable("system", "tables", StorageSystemTables::create("tables", global_context));
|
2013-08-28 20:47:43 +00:00
|
|
|
|
global_context.addTable("system", "databases", StorageSystemDatabases::create("databases", global_context));
|
2012-10-22 20:08:28 +00:00
|
|
|
|
|
|
|
|
|
global_context.setCurrentDatabase(config.getString("default_database", "default"));
|
|
|
|
|
|
2012-12-14 11:21:07 +00:00
|
|
|
|
bool use_olap_server = config.getBool("use_olap_http_server", false);
|
2013-07-15 02:03:35 +00:00
|
|
|
|
Poco::Timespan keep_alive_timeout(config.getInt("keep_alive_timeout", 10), 0);
|
2012-12-14 11:21:07 +00:00
|
|
|
|
|
|
|
|
|
Poco::ThreadPool server_pool(3, config.getInt("max_connections", 128));
|
|
|
|
|
Poco::Net::HTTPServerParams * http_params = new Poco::Net::HTTPServerParams;
|
|
|
|
|
http_params->setTimeout(settings.receive_timeout);
|
2013-07-15 02:03:35 +00:00
|
|
|
|
http_params->setKeepAliveTimeout(keep_alive_timeout);
|
2012-12-14 11:21:07 +00:00
|
|
|
|
|
|
|
|
|
/// HTTP
|
2012-03-09 15:46:52 +00:00
|
|
|
|
Poco::Net::ServerSocket http_socket(Poco::Net::SocketAddress("[::]:" + config.getString("http_port")));
|
2012-08-02 17:33:31 +00:00
|
|
|
|
http_socket.setReceiveTimeout(settings.receive_timeout);
|
|
|
|
|
http_socket.setSendTimeout(settings.send_timeout);
|
2012-03-09 15:46:52 +00:00
|
|
|
|
Poco::Net::HTTPServer http_server(
|
2012-12-14 11:21:07 +00:00
|
|
|
|
new HTTPRequestHandlerFactory<HTTPHandler>(*this, "HTTPHandler-factory"),
|
2012-03-09 03:06:09 +00:00
|
|
|
|
server_pool,
|
2012-03-09 15:46:52 +00:00
|
|
|
|
http_socket,
|
2012-07-26 20:16:57 +00:00
|
|
|
|
http_params);
|
2012-12-14 11:21:07 +00:00
|
|
|
|
|
|
|
|
|
/// TCP
|
|
|
|
|
Poco::Net::ServerSocket tcp_socket(Poco::Net::SocketAddress("[::]:" + config.getString("tcp_port")));
|
|
|
|
|
tcp_socket.setReceiveTimeout(settings.receive_timeout);
|
|
|
|
|
tcp_socket.setSendTimeout(settings.send_timeout);
|
2012-03-09 15:46:52 +00:00
|
|
|
|
Poco::Net::TCPServer tcp_server(
|
|
|
|
|
new TCPConnectionFactory(*this),
|
|
|
|
|
server_pool,
|
|
|
|
|
tcp_socket,
|
|
|
|
|
new Poco::Net::TCPServerParams);
|
2012-12-14 11:21:07 +00:00
|
|
|
|
|
|
|
|
|
/// OLAP HTTP
|
|
|
|
|
Poco::SharedPtr<Poco::Net::HTTPServer> olap_http_server;
|
|
|
|
|
if (use_olap_server)
|
|
|
|
|
{
|
2012-12-14 13:31:48 +00:00
|
|
|
|
olap_parser = new OLAP::QueryParser();
|
|
|
|
|
olap_converter = new OLAP::QueryConverter(config);
|
2012-12-27 17:54:16 +00:00
|
|
|
|
|
|
|
|
|
Poco::Net::HTTPServerParams * olap_http_params = new Poco::Net::HTTPServerParams;
|
|
|
|
|
olap_http_params->setTimeout(settings.receive_timeout);
|
2013-07-15 02:03:35 +00:00
|
|
|
|
olap_http_params->setKeepAliveTimeout(keep_alive_timeout);
|
2012-12-14 13:31:48 +00:00
|
|
|
|
|
2012-12-14 11:21:07 +00:00
|
|
|
|
Poco::Net::ServerSocket olap_http_socket(Poco::Net::SocketAddress("[::]:" + config.getString("olap_http_port")));
|
|
|
|
|
olap_http_socket.setReceiveTimeout(settings.receive_timeout);
|
|
|
|
|
olap_http_socket.setSendTimeout(settings.send_timeout);
|
|
|
|
|
olap_http_server = new Poco::Net::HTTPServer(
|
|
|
|
|
new HTTPRequestHandlerFactory<OLAPHTTPHandler>(*this, "OLAPHTTPHandler-factory"),
|
|
|
|
|
server_pool,
|
|
|
|
|
olap_http_socket,
|
2012-12-27 17:54:16 +00:00
|
|
|
|
olap_http_params);
|
2012-12-14 11:21:07 +00:00
|
|
|
|
}
|
2012-03-09 15:46:52 +00:00
|
|
|
|
|
|
|
|
|
http_server.start();
|
|
|
|
|
tcp_server.start();
|
2012-12-14 11:21:07 +00:00
|
|
|
|
if (use_olap_server)
|
|
|
|
|
olap_http_server->start();
|
2012-03-09 15:46:52 +00:00
|
|
|
|
|
2012-06-24 23:25:07 +00:00
|
|
|
|
LOG_INFO(log, "Ready for connections.");
|
|
|
|
|
|
2012-03-09 03:06:09 +00:00
|
|
|
|
waitForTerminationRequest();
|
2012-08-16 18:36:40 +00:00
|
|
|
|
|
|
|
|
|
LOG_DEBUG(log, "Received termination signal.");
|
|
|
|
|
is_cancelled = true;
|
2012-03-09 15:46:52 +00:00
|
|
|
|
|
|
|
|
|
http_server.stop();
|
|
|
|
|
tcp_server.stop();
|
2012-12-14 11:21:07 +00:00
|
|
|
|
if (use_olap_server)
|
|
|
|
|
olap_http_server->stop();
|
2012-03-09 15:46:52 +00:00
|
|
|
|
|
2012-03-09 03:06:09 +00:00
|
|
|
|
return Application::EXIT_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
YANDEX_APP_SERVER_MAIN(DB::Server);
|