1
0
Fork 0

cleanup action queues

This commit is contained in:
Frank Celler 2012-05-25 14:28:27 +02:00
parent 888436b95d
commit b2d521ee35
14 changed files with 228 additions and 218 deletions

View File

@ -3154,6 +3154,8 @@ unittests-shell-client:
kill `cat $(PIDFILE)`
while test -f $(PIDFILE); do sleep 1; done
@if [ "$(VALGRIND)" != "" ]; then sleep 60; fi
@rm -rf "$(VOCDIR)"
@echo

View File

@ -239,6 +239,8 @@ unittests-shell-client:
kill `cat $(PIDFILE)`
while test -f $(PIDFILE); do sleep 1; done
@if [ "$(VALGRIND)" != "" ]; then sleep 60; fi
@rm -rf "$(VOCDIR)"
@echo

View File

@ -50,10 +50,10 @@ using namespace triagens::arango;
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
RestActionHandler::RestActionHandler (HttpRequest* request, pair<TRI_vocbase_t*, set<string>*>* data)
: RestVocbaseBaseHandler(request, data->first),
RestActionHandler::RestActionHandler (HttpRequest* request, action_options_t* data)
: RestVocbaseBaseHandler(request, data->_vocbase),
_action(0),
_allowedQueues(*data->second) {
_queue(data->_queue) {
_action = TRI_LookupActionVocBase(request);
}
@ -83,9 +83,7 @@ bool RestActionHandler::isDirect () {
////////////////////////////////////////////////////////////////////////////////
string const& RestActionHandler::queue () {
static string const standard = "STANDARD";
return _action == 0 ? standard : _action->_queue;
return _queue;
}
////////////////////////////////////////////////////////////////////////////////
@ -110,50 +108,34 @@ HttpHandler::status_e RestActionHandler::execute () {
}
else {
// check the permission base on queue name
bool allowed = false;
for (set<string>::iterator i = _allowedQueues.begin(); i != _allowedQueues.end(); ++i) {
if (_action->_queue == *i) {
allowed = true;
break;
}
}
if (! allowed) {
generateForbidden();
}
else {
// extract the sub-request type
HttpRequest::HttpRequestType type = request->requestType();
// extract the sub-request type
HttpRequest::HttpRequestType type = request->requestType();
// prepare logging
switch (type) {
case HttpRequest::HTTP_REQUEST_DELETE: task = &logExecute; break;
case HttpRequest::HTTP_REQUEST_GET: task = &logExecute; break;
case HttpRequest::HTTP_REQUEST_POST: task = &logExecute; break;
case HttpRequest::HTTP_REQUEST_PUT: task = &logExecute; break;
case HttpRequest::HTTP_REQUEST_HEAD: task = &logHead; break;
case HttpRequest::HTTP_REQUEST_ILLEGAL: task = &logIllegal; break;
}
// prepare logging
switch (type) {
case HttpRequest::HTTP_REQUEST_DELETE: task = &logExecute; break;
case HttpRequest::HTTP_REQUEST_GET: task = &logExecute; break;
case HttpRequest::HTTP_REQUEST_POST: task = &logExecute; break;
case HttpRequest::HTTP_REQUEST_PUT: task = &logExecute; break;
case HttpRequest::HTTP_REQUEST_HEAD: task = &logHead; break;
case HttpRequest::HTTP_REQUEST_ILLEGAL: task = &logIllegal; break;
}
_timing << *task;
LOGGER_REQUEST_IN_START_I(_timing);
_timing << *task;
LOGGER_REQUEST_IN_START_I(_timing);
// execute one of the CRUD methods
switch (type) {
case HttpRequest::HTTP_REQUEST_GET: res = executeAction(); break;
case HttpRequest::HTTP_REQUEST_POST: res = executeAction(); break;
case HttpRequest::HTTP_REQUEST_PUT: res = executeAction(); break;
case HttpRequest::HTTP_REQUEST_DELETE: res = executeAction(); break;
case HttpRequest::HTTP_REQUEST_HEAD: res = executeAction(); break;
// execute one of the CRUD methods
switch (type) {
case HttpRequest::HTTP_REQUEST_GET: res = executeAction(); break;
case HttpRequest::HTTP_REQUEST_POST: res = executeAction(); break;
case HttpRequest::HTTP_REQUEST_PUT: res = executeAction(); break;
case HttpRequest::HTTP_REQUEST_DELETE: res = executeAction(); break;
case HttpRequest::HTTP_REQUEST_HEAD: res = executeAction(); break;
default:
res = false;
generateNotImplemented("METHOD");
break;
}
default:
res = false;
generateNotImplemented("METHOD");
break;
}
}

View File

@ -54,6 +54,30 @@ namespace triagens {
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- public types
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoDB
/// @{
////////////////////////////////////////////////////////////////////////////////
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief constructor options
////////////////////////////////////////////////////////////////////////////////
struct action_options_t {
TRI_vocbase_t* _vocbase;
string _queue;
};
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- constructors and destructors
// -----------------------------------------------------------------------------
@ -69,7 +93,7 @@ namespace triagens {
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
RestActionHandler (rest::HttpRequest*, std::pair<TRI_vocbase_t*, set<string>*>*);
RestActionHandler (rest::HttpRequest*, action_options_t*);
////////////////////////////////////////////////////////////////////////////////
/// @}
@ -148,10 +172,10 @@ RestActionHandler (rest::HttpRequest*, std::pair<TRI_vocbase_t*, set<string>*>*)
TRI_action_t const* _action;
////////////////////////////////////////////////////////////////////////////////
/// @brief allowed queues
/// @brief queue to use
////////////////////////////////////////////////////////////////////////////////
set<string> const& _allowedQueues;
string _queue;
};
}
}

View File

@ -100,11 +100,13 @@ uint64_t ActionDispatcherThread::_gcInterval = 1000;
ActionDispatcherThread::ActionDispatcherThread (rest::DispatcherQueue* queue,
string const& actionQueue,
set<string> const& allowedContexts,
JSLoader* actionLoader)
: DispatcherThread(queue),
_isolate(0),
_context(),
_actionQueue(actionQueue),
_allowedContexts(allowedContexts),
_actionLoader(actionLoader),
_gc(0),
_v8g(0) {
@ -258,7 +260,7 @@ void ActionDispatcherThread::initialise () {
_v8g = TRI_InitV8VocBridge(_context, _vocbase);
TRI_InitV8Queries(_context);
TRI_InitV8Actions(_context, _actionQueue.c_str());
TRI_InitV8Actions(_context, _actionQueue, _allowedContexts);
TRI_InitV8Conversions(_context);
TRI_InitV8Utils(_context, _startupModules);
TRI_InitV8Shell(_context);

View File

@ -116,7 +116,10 @@ namespace triagens {
/// @brief constructs a new dispatcher thread
////////////////////////////////////////////////////////////////////////////////
ActionDispatcherThread (rest::DispatcherQueue*, string const& actionQueue, JSLoader*);
ActionDispatcherThread (rest::DispatcherQueue*,
string const& actionQueue,
set<string> const& allowedContexts,
JSLoader*);
////////////////////////////////////////////////////////////////////////////////
/// @brief destructs a dispatcher thread
@ -236,7 +239,7 @@ namespace triagens {
v8::Isolate* _isolate;
////////////////////////////////////////////////////////////////////////////////
/// @brief context
/// @brief V8 context
////////////////////////////////////////////////////////////////////////////////
v8::Persistent<v8::Context> _context;
@ -247,6 +250,12 @@ namespace triagens {
std::string _actionQueue;
////////////////////////////////////////////////////////////////////////////////
/// @brief allowed action contexts
////////////////////////////////////////////////////////////////////////////////
std::set<std::string> _allowedContexts;
////////////////////////////////////////////////////////////////////////////////
/// @brief action path
////////////////////////////////////////////////////////////////////////////////

View File

@ -113,10 +113,16 @@ static JSLoader StartupLoader;
static JSLoader ActionLoader;
////////////////////////////////////////////////////////////////////////////////
/// @brief system action loader
/// @brief allowed client actions
////////////////////////////////////////////////////////////////////////////////
static JSLoader SystemActionLoader;
static set<string> AllowedClientActions;
////////////////////////////////////////////////////////////////////////////////
/// @brief allowed admin actions
////////////////////////////////////////////////////////////////////////////////
static set<string> AllowedAdminActions;
////////////////////////////////////////////////////////////////////////////////
/// @}
@ -136,7 +142,7 @@ static JSLoader SystemActionLoader;
////////////////////////////////////////////////////////////////////////////////
static DispatcherThread* ClientActionDispatcherThreadCreator (DispatcherQueue* queue) {
return new ActionDispatcherThread(queue, "CLIENT", &ActionLoader);
return new ActionDispatcherThread(queue, "CLIENT", AllowedClientActions, &ActionLoader);
}
////////////////////////////////////////////////////////////////////////////////
@ -144,7 +150,52 @@ static DispatcherThread* ClientActionDispatcherThreadCreator (DispatcherQueue* q
////////////////////////////////////////////////////////////////////////////////
static DispatcherThread* SystemActionDispatcherThreadCreator (DispatcherQueue* queue) {
return new ActionDispatcherThread(queue, "SYSTEM", &SystemActionLoader);
return new ActionDispatcherThread(queue, "SYSTEM", AllowedAdminActions, &ActionLoader);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief define "_api" handlers
////////////////////////////////////////////////////////////////////////////////
static void DefineApiHandlers (HttpHandlerFactory* factory,
ApplicationAdminServer* admin,
TRI_vocbase_t* vocbase) {
// add "/version" handler
admin->addBasicHandlers(factory, "/_api");
// add "/document" handler
factory->addPrefixHandler(RestVocbaseBaseHandler::DOCUMENT_PATH,
RestHandlerCreator<RestDocumentHandler>::createData<TRI_vocbase_t*>,
vocbase);
// add "/edge" handler
factory->addPrefixHandler(RestVocbaseBaseHandler::EDGE_PATH,
RestHandlerCreator<RestEdgeHandler>::createData<TRI_vocbase_t*>,
vocbase);
// add import handler
factory->addPrefixHandler(RestVocbaseBaseHandler::DOCUMENT_IMPORT_PATH,
RestHandlerCreator<RestImportHandler>::createData<TRI_vocbase_t*>,
vocbase);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief define "admin" handlers
////////////////////////////////////////////////////////////////////////////////
static void DefineAdminHandlers (HttpHandlerFactory* factory,
ApplicationAdminServer* admin,
ApplicationUserManager* user,
TRI_vocbase_t* vocbase) {
// add "/version" handler
admin->addBasicHandlers(factory, "/_admin");
// add admin handlers
admin->addHandlers(factory, "/_admin");
user->addHandlers(factory, "/_admin");
}
////////////////////////////////////////////////////////////////////////////////
@ -181,7 +232,6 @@ ArangoServer::ArangoServer (int argc, char** argv)
_dispatcherThreads(1),
_startupPath(),
_startupModules("js/modules"),
_actionPath(),
_systemActionPath(),
_actionThreads(1),
_gcInterval(1000),
@ -424,7 +474,6 @@ void ArangoServer::buildApplicationServer () {
additional["JAVASCRIPT Options:help-admin"]
("startup.directory", &_startupPath, "path to the directory containing alternate startup scripts")
("startup.modules-path", &_startupModules, "one or more directories separated by cola")
("action.directory", &_actionPath, "path to the action directory, defaults to <database.directory>/_ACTIONS")
("gc.interval", &_gcInterval, "garbage collection interval (each x requests)")
;
@ -477,51 +526,12 @@ void ArangoServer::buildApplicationServer () {
StartupLoader.setDirectory(_startupPath);
}
if (_actionPath.empty()) {
char* path = TRI_Concatenate2File(_databasePath.c_str(), "_ACTIONS");
if (path == 0) {
LOGGER_FATAL << "out-of-memory";
exit(EXIT_FAILURE);
}
string pathString(path);
TRI_FreeString(TRI_CORE_MEM_ZONE, path);
if (! TRI_IsDirectory(pathString.c_str())) {
bool ok = TRI_ExistsFile(pathString.c_str());
if (ok) {
LOGGER_FATAL << "action directory '" << pathString << "' must be a directory";
cerr << "action directory '" << pathString << "' must be a directory\n";
LOGGER_INFO << "please use the '--database.directory' option";
exit(EXIT_FAILURE);
}
ok = TRI_CreateDirectory(pathString.c_str());
if (! ok) {
LOGGER_FATAL << "cannot create action directory '" << pathString << "': " << TRI_last_error();
LOGGER_INFO << "please use the '--database.directory' option";
exit(EXIT_FAILURE);
}
}
ActionLoader.setDirectory(pathString);
LOGGER_INFO << "using database action files at '" << pathString << "'";
}
else {
ActionLoader.setDirectory(_actionPath);
LOGGER_INFO << "using alternate action files at '" << _actionPath << "'";
}
if (! _systemActionPath.empty()) {
SystemActionLoader.setDirectory(_systemActionPath);
LOGGER_INFO << "using system action files at '" << _systemActionPath << "'";
ActionLoader.setDirectory(_systemActionPath);
LOGGER_INFO << "using action files at '" << _systemActionPath << "'";
}
else {
LOGGER_INFO << "system actions are disabled, empty system action path";
LOGGER_INFO << "actions are disabled, empty system action path";
}
// .............................................................................
@ -581,6 +591,10 @@ void ArangoServer::buildApplicationServer () {
int ArangoServer::startupServer () {
v8::HandleScope handle_scope;
bool useHttpPort = ! _httpPort.empty();
bool useAdminPort = ! _adminPort.empty() && _adminPort != "-";
bool shareAdminPort = useHttpPort && _adminPort.empty();
// .............................................................................
// open the database
// .............................................................................
@ -616,51 +630,50 @@ int ArangoServer::startupServer () {
_actionThreads = 1;
}
safe_cast<DispatcherImpl*>(dispatcher)->addQueue("CLIENT", ClientActionDispatcherThreadCreator, _actionThreads);
safe_cast<DispatcherImpl*>(dispatcher)->addQueue("SYSTEM", SystemActionDispatcherThreadCreator, 2);
// if we share a the server port for admin and client, only create a SYSTEM queue
if (shareAdminPort) {
safe_cast<DispatcherImpl*>(dispatcher)->addQueue("CLIENT", ClientActionDispatcherThreadCreator, _actionThreads);
}
// use a separate queue for administrator requests
else {
safe_cast<DispatcherImpl*>(dispatcher)->addQueue("CLIENT", ClientActionDispatcherThreadCreator, _actionThreads);
if (useAdminPort) {
safe_cast<DispatcherImpl*>(dispatcher)->addQueue("SYSTEM", SystemActionDispatcherThreadCreator, 2);
}
}
// .............................................................................
// create a http server and http handler factory
// .............................................................................
bool useHttpPort = ! _httpPort.empty();
bool useAdminPort = ! _adminPort.empty() && _adminPort != "-";
bool shareAdminPort = useHttpPort && _adminPort.empty();
Scheduler* scheduler = _applicationServer->scheduler();
set<string> allowedQueuesHttp;
pair< TRI_vocbase_t*, set<string>* > handlerDataHttp = make_pair(_vocbase, &allowedQueuesHttp);
RestActionHandler::action_options_t httpOptions;
httpOptions._vocbase = _vocbase;
httpOptions._queue = "CLIENT";
if (useHttpPort) {
HttpHandlerFactory* factory = new HttpHandlerFactory();
allowedQueuesHttp.insert("STANDARD");
allowedQueuesHttp.insert("CLIENT");
AllowedClientActions.insert("user");
AllowedClientActions.insert("api");
vector<AddressPort> ports;
ports.push_back(AddressPort(_httpPort));
// add /version URL
_applicationAdminServer->addBasicHandlers(factory, "/_api");
factory->addPrefixHandler(RestVocbaseBaseHandler::DOCUMENT_PATH, RestHandlerCreator<RestDocumentHandler>::createData<TRI_vocbase_t*>, _vocbase);
factory->addPrefixHandler(RestVocbaseBaseHandler::EDGE_PATH, RestHandlerCreator<RestEdgeHandler>::createData<TRI_vocbase_t*>, _vocbase);
factory->addPrefixHandler(RestVocbaseBaseHandler::DOCUMENT_IMPORT_PATH, RestHandlerCreator<RestImportHandler>::createData<TRI_vocbase_t*>, _vocbase);
DefineApiHandlers(factory, _applicationAdminServer, _vocbase);
if (shareAdminPort) {
// add /version URL
_applicationAdminServer->addBasicHandlers(factory, "/_admin");
_applicationAdminServer->addHandlers(factory, "/_admin");
_applicationUserManager->addHandlers(factory, "/_admin");
allowedQueuesHttp.insert("SYSTEM");
DefineAdminHandlers(factory, _applicationAdminServer, _applicationUserManager, _vocbase);
AllowedClientActions.insert("admin");
}
// add action handler
factory->addPrefixHandler("/",
RestHandlerCreator<RestActionHandler>::createData< pair< TRI_vocbase_t*, set<string>* >* >,
(void*) &handlerDataHttp);
RestHandlerCreator<RestActionHandler>::createData<RestActionHandler::action_options_t*>,
(void*) &httpOptions);
_httpServer = _applicationHttpServer->buildServer(new ArangoHttpServer(scheduler, dispatcher), factory, ports);
}
@ -669,36 +682,28 @@ int ArangoServer::startupServer () {
// create a http server and http handler factory
// .............................................................................
set<string> allowedQueuesAdmin;
pair< TRI_vocbase_t*, set<string>* > handlerDataAdmin = make_pair(_vocbase, &allowedQueuesAdmin);
RestActionHandler::action_options_t adminOptions;
adminOptions._vocbase = _vocbase;
adminOptions._queue = "SYSTEM";
if (useAdminPort) {
HttpHandlerFactory* adminFactory = new HttpHandlerFactory();
HttpHandlerFactory* factory = new HttpHandlerFactory();
allowedQueuesAdmin.insert("STANDARD");
allowedQueuesAdmin.insert("CLIENT");
allowedQueuesAdmin.insert("SYSTEM");
AllowedAdminActions.insert("api");
AllowedAdminActions.insert("admin");
vector<AddressPort> adminPorts;
adminPorts.push_back(AddressPort(_adminPort));
// add /version URL
_applicationAdminServer->addBasicHandlers(adminFactory, "/_admin");
_applicationAdminServer->addBasicHandlers(adminFactory, "/_api");
DefineApiHandlers(factory, _applicationAdminServer, _vocbase);
DefineAdminHandlers(factory, _applicationAdminServer, _applicationUserManager, _vocbase);
_applicationAdminServer->addHandlers(adminFactory, "/_admin");
_applicationUserManager->addHandlers(adminFactory, "/_admin");
// add action handler
factory->addPrefixHandler("/",
RestHandlerCreator<RestActionHandler>::createData<RestActionHandler::action_options_t*>,
(void*) &adminOptions);
adminFactory->addPrefixHandler(RestVocbaseBaseHandler::DOCUMENT_PATH, RestHandlerCreator<RestDocumentHandler>::createData<TRI_vocbase_t*>, _vocbase);
adminFactory->addPrefixHandler(RestVocbaseBaseHandler::EDGE_PATH, RestHandlerCreator<RestEdgeHandler>::createData<TRI_vocbase_t*>, _vocbase);
adminFactory->addPrefixHandler("/",
RestHandlerCreator<RestActionHandler>::createData< pair< TRI_vocbase_t*, set<string>* >* >,
(void*) &handlerDataAdmin);
adminFactory->addPrefixHandler(RestVocbaseBaseHandler::DOCUMENT_IMPORT_PATH, RestHandlerCreator<RestImportHandler>::createData<TRI_vocbase_t*>, _vocbase);
_adminHttpServer = _applicationHttpServer->buildServer(new ArangoHttpServer(scheduler, dispatcher), adminFactory, adminPorts);
_adminHttpServer = _applicationHttpServer->buildServer(new ArangoHttpServer(scheduler, dispatcher), factory, adminPorts);
}
// .............................................................................

View File

@ -288,17 +288,6 @@ namespace triagens {
string _startupModules;
////////////////////////////////////////////////////////////////////////////////
/// @brief path to the action directory
///
/// @CMDOPT{--action.directory @CA{directory}}
///
/// Specifies the @CA{directory} path to user defined Javascript files that
/// can be invoked as actions.
////////////////////////////////////////////////////////////////////////////////
string _actionPath;
////////////////////////////////////////////////////////////////////////////////
/// @brief path to the system action directory
///

View File

@ -187,12 +187,7 @@ static TRI_action_options_t ParseActionOptions (TRI_v8_global_t* v8g,
////////////////////////////////////////////////////////////////////////////////
/// @brief defines a new action
///
/// @FUN{defineAction(@FA{name}, @FA{queue}, @FA{callback}, @FA{parameter})}
///
/// Possible queues are:
/// - "CLIENT"
/// - "SYSTEM"
/// - "MONITORING"
/// @FUN{defineAction(@FA{name}, @FA{callback}, @FA{parameter})}
////////////////////////////////////////////////////////////////////////////////
static v8::Handle<v8::Value> JS_DefineAction (v8::Arguments const& argv) {
@ -201,8 +196,8 @@ static v8::Handle<v8::Value> JS_DefineAction (v8::Arguments const& argv) {
v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData();
if (argv.Length() != 4) {
return scope.Close(v8::ThrowException(v8::String::New("usage: SYS_DEFINE_ACTION(<name>, <queue>, <callback>, <parameter>)")));
if (argv.Length() != 3) {
return scope.Close(v8::ThrowException(v8::String::New("usage: SYS_DEFINE_ACTION(<name>, <callback>, <parameter>)")));
}
// extract the action name
@ -214,31 +209,18 @@ static v8::Handle<v8::Value> JS_DefineAction (v8::Arguments const& argv) {
string name = *utf8name;
// extract the action queue
v8::String::Utf8Value utf8queue(argv[1]);
if (*utf8queue == 0) {
return scope.Close(v8::ThrowException(v8::String::New("<queue> must be an UTF8 name")));
}
string queue = *utf8queue;
if (queue != "CLIENT" && queue != "SYSTEM" && queue != "MONITORING") {
return scope.Close(v8::ThrowException(v8::String::New("<queue> must CLIENT, SYSTEM, MONITORING")));
}
// extract the action callback
if (! argv[2]->IsFunction()) {
if (! argv[1]->IsFunction()) {
return scope.Close(v8::ThrowException(v8::String::New("<callback> must be a function")));
}
v8::Handle<v8::Function> callback = v8::Handle<v8::Function>::Cast(argv[2]);
v8::Handle<v8::Function> callback = v8::Handle<v8::Function>::Cast(argv[1]);
// extract the options
v8::Handle<v8::Object> options;
if (argv[3]->IsObject()) {
options = argv[3]->ToObject();
if (argv[2]->IsObject()) {
options = argv[2]->ToObject();
}
else {
options = v8::Object::New();
@ -247,7 +229,7 @@ static v8::Handle<v8::Value> JS_DefineAction (v8::Arguments const& argv) {
TRI_action_options_t ao = ParseActionOptions(v8g, options);
// store an action with the given name
TRI_CreateActionVocBase(name, queue, ao, callback);
TRI_CreateActionVocBase(name, ao, callback);
return scope.Close(v8::Undefined());
}
@ -270,7 +252,6 @@ static v8::Handle<v8::Value> JS_DefineAction (v8::Arguments const& argv) {
////////////////////////////////////////////////////////////////////////////////
void TRI_CreateActionVocBase (string const& name,
string const& queue,
TRI_action_options_t ao,
v8::Handle<v8::Function> callback) {
@ -293,7 +274,6 @@ void TRI_CreateActionVocBase (string const& name,
action->_url = url;
action->_urlParts = StringUtils::split(url, "/").size();
action->_queue = queue;
action->_options = ao;
Actions[url] = action;
@ -311,7 +291,7 @@ void TRI_CreateActionVocBase (string const& name,
v8g->Actions[url] = v8::Persistent<v8::Function>::New(callback);
// some debug output
LOG_DEBUG("created action '%s' for queue %s", url.c_str(), queue.c_str());
LOG_DEBUG("created action '%s'", url.c_str());
}
////////////////////////////////////////////////////////////////////////////////
@ -600,7 +580,9 @@ HttpResponse* TRI_ExecuteActionVocBase (TRI_vocbase_t* vocbase,
/// @brief stores the V8 actions function inside the global variable
////////////////////////////////////////////////////////////////////////////////
void TRI_InitV8Actions (v8::Handle<v8::Context> context, char const* actionQueue) {
void TRI_InitV8Actions (v8::Handle<v8::Context> context,
string const& actionQueue,
set<string> const& allowedContexts) {
v8::HandleScope scope;
// check the isolate
@ -617,7 +599,18 @@ void TRI_InitV8Actions (v8::Handle<v8::Context> context, char const* actionQueue
// .............................................................................
context->Global()->Set(v8::String::New("SYS_ACTION_QUEUE"),
v8::String::New(actionQueue),
v8::String::New(actionQueue.c_str()),
v8::ReadOnly);
v8::Handle<v8::Array> contexts = v8::Array::New();
size_t pos = 0;
for (set<string>::iterator i = allowedContexts.begin(); i != allowedContexts.end(); ++i, ++pos) {
contexts->Set(pos, v8::String::New((*i).c_str()));
}
context->Global()->Set(v8::String::New("SYS_ACTION_CONTEXTS"),
contexts,
v8::ReadOnly);
// .............................................................................

View File

@ -199,7 +199,6 @@ TRI_action_options_t;
typedef struct TRI_action_s {
std::string _url;
size_t _urlParts;
std::string _queue;
TRI_action_options_t _options;
}
TRI_action_t;
@ -222,7 +221,6 @@ TRI_action_t;
////////////////////////////////////////////////////////////////////////////////
void TRI_CreateActionVocBase (std::string const& name,
std::string const& queue,
TRI_action_options_t ao,
v8::Handle<v8::Function> callback);
@ -250,7 +248,9 @@ triagens::rest::HttpResponse* TRI_ExecuteActionVocBase (TRI_vocbase_t* vocbase,
/// @brief stores the V8 actions function inside the global variable
////////////////////////////////////////////////////////////////////////////////
void TRI_InitV8Actions (v8::Handle<v8::Context> context, char const* actionQueue);
void TRI_InitV8Actions (v8::Handle<v8::Context> context,
std::string const& actionQueue,
std::set<std::string> const& allowedContexts);
////////////////////////////////////////////////////////////////////////////////
/// @}

View File

@ -52,6 +52,13 @@ actions.defineHttp({
callback : GET_time
});
actions.defineHttp({
url : "_admin/time",
context : "admin",
prefix : false,
callback : GET_time
});
////////////////////////////////////////////////////////////////////////////////
/// @brief returns system status information for the server
////////////////////////////////////////////////////////////////////////////////

View File

@ -59,14 +59,22 @@ static string JS_server_server =
" internal.edges = edges;\n"
" internal.ArangoCollection = ArangoCollection;\n"
" internal.ArangoEdgesCollection = ArangoEdgesCollection;\n"
" internal.allowedActionContexts = {}\n"
"\n"
" if (typeof SYS_DEFINE_ACTION === \"undefined\") {\n"
" ModuleCache[\"/internal\"].exports.defineAction = function() {\n"
" internal.defineAction = function() {\n"
" console.error(\"SYS_DEFINE_ACTION not available\");\n"
" };\n"
" }\n"
" else {\n"
" ModuleCache[\"/internal\"].exports.defineAction = SYS_DEFINE_ACTION;\n"
" var i;\n"
" console.error(SYS_ACTION_CONTEXTS + \", \" + SYS_ACTION_QUEUE);\n"
"\n"
" for (i = 0; i < SYS_ACTION_CONTEXTS.length; ++i) {\n"
" internal.allowedActionContexts[SYS_ACTION_CONTEXTS[i]] = true;\n"
" }\n"
"\n"
" internal.defineAction = SYS_DEFINE_ACTION;\n"
" }\n"
"\n"
"////////////////////////////////////////////////////////////////////////////////\n"

View File

@ -150,32 +150,11 @@ function DefineHttp (options) {
for (var i = 0; i < contexts.length; ++i) {
var context = contexts[i];
var use = false;
if (context == "admin") {
if (SYS_ACTION_QUEUE == "SYSTEM") {
use = true;
}
}
else if (context == "api") {
if (SYS_ACTION_QUEUE == "SYSTEM" || SYS_ACTION_QUEUE == "CLIENT") {
use = true;
}
}
else if (context == "user") {
if (SYS_ACTION_QUEUE == "SYSTEM" || SYS_ACTION_QUEUE == "CLIENT") {
use = true;
}
}
else if (context == "monitoring") {
if (SYS_ACTION_QUEUE == "MONITORING") {
use = true;
}
}
var use = (internal.allowedActionContexts[context] === true)
if (use) {
try {
internal.defineAction(url, SYS_ACTION_QUEUE, callback, parameter);
internal.defineAction(url, callback, parameter);
console.debug("defining action '%s' in context '%s' using queue '%s'", url, context, SYS_ACTION_QUEUE);
}
catch (err) {

View File

@ -58,14 +58,22 @@
internal.edges = edges;
internal.ArangoCollection = ArangoCollection;
internal.ArangoEdgesCollection = ArangoEdgesCollection;
internal.allowedActionContexts = {}
if (typeof SYS_DEFINE_ACTION === "undefined") {
ModuleCache["/internal"].exports.defineAction = function() {
internal.defineAction = function() {
console.error("SYS_DEFINE_ACTION not available");
};
}
else {
ModuleCache["/internal"].exports.defineAction = SYS_DEFINE_ACTION;
var i;
console.error(SYS_ACTION_CONTEXTS + ", " + SYS_ACTION_QUEUE);
for (i = 0; i < SYS_ACTION_CONTEXTS.length; ++i) {
internal.allowedActionContexts[SYS_ACTION_CONTEXTS[i]] = true;
}
internal.defineAction = SYS_DEFINE_ACTION;
}
////////////////////////////////////////////////////////////////////////////////