mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of github.com:arangodb/arangodb into devel
This commit is contained in:
commit
bcfb356e9e
|
@ -3,7 +3,7 @@ set -e
|
|||
|
||||
TAG=1
|
||||
|
||||
if [ "$1" == "--no-tag" ]; then
|
||||
if [ "$1" == "--no-commit" ]; then
|
||||
TAG=0
|
||||
shift
|
||||
fi
|
||||
|
@ -32,9 +32,9 @@ VERSION_MINOR=`echo $VERSION | awk -F. '{print $2}'`
|
|||
VERSION_REVISION=`echo $VERSION | awk -F. '{print $3}'`
|
||||
|
||||
cat CMakeLists.txt \
|
||||
| sed -e "s~set(ARANGODB_VERSION_MAJOR.*~set(ARANGODB_VERSION_MAJOR \"$VERSION_MAJOR\")" \
|
||||
| sed -e "s~set(ARANGODB_VERSION_MINOR.*~set(ARANGODB_VERSION_MINOR \"$VERSION_MINOR\")" \
|
||||
| sed -e "s~set(ARANGODB_VERSION_REVISION.*~set(ARANGODB_VERSION_REVISION \"$VERSION_REVISION\")" \
|
||||
| sed -e "s~set(ARANGODB_VERSION_MAJOR.*~set(ARANGODB_VERSION_MAJOR \"$VERSION_MAJOR\")~" \
|
||||
| sed -e "s~set(ARANGODB_VERSION_MINOR.*~set(ARANGODB_VERSION_MINOR \"$VERSION_MINOR\")~" \
|
||||
| sed -e "s~set(ARANGODB_VERSION_REVISION.*~set(ARANGODB_VERSION_REVISION \"$VERSION_REVISION\")~" \
|
||||
> CMakeLists.txt.tmp
|
||||
|
||||
mv CMakeLists.txt.tmp CMakeLists.txt
|
||||
|
@ -42,18 +42,22 @@ mv CMakeLists.txt.tmp CMakeLists.txt
|
|||
CMAKE_CONFIGURE="-DUSE_MAINTAINER_MODE=ON"
|
||||
|
||||
if [ `uname` == "Darwin" ]; then
|
||||
CMAKE_CONFIGURE="${CMAKE_CONFIGURE} -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl"
|
||||
CMAKE_CONFIGURE="${CMAKE_CONFIGURE} -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -DCMAKE_OSX_DEPLOYMENT_TARGET=10.11"
|
||||
fi
|
||||
|
||||
if test 0 = 1; then
|
||||
echo "COMPILING"
|
||||
rm -rf build && mkdir build
|
||||
|
||||
./scripts/jsint.sh
|
||||
|
||||
(
|
||||
cd build
|
||||
cmake .. ${CMAKE_CONFIGURE}
|
||||
make -j 8
|
||||
)
|
||||
fi
|
||||
|
||||
echo "LINTING"
|
||||
./utils/jslint.sh
|
||||
|
||||
git add -f \
|
||||
README \
|
||||
|
@ -67,13 +71,13 @@ git add -f \
|
|||
js/common/bootstrap/errors.js \
|
||||
CMakeLists.txt
|
||||
|
||||
(
|
||||
cd build
|
||||
make swagger
|
||||
)
|
||||
echo "SWAGGER"
|
||||
./utils/generateSwagger.sh
|
||||
|
||||
./scripts/generateExamples
|
||||
echo "EXAMPLES"
|
||||
./utils/generateExamples.sh
|
||||
|
||||
echo "GRUNT"
|
||||
(
|
||||
cd js/apps/system/_admin/aardvark/APP
|
||||
npm install --only=dev
|
||||
|
@ -82,6 +86,7 @@ git add -f \
|
|||
|
||||
git add -f Documentation/Examples/*.generated
|
||||
|
||||
echo "DOCUMENTATION"
|
||||
cd Documentation/Books; make
|
||||
|
||||
case "$TAG" in
|
||||
|
@ -94,6 +99,8 @@ case "$TAG" in
|
|||
esac
|
||||
|
||||
if [ "$TAG" == "1" ]; then
|
||||
echo "COMMIT"
|
||||
|
||||
git commit -m "release version $VERSION" -a
|
||||
git push
|
||||
|
||||
|
|
|
@ -21,16 +21,16 @@
|
|||
/// @author Kaveh Vahedipour
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "Rest/HttpRequest.h"
|
||||
#include "Rest/Version.h"
|
||||
#include "RestAgencyHandler.h"
|
||||
|
||||
#include "Agency/Agent.h"
|
||||
|
||||
#include <velocypack/Builder.h>
|
||||
#include <velocypack/velocypack-aliases.h>
|
||||
|
||||
#include "Agency/Agent.h"
|
||||
#include "Basics/StaticStrings.h"
|
||||
#include "Logger/Logger.h"
|
||||
#include "Rest/HttpRequest.h"
|
||||
#include "Rest/Version.h"
|
||||
|
||||
using namespace arangodb;
|
||||
|
||||
|
@ -74,8 +74,7 @@ void RestAgencyHandler::redirectRequest(arangodb::consensus::id_t leaderId) {
|
|||
std::string url = Endpoint::uriForm(
|
||||
_agent->config().endpoints.at(leaderId)) + _request->requestPath();
|
||||
createResponse(GeneralResponse::ResponseCode::TEMPORARY_REDIRECT);
|
||||
static std::string const location = "location";
|
||||
_response->setHeaderNC(location, url);
|
||||
_response->setHeaderNC(StaticStrings::Location, url);
|
||||
} catch (std::exception const& e) {
|
||||
LOG_TOPIC(WARN, Logger::AGENCY) << e.what();
|
||||
generateError(GeneralResponse::ResponseCode::SERVER_ERROR,
|
||||
|
|
|
@ -350,8 +350,10 @@ bool HttpCommTask::processRead() {
|
|||
TRI_invalidatesocket(&_commSocket);
|
||||
|
||||
// might delete this
|
||||
// note that as we closed the socket above, the response will not make it to
|
||||
// the client! will result in a "Empty reply from server" error in curl etc.
|
||||
// note that as we closed the socket above, the response will not make
|
||||
// it to
|
||||
// the client! will result in a "Empty reply from server" error in
|
||||
// curl etc.
|
||||
handleResponse(&response);
|
||||
|
||||
return false;
|
||||
|
@ -536,14 +538,12 @@ bool HttpCommTask::processRead() {
|
|||
else {
|
||||
HttpResponse response(GeneralResponse::ResponseCode::UNAUTHORIZED,
|
||||
compatibility);
|
||||
static std::string const wwwAuthenticate = "www-authenticate";
|
||||
|
||||
if (sendWwwAuthenticateHeader()) {
|
||||
static std::string const realm =
|
||||
"basic realm=\"" +
|
||||
_server->handlerFactory()->authenticationRealm(_request) + "\"";
|
||||
|
||||
response.setHeaderNC(wwwAuthenticate, realm);
|
||||
response.setHeaderNC(StaticStrings::WwwAuthenticate, realm);
|
||||
}
|
||||
|
||||
clearRequest();
|
||||
|
@ -608,32 +608,27 @@ void HttpCommTask::addResponse(HttpResponse* response) {
|
|||
// access-control-allow-origin header now
|
||||
LOG(TRACE) << "handling CORS response";
|
||||
|
||||
static std::string const accessControl = "access-control-expose-headers";
|
||||
static std::string const exposedHeaders =
|
||||
"etag, content-encoding, content-length, location, "
|
||||
"server, x-arango-errors, x-arango-async-id";
|
||||
|
||||
response->setHeaderNC(accessControl, exposedHeaders);
|
||||
response->setHeaderNC(StaticStrings::AccessControlExposeHeaders,
|
||||
exposedHeaders);
|
||||
|
||||
// send back original value of "Origin" header
|
||||
static std::string const accessOrigin = "access-control-allow-origin";
|
||||
|
||||
response->setHeaderNC(accessOrigin, _origin);
|
||||
response->setHeaderNC(StaticStrings::AccessControlAllowOrigin, _origin);
|
||||
|
||||
// send back "Access-Control-Allow-Credentials" header
|
||||
static std::string const accessCredentials =
|
||||
"access-control-allow-credentials";
|
||||
|
||||
response->setHeaderNC(accessCredentials,
|
||||
response->setHeaderNC(StaticStrings::AccessControlAllowCredentials,
|
||||
(_denyCredentials ? "false" : "true"));
|
||||
}
|
||||
// CORS request handling EOF
|
||||
|
||||
// set "connection" header
|
||||
// keep-alive is the default
|
||||
static std::string const connection = "connection";
|
||||
|
||||
response->setHeaderNC(connection, (_closeRequested ? "Close" : "Keep-Alive"));
|
||||
response->setHeaderNC(
|
||||
StaticStrings::Connection,
|
||||
(_closeRequested ? StaticStrings::Close : StaticStrings::KeepAlive));
|
||||
|
||||
size_t const responseBodyLength = response->bodySize();
|
||||
|
||||
|
@ -780,40 +775,37 @@ void HttpCommTask::fillWriteBuffer() {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void HttpCommTask::processCorsOptions(uint32_t compatibility) {
|
||||
static std::string const allowedMethods = "DELETE, GET, HEAD, PATCH, POST, PUT";
|
||||
static std::string const allowedMethods =
|
||||
"DELETE, GET, HEAD, PATCH, POST, PUT";
|
||||
|
||||
HttpResponse response(GeneralResponse::ResponseCode::OK, compatibility);
|
||||
|
||||
static std::string const allow = "allow";
|
||||
response.setHeaderNC(allow, allowedMethods);
|
||||
response.setHeaderNC(StaticStrings::Allow, allowedMethods);
|
||||
|
||||
if (!_origin.empty()) {
|
||||
LOG(TRACE) << "got CORS preflight request";
|
||||
std::string const allowHeaders =
|
||||
StringUtils::trim(_request->header("access-control-request-headers"));
|
||||
std::string const allowHeaders = StringUtils::trim(
|
||||
_request->header(StaticStrings::AccessControlRequestHeaders));
|
||||
|
||||
// send back which HTTP methods are allowed for the resource
|
||||
// we'll allow all
|
||||
static std::string const accessControl = "access-control-allow-methods";
|
||||
response.setHeaderNC(accessControl, allowedMethods);
|
||||
response.setHeaderNC(StaticStrings::AccessControlAllowMethods,
|
||||
allowedMethods);
|
||||
|
||||
if (!allowHeaders.empty()) {
|
||||
// allow all extra headers the client requested
|
||||
// we don't verify them here. the worst that can happen is that the client
|
||||
// sends some broken headers and then later cannot access the data on the
|
||||
// server. that's a client problem.
|
||||
static std::string const accessControl = "access-control-allow-headers";
|
||||
response.setHeaderNC(accessControl, allowHeaders);
|
||||
response.setHeaderNC(StaticStrings::AccessControlAllowHeaders,
|
||||
allowHeaders);
|
||||
|
||||
LOG(TRACE) << "client requested validation of the following headers: "
|
||||
<< allowHeaders;
|
||||
}
|
||||
|
||||
// set caching time (hard-coded value)
|
||||
static std::string const accessAge = "access-control-max-age";
|
||||
static std::string const maxAge = "1800";
|
||||
|
||||
response.setHeaderNC(accessAge, maxAge);
|
||||
response.setHeaderNC(StaticStrings::AccessControlMaxAge, StaticStrings::N1800);
|
||||
}
|
||||
|
||||
clearRequest();
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RestBaseHandler.h"
|
||||
|
||||
#include "Basics/StaticStrings.h"
|
||||
#include "Basics/StringUtils.h"
|
||||
#include "Basics/VPackStringBufferAdapter.h"
|
||||
|
@ -149,7 +150,7 @@ void RestBaseHandler::dumpResponse(VPackSlice const& slice,
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool RestBaseHandler::returnVelocypack() const {
|
||||
std::string const& result = _request->header(StaticStrings::AcceptHeader);
|
||||
std::string const& result = _request->header(StaticStrings::Accept);
|
||||
return (std::string::npos != result.find(StaticStrings::MimeTypeVPack));
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,8 @@ HttpHandler::status_t RestVersionHandler::execute() {
|
|||
Version::getVPack(result);
|
||||
|
||||
if (application_features::ApplicationServer::server != nullptr) {
|
||||
auto server = application_features::ApplicationServer::server->getFeature<ServerFeature>("Server");
|
||||
auto server = application_features::ApplicationServer::server
|
||||
->getFeature<ServerFeature>("Server");
|
||||
result.add("mode", VPackValue(server->operationModeString()));
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,309 @@
|
|||
virtual void startupProgress() override final {
|
||||
SetServiceStatus(SERVICE_START_PENDING, NO_ERROR, _progress++, 20000);
|
||||
}
|
||||
|
||||
virtual void startupFinished() override final {
|
||||
// startup finished - signalize we're running.
|
||||
SetServiceStatus(SERVICE_RUNNING, NO_ERROR, 0, 0);
|
||||
}
|
||||
|
||||
virtual void shutDownBegins() override final {
|
||||
// startup finished - signalize we're running.
|
||||
SetServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 0, 0);
|
||||
}
|
||||
|
||||
static void WINAPI ServiceMain(DWORD dwArgc, LPSTR* lpszArgv) {
|
||||
// register the service ctrl handler, lpszArgv[0] contains service name
|
||||
ServiceStatus =
|
||||
RegisterServiceCtrlHandlerA(lpszArgv[0], (LPHANDLER_FUNCTION)ServiceCtrl);
|
||||
|
||||
// set start pending
|
||||
SetServiceStatus(SERVICE_START_PENDING, 0, 1, 10000);
|
||||
|
||||
// and fire up the service
|
||||
STARTUP_FUNCTION(dwArgc, lpszArgv);
|
||||
|
||||
// service has stopped
|
||||
SetServiceStatus(SERVICE_STOPPED, NO_ERROR, 0, 0);
|
||||
TRI_CloseWindowsEventlog();
|
||||
}
|
||||
|
||||
void WindowsService::startService(int argc, char** argv) {
|
||||
SERVICE_TABLE_ENTRY ste[] = {{TEXT(""), (LPSERVICE_MAIN_FUNCTION)ServiceMain},
|
||||
{nullptr, nullptr}};
|
||||
|
||||
if (!StartServiceCtrlDispatcher(ste)) {
|
||||
std::cerr << "FATAL: StartServiceCtrlDispatcher has failed with "
|
||||
<< GetLastError() << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
void WindowsService::installService() {
|
||||
CHAR path[MAX_PATH];
|
||||
|
||||
if (!GetModuleFileNameA(nullptr, path, MAX_PATH)) {
|
||||
std::cerr << "FATAL: GetModuleFileNameA failed" << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// build command
|
||||
std::string command;
|
||||
|
||||
command += "\"";
|
||||
command += path;
|
||||
command += "\"";
|
||||
|
||||
command += " --start-service";
|
||||
|
||||
// register service
|
||||
InstallServiceCommand(command);
|
||||
}
|
||||
|
||||
void WindowsService::uninstallService(bool force) {
|
||||
CHAR path[MAX_PATH] = "";
|
||||
|
||||
if (!GetModuleFileNameA(nullptr, path, MAX_PATH)) {
|
||||
std::cerr << "FATAL: GetModuleFileNameA failed" << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
std::cout << "INFO: removing service '" << ServiceName << "'" << std::endl;
|
||||
|
||||
SC_HANDLE schSCManager =
|
||||
OpenSCManager(nullptr, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS);
|
||||
|
||||
if (schSCManager == 0) {
|
||||
std::cerr << "FATAL: OpenSCManager failed with " << GetLastError()
|
||||
<< std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
SC_HANDLE schService = OpenServiceA(
|
||||
schSCManager, // SCManager database
|
||||
ServiceName.c_str(), // name of service
|
||||
DELETE |
|
||||
SERVICE_QUERY_CONFIG); // first validate whether its us, then delete.
|
||||
|
||||
char serviceConfigMemory[8192]; // msdn says: 8k is enough.
|
||||
DWORD bytesNeeded = 0;
|
||||
if (QueryServiceConfig(schService,
|
||||
(LPQUERY_SERVICE_CONFIGA)&serviceConfigMemory,
|
||||
sizeof(serviceConfigMemory), &bytesNeeded)) {
|
||||
QUERY_SERVICE_CONFIG* cfg = (QUERY_SERVICE_CONFIG*)&serviceConfigMemory;
|
||||
|
||||
std::string command = std::string("\"") + std::string(path) +
|
||||
std::string("\" --start-service");
|
||||
if (strcmp(cfg->lpBinaryPathName, command.c_str())) {
|
||||
if (!force) {
|
||||
std::cerr << "NOT removing service of other installation: "
|
||||
<< cfg->lpBinaryPathName << " Our path is: " << path
|
||||
<< std::endl;
|
||||
|
||||
CloseServiceHandle(schSCManager);
|
||||
return;
|
||||
} else {
|
||||
std::cerr << "Removing service of other installation because of FORCE: "
|
||||
<< cfg->lpBinaryPathName << "Our path is: " << path
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CloseServiceHandle(schSCManager);
|
||||
|
||||
if (schService == 0) {
|
||||
std::cerr << "FATAL: OpenServiceA failed with " << GetLastError()
|
||||
<< std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (!DeleteService(schService)) {
|
||||
std::cerr << "FATAL: DeleteService failed with " << GetLastError()
|
||||
<< std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
CloseServiceHandle(schService);
|
||||
}
|
||||
|
||||
void WindowsService::serviceControlStart(bool waitForRunning) {
|
||||
TRI_ERRORBUF;
|
||||
SERVICE_STATUS_PROCESS ssp;
|
||||
DWORD bytesNeeded;
|
||||
|
||||
SC_HANDLE schSCManager =
|
||||
OpenSCManager(nullptr, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS);
|
||||
|
||||
if (schSCManager == 0) {
|
||||
TRI_SYSTEM_ERROR();
|
||||
std::cerr << "FATAL: OpenSCManager failed with " << windowsErrorBuf
|
||||
<< std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
// Get a handle to the service.
|
||||
auto arangoService = OpenService(
|
||||
schSCManager, ServiceName.c_str(),
|
||||
SERVICE_START | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS);
|
||||
|
||||
if (arangoService == nullptr) {
|
||||
TRI_SYSTEM_ERROR();
|
||||
std::cerr << "INFO: OpenService failed with " << windowsErrorBuf
|
||||
<< std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Make sure the service is not already started.
|
||||
if (!QueryServiceStatusEx(arangoService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp,
|
||||
sizeof(SERVICE_STATUS_PROCESS), &bytesNeeded)) {
|
||||
TRI_SYSTEM_ERROR();
|
||||
std::cerr << "INFO: QueryServiceStatusEx failed with " << windowsErrorBuf
|
||||
<< std::endl;
|
||||
CloseServiceHandle(schSCManager);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (ssp.dwCurrentState == SERVICE_RUNNING) {
|
||||
CloseServiceHandle(schSCManager);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
if (!StartService(arangoService, 0, nullptr)) {
|
||||
TRI_SYSTEM_ERROR();
|
||||
std::cerr << "StartService failed " << windowsErrorBuf << std::endl;
|
||||
CloseServiceHandle(arangoService);
|
||||
CloseServiceHandle(schSCManager);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Save the tick count and initial checkpoint.
|
||||
ssp.dwCurrentState = SERVICE_START_PENDING;
|
||||
|
||||
while (WaitForRunning && ssp.dwCurrentState != SERVICE_START_PENDING) {
|
||||
// we sleep 1 second before we re-check the status.
|
||||
Sleep(1000);
|
||||
|
||||
// Check the status again.
|
||||
|
||||
if (!QueryServiceStatusEx(
|
||||
arangoService,
|
||||
SC_STATUS_PROCESS_INFO, // info level
|
||||
(LPBYTE)&ssp, // address of structure
|
||||
sizeof(SERVICE_STATUS_PROCESS), // size of structure
|
||||
&bytesNeeded)) {
|
||||
TRI_SYSTEM_ERROR();
|
||||
std::cerr << "INFO: QueryServiceStatusEx failed with " << windowsErrorBuf
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CloseServiceHandle(arangoService);
|
||||
CloseServiceHandle(schSCManager);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
void WindowsService::serviceControlStop(bool waitForRunning) {
|
||||
TRI_ERRORBUF;
|
||||
SERVICE_STATUS_PROCESS ssp;
|
||||
DWORD bytesNeeded;
|
||||
|
||||
SC_HANDLE schSCManager =
|
||||
OpenSCManager(nullptr, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS);
|
||||
|
||||
if (schSCManager == 0) {
|
||||
TRI_SYSTEM_ERROR();
|
||||
std::cerr << "FATAL: OpenSCManager failed with " << windowsErrorBuf
|
||||
<< std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Get a handle to the service.
|
||||
auto arangoService = OpenService(
|
||||
schSCManager, ServiceName.c_str(),
|
||||
SERVICE_STOP | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS);
|
||||
|
||||
if (arangoService == nullptr) {
|
||||
TRI_SYSTEM_ERROR();
|
||||
std::cerr << "INFO: OpenService failed with " << windowsErrorBuf
|
||||
<< std::endl;
|
||||
CloseServiceHandle(schSCManager);
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure the service is not already stopped.
|
||||
if (!QueryServiceStatusEx(arangoService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp,
|
||||
sizeof(SERVICE_STATUS_PROCESS), &bytesNeeded)) {
|
||||
TRI_SYSTEM_ERROR();
|
||||
std::cerr << "INFO: QueryServiceStatusEx failed with " << windowsErrorBuf
|
||||
<< std::endl;
|
||||
CloseServiceHandle(schSCManager);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (ssp.dwCurrentState == SERVICE_STOPPED) {
|
||||
CloseServiceHandle(schSCManager);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
// Send a stop code to the service.
|
||||
if (!ControlService(arangoService, SERVICE_CONTROL_STOP,
|
||||
(LPSERVICE_STATUS)&ssp)) {
|
||||
TRI_SYSTEM_ERROR();
|
||||
std::cerr << "ControlService failed with " << windowsErrorBuf << std::endl;
|
||||
CloseServiceHandle(arangoService);
|
||||
CloseServiceHandle(schSCManager);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
while (WaitForShutdown && ssp.dwCurrentState == SERVICE_STOPPED) {
|
||||
// we sleep 1 second before we re-check the status.
|
||||
Sleep(1000);
|
||||
|
||||
if (!QueryServiceStatusEx(arangoService, SC_STATUS_PROCESS_INFO,
|
||||
(LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS),
|
||||
&bytesNeeded)) {
|
||||
TRI_SYSTEM_ERROR();
|
||||
printf("QueryServiceStatusEx failed (%s)\n", windowsErrorBuf);
|
||||
CloseServiceHandle(arangoService);
|
||||
CloseServiceHandle(schSCManager);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
CloseServiceHandle(arangoService);
|
||||
CloseServiceHandle(schSCManager);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
void WindowsService::checkService(int argc, char* argv[],
|
||||
std::function<int(int, char**)> runServer) {
|
||||
if (argc < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string cmd = argv[1];
|
||||
|
||||
if (cmd == "--install-service") {
|
||||
installService(argc, argv);
|
||||
}
|
||||
else if (cmd == "--start-service") {
|
||||
startService(runServer);
|
||||
}
|
||||
else if (cmd == "--servicectl-start") {
|
||||
serviceControlStart(false);
|
||||
}
|
||||
else if (cmd == "--servicectl-start-wait") {
|
||||
serviceControlStart(true);
|
||||
}
|
||||
else if (cmd == "--servicectl-stop") {
|
||||
serviceControlStop(false);
|
||||
}
|
||||
else if (cmd == "--servicectl-stop-wait") {
|
||||
serviceControlStop(true);
|
||||
}
|
||||
else if (cmd == "--uninstall-service") {
|
||||
bool force = ((argc > 2) && !strcmp(argv[2], "--force"));
|
||||
uninstallService(force);
|
||||
}
|
||||
}
|
|
@ -71,7 +71,6 @@ static std::string FriendlyServiceName = "ArangoDB - the multi-model database";
|
|||
static SERVICE_STATUS_HANDLE ServiceStatus;
|
||||
|
||||
// So we have a valid minidump area during startup:
|
||||
static std::string miniDumpFilename = "c:\\arangodpanic.dmp";
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief installs arangod as service with command-line
|
||||
|
@ -123,259 +122,6 @@ static void InstallServiceCommand(std::string command) {
|
|||
CloseServiceHandle(schService);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief installs a windows service
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void InstallService(int argc, char* argv[]) {
|
||||
CHAR path[MAX_PATH];
|
||||
|
||||
if (!GetModuleFileNameA(nullptr, path, MAX_PATH)) {
|
||||
std::cerr << "FATAL: GetModuleFileNameA failed" << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// build command
|
||||
std::string command;
|
||||
|
||||
command += "\"";
|
||||
command += path;
|
||||
command += "\"";
|
||||
|
||||
command += " --start-service";
|
||||
|
||||
// register service
|
||||
InstallServiceCommand(command);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief deletes a windows service
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void DeleteService(int argc, char* argv[], bool force) {
|
||||
CHAR path[MAX_PATH] = "";
|
||||
|
||||
if (!GetModuleFileNameA(nullptr, path, MAX_PATH)) {
|
||||
std::cerr << "FATAL: GetModuleFileNameA failed" << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
std::cout << "INFO: removing service '" << ServiceName << "'" << std::endl;
|
||||
|
||||
SC_HANDLE schSCManager =
|
||||
OpenSCManager(nullptr, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS);
|
||||
|
||||
if (schSCManager == 0) {
|
||||
std::cerr << "FATAL: OpenSCManager failed with " << GetLastError()
|
||||
<< std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
SC_HANDLE schService = OpenServiceA(
|
||||
schSCManager, // SCManager database
|
||||
ServiceName.c_str(), // name of service
|
||||
DELETE |
|
||||
SERVICE_QUERY_CONFIG); // first validate whether its us, then delete.
|
||||
|
||||
char serviceConfigMemory[8192]; // msdn says: 8k is enough.
|
||||
DWORD bytesNeeded = 0;
|
||||
if (QueryServiceConfig(schService,
|
||||
(LPQUERY_SERVICE_CONFIGA)&serviceConfigMemory,
|
||||
sizeof(serviceConfigMemory), &bytesNeeded)) {
|
||||
QUERY_SERVICE_CONFIG* cfg = (QUERY_SERVICE_CONFIG*)&serviceConfigMemory;
|
||||
|
||||
std::string command = std::string("\"") + std::string(path) +
|
||||
std::string("\" --start-service");
|
||||
if (strcmp(cfg->lpBinaryPathName, command.c_str())) {
|
||||
if (!force) {
|
||||
std::cerr << "NOT removing service of other installation: "
|
||||
<< cfg->lpBinaryPathName << " Our path is: " << path
|
||||
<< std::endl;
|
||||
|
||||
CloseServiceHandle(schSCManager);
|
||||
return;
|
||||
} else {
|
||||
std::cerr << "Removing service of other installation because of FORCE: "
|
||||
<< cfg->lpBinaryPathName << "Our path is: " << path
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CloseServiceHandle(schSCManager);
|
||||
|
||||
if (schService == 0) {
|
||||
std::cerr << "FATAL: OpenServiceA failed with " << GetLastError()
|
||||
<< std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (!DeleteService(schService)) {
|
||||
std::cerr << "FATAL: DeleteService failed with " << GetLastError()
|
||||
<< std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
CloseServiceHandle(schService);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Start the service and optionaly wait till its up & running
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void StartArangoService(bool WaitForRunning) {
|
||||
TRI_ERRORBUF;
|
||||
SERVICE_STATUS_PROCESS ssp;
|
||||
DWORD bytesNeeded;
|
||||
|
||||
SC_HANDLE schSCManager =
|
||||
OpenSCManager(nullptr, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS);
|
||||
|
||||
if (schSCManager == 0) {
|
||||
TRI_SYSTEM_ERROR();
|
||||
std::cerr << "FATAL: OpenSCManager failed with " << windowsErrorBuf
|
||||
<< std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
// Get a handle to the service.
|
||||
auto arangoService = OpenService(
|
||||
schSCManager, ServiceName.c_str(),
|
||||
SERVICE_START | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS);
|
||||
|
||||
if (arangoService == nullptr) {
|
||||
TRI_SYSTEM_ERROR();
|
||||
std::cerr << "INFO: OpenService failed with " << windowsErrorBuf
|
||||
<< std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Make sure the service is not already started.
|
||||
if (!QueryServiceStatusEx(arangoService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp,
|
||||
sizeof(SERVICE_STATUS_PROCESS), &bytesNeeded)) {
|
||||
TRI_SYSTEM_ERROR();
|
||||
std::cerr << "INFO: QueryServiceStatusEx failed with " << windowsErrorBuf
|
||||
<< std::endl;
|
||||
CloseServiceHandle(schSCManager);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (ssp.dwCurrentState == SERVICE_RUNNING) {
|
||||
CloseServiceHandle(schSCManager);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
if (!StartService(arangoService, 0, nullptr)) {
|
||||
TRI_SYSTEM_ERROR();
|
||||
std::cerr << "StartService failed " << windowsErrorBuf << std::endl;
|
||||
CloseServiceHandle(arangoService);
|
||||
CloseServiceHandle(schSCManager);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Save the tick count and initial checkpoint.
|
||||
ssp.dwCurrentState = SERVICE_START_PENDING;
|
||||
|
||||
while (WaitForRunning && ssp.dwCurrentState != SERVICE_START_PENDING) {
|
||||
// we sleep 1 second before we re-check the status.
|
||||
Sleep(1000);
|
||||
|
||||
// Check the status again.
|
||||
|
||||
if (!QueryServiceStatusEx(
|
||||
arangoService,
|
||||
SC_STATUS_PROCESS_INFO, // info level
|
||||
(LPBYTE)&ssp, // address of structure
|
||||
sizeof(SERVICE_STATUS_PROCESS), // size of structure
|
||||
&bytesNeeded)) {
|
||||
TRI_SYSTEM_ERROR();
|
||||
std::cerr << "INFO: QueryServiceStatusEx failed with " << windowsErrorBuf
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
CloseServiceHandle(arangoService);
|
||||
CloseServiceHandle(schSCManager);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Stop the service and optionaly wait till its all dead
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void StopArangoService(bool WaitForShutdown) {
|
||||
TRI_ERRORBUF;
|
||||
|
||||
SERVICE_STATUS_PROCESS ssp;
|
||||
DWORD bytesNeeded;
|
||||
|
||||
SC_HANDLE schSCManager =
|
||||
OpenSCManager(nullptr, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS);
|
||||
|
||||
if (schSCManager == 0) {
|
||||
TRI_SYSTEM_ERROR();
|
||||
std::cerr << "FATAL: OpenSCManager failed with " << windowsErrorBuf
|
||||
<< std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Get a handle to the service.
|
||||
auto arangoService = OpenService(
|
||||
schSCManager, ServiceName.c_str(),
|
||||
SERVICE_STOP | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS);
|
||||
|
||||
if (arangoService == nullptr) {
|
||||
TRI_SYSTEM_ERROR();
|
||||
std::cerr << "INFO: OpenService failed with " << windowsErrorBuf
|
||||
<< std::endl;
|
||||
CloseServiceHandle(schSCManager);
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure the service is not already stopped.
|
||||
if (!QueryServiceStatusEx(arangoService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp,
|
||||
sizeof(SERVICE_STATUS_PROCESS), &bytesNeeded)) {
|
||||
TRI_SYSTEM_ERROR();
|
||||
std::cerr << "INFO: QueryServiceStatusEx failed with " << windowsErrorBuf
|
||||
<< std::endl;
|
||||
CloseServiceHandle(schSCManager);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (ssp.dwCurrentState == SERVICE_STOPPED) {
|
||||
CloseServiceHandle(schSCManager);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
// Send a stop code to the service.
|
||||
if (!ControlService(arangoService, SERVICE_CONTROL_STOP,
|
||||
(LPSERVICE_STATUS)&ssp)) {
|
||||
TRI_SYSTEM_ERROR();
|
||||
std::cerr << "ControlService failed with " << windowsErrorBuf << std::endl;
|
||||
CloseServiceHandle(arangoService);
|
||||
CloseServiceHandle(schSCManager);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
while (WaitForShutdown && ssp.dwCurrentState == SERVICE_STOPPED) {
|
||||
// we sleep 1 second before we re-check the status.
|
||||
Sleep(1000);
|
||||
|
||||
if (!QueryServiceStatusEx(arangoService, SC_STATUS_PROCESS_INFO,
|
||||
(LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS),
|
||||
&bytesNeeded)) {
|
||||
TRI_SYSTEM_ERROR();
|
||||
printf("QueryServiceStatusEx failed (%s)\n", windowsErrorBuf);
|
||||
CloseServiceHandle(arangoService);
|
||||
CloseServiceHandle(schSCManager);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
CloseServiceHandle(arangoService);
|
||||
CloseServiceHandle(schSCManager);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief flips the status for a service
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -452,57 +198,6 @@ static void WINAPI ServiceCtrl(DWORD dwCtrlCode) {
|
|||
}
|
||||
}
|
||||
|
||||
#include <DbgHelp.h>
|
||||
LONG CALLBACK unhandledExceptionHandler(EXCEPTION_POINTERS* e) {
|
||||
#if ARANGODB_ENABLE_BACKTRACE
|
||||
|
||||
if ((e != nullptr) && (e->ExceptionRecord != nullptr)) {
|
||||
LOG_FATAL_WINDOWS("Unhandled exception: %d",
|
||||
(int)e->ExceptionRecord->ExceptionCode);
|
||||
} else {
|
||||
LOG_FATAL_WINDOWS("Unhandled exception without ExceptionCode!");
|
||||
}
|
||||
|
||||
std::string bt;
|
||||
TRI_GetBacktrace(bt);
|
||||
std::cerr << bt << std::endl;
|
||||
LOG_FATAL_WINDOWS(bt.c_str());
|
||||
|
||||
HANDLE hFile =
|
||||
CreateFile(miniDumpFilename.c_str(), GENERIC_WRITE, FILE_SHARE_READ, 0,
|
||||
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
LOG_FATAL_WINDOWS("could not open minidump file : %lu", GetLastError());
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
MINIDUMP_EXCEPTION_INFORMATION exceptionInfo;
|
||||
exceptionInfo.ThreadId = GetCurrentThreadId();
|
||||
exceptionInfo.ExceptionPointers = e;
|
||||
exceptionInfo.ClientPointers = FALSE;
|
||||
|
||||
MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile,
|
||||
MINIDUMP_TYPE(MiniDumpWithIndirectlyReferencedMemory |
|
||||
MiniDumpScanMemory | MiniDumpWithFullMemory),
|
||||
e ? &exceptionInfo : nullptr, nullptr, nullptr);
|
||||
|
||||
if (hFile) {
|
||||
CloseHandle(hFile);
|
||||
hFile = nullptr;
|
||||
}
|
||||
LOG_FATAL_WINDOWS("wrote minidump: %s", miniDumpFilename.c_str());
|
||||
#endif
|
||||
if ((e != nullptr) && (e->ExceptionRecord != nullptr)) {
|
||||
LOG_FATAL_WINDOWS("Unhandled exception: %d - will crash now.",
|
||||
(int)e->ExceptionRecord->ExceptionCode);
|
||||
} else {
|
||||
LOG_FATAL_WINDOWS(
|
||||
"Unhandled exception without ExceptionCode - will crash now.!");
|
||||
}
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief starts server as service
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -511,73 +206,9 @@ class WindowsArangoServer : public ArangoServer {
|
|||
private:
|
||||
DWORD _progress;
|
||||
|
||||
#if 0
|
||||
// TODO doesn't work that way.
|
||||
protected:
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief wrap ArangoDB server so we can properly emmit a status once we're
|
||||
/// really up and running.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual void startupProgress() override final {
|
||||
SetServiceStatus(SERVICE_START_PENDING, NO_ERROR, _progress++, 20000);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief wrap ArangoDB server so we can properly emmit a status once we're
|
||||
/// really up and running.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual void startupFinished() override final {
|
||||
// startup finished - signalize we're running.
|
||||
SetServiceStatus(SERVICE_RUNNING, NO_ERROR, 0, 0);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief wrap ArangoDB server so we can properly emmit a status on shutdown
|
||||
/// starting
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
virtual void shutDownBegins() override final {
|
||||
// startup finished - signalize we're running.
|
||||
SetServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 0, 0);
|
||||
}
|
||||
#endif
|
||||
public:
|
||||
WindowsArangoServer(int argc, char** argv) : ArangoServer(argc, argv) {
|
||||
_progress = 2;
|
||||
miniDumpFilename = TRI_GetTempPath();
|
||||
|
||||
miniDumpFilename +=
|
||||
"\\minidump_" + std::to_string(GetCurrentProcessId()) + ".dmp";
|
||||
}
|
||||
};
|
||||
|
||||
static int ARGC;
|
||||
static char** ARGV;
|
||||
|
||||
static void WINAPI ServiceMain(DWORD dwArgc, LPSTR* lpszArgv) {
|
||||
if (!TRI_InitWindowsEventLog()) {
|
||||
return;
|
||||
}
|
||||
// register the service ctrl handler, lpszArgv[0] contains service name
|
||||
ServiceStatus =
|
||||
RegisterServiceCtrlHandlerA(lpszArgv[0], (LPHANDLER_FUNCTION)ServiceCtrl);
|
||||
|
||||
// set start pending
|
||||
SetServiceStatus(SERVICE_START_PENDING, 0, 1, 10000);
|
||||
|
||||
IsRunning = true;
|
||||
ArangoInstance = new WindowsArangoServer(ARGC, ARGV);
|
||||
ArangoInstance->setMode(ArangoServer::ServerMode::MODE_SERVICE);
|
||||
|
||||
ArangoInstance->start();
|
||||
IsRunning = false;
|
||||
|
||||
// service has stopped
|
||||
SetServiceStatus(SERVICE_STOPPED, NO_ERROR, 0, 0);
|
||||
TRI_CloseWindowsEventlog();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief parse windows specific commandline options
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -627,26 +258,6 @@ bool TRI_ParseMoreArgs(int argc, char* argv[]) {
|
|||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief start the windows service
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_StartService(int argc, char* argv[]) {
|
||||
// create and start an ArangoDB server
|
||||
|
||||
SERVICE_TABLE_ENTRY ste[] = {{TEXT(""), (LPSERVICE_MAIN_FUNCTION)ServiceMain},
|
||||
{nullptr, nullptr}};
|
||||
|
||||
ARGC = argc;
|
||||
ARGV = argv;
|
||||
|
||||
if (!StartServiceCtrlDispatcher(ste)) {
|
||||
std::cerr << "FATAL: StartServiceCtrlDispatcher has failed with "
|
||||
<< GetLastError() << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -68,26 +68,13 @@
|
|||
using namespace arangodb;
|
||||
using namespace arangodb::wal;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Hooks for OS-Specific functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// YYY #warning TODO
|
||||
#if 0
|
||||
#ifdef _WIN32
|
||||
extern bool TRI_ParseMoreArgs(int argc, char* argv[]);
|
||||
extern void TRI_StartService(int argc, char* argv[]);
|
||||
#else
|
||||
bool TRI_ParseMoreArgs(int argc, char* argv[]) { return false; }
|
||||
void TRI_StartService(int argc, char* argv[]) {}
|
||||
WindowsService WINDOWS_SERVICE;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief creates an application server
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
static int runServer(int argc, char** argv) {
|
||||
ArangoGlobalContext context(argc, argv);
|
||||
context.installSegv();
|
||||
context.maskAllSignals();
|
||||
|
@ -100,6 +87,45 @@ int main(int argc, char* argv[]) {
|
|||
|
||||
application_features::ApplicationServer server(options);
|
||||
|
||||
#if 0
|
||||
#ifdef _WIN32
|
||||
application_features::ProgressHandler reporter{
|
||||
[](application_features::ServerState state) {
|
||||
switch (_state) {
|
||||
case ServerState::IN_WAIT:
|
||||
WINDOWS_SERVICE.startupFinished();
|
||||
break;
|
||||
case ServerState::IN_STOP:
|
||||
server.shutdownBegins();
|
||||
break;
|
||||
case ServerState::IN_COLLECT_OPTIONS:
|
||||
case ServerState::IN_VALIDATE_OPTIONS:
|
||||
case ServerState::IN_PREPARE:
|
||||
case ServerState::IN_START:
|
||||
WINDOWS_SERVICE.startupProgress();
|
||||
break;
|
||||
case ServerState::UNINITIALIZED:
|
||||
case ServerState::STOPPED:
|
||||
break;
|
||||
}
|
||||
},
|
||||
[](application_features::ServerState state, std::string const& name) {
|
||||
switch (_state) {
|
||||
case ServerState::IN_COLLECT_OPTIONS:
|
||||
case ServerState::IN_VALIDATE_OPTIONS:
|
||||
case ServerState::IN_PREPARE:
|
||||
case ServerState::IN_START:
|
||||
WINDOWS_SERVICE.startupProgress();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}};
|
||||
|
||||
server.addReporter(reporter);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
std::vector<std::string> nonServerFeatures = {
|
||||
"Action", "Affinity", "Agency",
|
||||
"Cluster", "Daemon", "Dispatcher",
|
||||
|
@ -175,35 +201,12 @@ int main(int argc, char* argv[]) {
|
|||
return context.exit(ret);
|
||||
}
|
||||
|
||||
// YYY #warning TODO
|
||||
int main(int argc, char* argv[]) {
|
||||
#if 0
|
||||
|
||||
// windows only
|
||||
bool const startAsService = TRI_ParseMoreArgs(argc, argv);
|
||||
|
||||
// initialize sub-systems
|
||||
if (startAsService) {
|
||||
TRI_StartService(argc, argv);
|
||||
} else {
|
||||
ArangoInstance = new ArangoServer(argc, argv);
|
||||
res = ArangoInstance->start();
|
||||
}
|
||||
|
||||
if (ArangoInstance != nullptr) {
|
||||
try {
|
||||
delete ArangoInstance;
|
||||
} catch (...) {
|
||||
// caught an error during shutdown
|
||||
res = EXIT_FAILURE;
|
||||
|
||||
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
|
||||
std::cerr << "Caught an exception during shutdown" << std::endl;
|
||||
#ifdef _WIN32
|
||||
WINDOWS_SERVICE.serviceStart(argc, argv, runServer);
|
||||
#endif
|
||||
}
|
||||
|
||||
ArangoInstance = nullptr;
|
||||
}
|
||||
|
||||
// shutdown sub-systems
|
||||
return context.exit(ret);
|
||||
#endif
|
||||
|
||||
return runServer(argc, argv);
|
||||
}
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
|
||||
using namespace arangodb;
|
||||
|
||||
// constants
|
||||
std::string const StaticStrings::N1800("1800");
|
||||
|
||||
// system attribute names
|
||||
std::string const StaticStrings::IdString("_id");
|
||||
std::string const StaticStrings::KeyString("_key");
|
||||
|
@ -32,8 +35,21 @@ std::string const StaticStrings::FromString("_from");
|
|||
std::string const StaticStrings::ToString("_to");
|
||||
|
||||
// HTTP headers
|
||||
std::string const StaticStrings::AcceptHeader("accept");
|
||||
std::string const StaticStrings::Accept("accept");
|
||||
std::string const StaticStrings::AccessControlAllowCredentials("access-control-allow-credentials");
|
||||
std::string const StaticStrings::AccessControlAllowHeaders("access-control-allow-headers");
|
||||
std::string const StaticStrings::AccessControlAllowMethods("access-control-allow-methods");
|
||||
std::string const StaticStrings::AccessControlAllowOrigin("access-control-allow-origin");
|
||||
std::string const StaticStrings::AccessControlExposeHeaders("access-control-expose-headers");
|
||||
std::string const StaticStrings::AccessControlMaxAge("access-control-max-age");
|
||||
std::string const StaticStrings::AccessControlRequestHeaders("access-control-request-headers");
|
||||
std::string const StaticStrings::Allow("allow");
|
||||
std::string const StaticStrings::Close("Close");
|
||||
std::string const StaticStrings::Connection("connection");
|
||||
std::string const StaticStrings::ContentTypeHeader("content-type");
|
||||
std::string const StaticStrings::KeepAlive("Close");
|
||||
std::string const StaticStrings::Location("location");
|
||||
std::string const StaticStrings::WwwAuthenticate("www-authenticate");
|
||||
|
||||
// mime types
|
||||
std::string const StaticStrings::MimeTypeJson("application/json; charset=utf-8");
|
||||
|
|
|
@ -28,7 +28,11 @@
|
|||
namespace arangodb {
|
||||
class StaticStrings {
|
||||
StaticStrings() = delete;
|
||||
|
||||
public:
|
||||
// constants
|
||||
static std::string const N1800;
|
||||
|
||||
// system attribute names
|
||||
static std::string const IdString;
|
||||
static std::string const KeyString;
|
||||
|
@ -37,8 +41,21 @@ class StaticStrings {
|
|||
static std::string const ToString;
|
||||
|
||||
// HTTP headers
|
||||
static std::string const AcceptHeader;
|
||||
static std::string const Accept;
|
||||
static std::string const AccessControlAllowCredentials;
|
||||
static std::string const AccessControlAllowHeaders;
|
||||
static std::string const AccessControlAllowMethods;
|
||||
static std::string const AccessControlAllowOrigin;
|
||||
static std::string const AccessControlExposeHeaders;
|
||||
static std::string const AccessControlMaxAge;
|
||||
static std::string const AccessControlRequestHeaders;
|
||||
static std::string const Allow;
|
||||
static std::string const Close;
|
||||
static std::string const Connection;
|
||||
static std::string const ContentTypeHeader;
|
||||
static std::string const KeepAlive;
|
||||
static std::string const Location;
|
||||
static std::string const WwwAuthenticate;
|
||||
|
||||
// mime types
|
||||
static std::string const MimeTypeVPack;
|
||||
|
|
|
@ -127,7 +127,7 @@ function main(argv) {
|
|||
serverArgs["javascript.app-path"] = fs.join(tmpDataDir, "apps");
|
||||
serverArgs["javascript.startup-directory"] = "js";
|
||||
serverArgs["log.file"] = fs.join(tmpDataDir, "log");
|
||||
serverArgs["server.disable-authentication"] = "true";
|
||||
serverArgs["server.authentication"] = "false";
|
||||
serverArgs["server.endpoint"] = serverEndpoint;
|
||||
serverArgs["server.threads"] = "3";
|
||||
|
||||
|
|
Loading…
Reference in New Issue