From be319498f739bd60e4bf23659bfa6ed17c369519 Mon Sep 17 00:00:00 2001 From: Max Neunhoeffer Date: Wed, 12 Feb 2014 09:12:43 +0100 Subject: [PATCH 1/9] Correct documentation. --- Documentation/UserManual/Sharding.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Documentation/UserManual/Sharding.md b/Documentation/UserManual/Sharding.md index 5bcee49492..c838bea698 100644 --- a/Documentation/UserManual/Sharding.md +++ b/Documentation/UserManual/Sharding.md @@ -72,7 +72,7 @@ Start up a regular ArangoDB, either in console mode or connect to it with the Arango shell `arangosh`. Then you can ask it to plan a cluster for you: - arangodb> var Planner = require("org/arangodb/cluster/planner").Planner; + arangodb> var Planner = require("org/arangodb/cluster").Planner; arangodb> p = new Planner({numberOfDBservers:3, numberOfCoordinators:2}); [object Object] @@ -127,7 +127,7 @@ data directories and log files, so if you have previously used the same cluster plan you will lose all your data. Use the `relaunch` method described below instead in that case. - arangodb> var Kickstarter = require("org/arangodb/cluster/kickstarter").Kickstarter; + arangodb> var Kickstarter = require("org/arangodb/cluster").Kickstarter; arangodb> k = new Kickstarter(p.getPlan()); arangodb> k.launch(); @@ -201,7 +201,7 @@ running on the network addresses `tcp://192.168.173.78:8529` and instance installed and running, please make sure that both bind to all network devices, such that they can talk to each other. - arangodb> var Planner = require("org/arangodb/cluster/planner").Planner; + arangodb> var Planner = require("org/arangodb/cluster").Planner; arangodb> var p = new Planner({ dispatchers: {"me":{"endpoint":"tcp://192.168.173.78:8529"}, "theother":{"endpoint":"tcp://192.168.173.13:6789"}}, @@ -211,6 +211,8 @@ With this you create a cluster plan involving two machines. The planner will put one DBserver and one coordinator on each machine. You can now launch this cluster exactly as above: + arangodb> var Kickstarter = require("org/arangodb/cluster").Kickstarter; + arangodb> k = new Kickstarter(p.getPlan()); arangodb> k.launch(); Likewise, the methods `shutdown`, `relaunch`, `isHealthy` and `cleanup` From 733e94ad0a092c3ae078982fd0b510e266c32a79 Mon Sep 17 00:00:00 2001 From: Max Neunhoeffer Date: Wed, 12 Feb 2014 09:36:35 +0100 Subject: [PATCH 2/9] Improve error reporting in arangosh with kickstarter. --- js/client/modules/org/arangodb/cluster.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/js/client/modules/org/arangodb/cluster.js b/js/client/modules/org/arangodb/cluster.js index ba7dca8538..68a59e109e 100644 --- a/js/client/modules/org/arangodb/cluster.js +++ b/js/client/modules/org/arangodb/cluster.js @@ -68,7 +68,6 @@ Kickstarter.prototype.launch = function () { JSON.stringify({"action": "launch", "clusterPlan": this.clusterPlan, "myname": this.myname})); - arangosh.checkRequestResult(r); this.runInfo = r.runInfo; return r; }; @@ -80,7 +79,6 @@ Kickstarter.prototype.shutdown = function () { "clusterPlan": this.clusterPlan, "myname": this.myname, "runInfo": this.runInfo})); - arangosh.checkRequestResult(r); return r; }; @@ -90,7 +88,6 @@ Kickstarter.prototype.relaunch = function () { JSON.stringify({"action": "relaunch", "clusterPlan": this.clusterPlan, "myname": this.myname})); - arangosh.checkRequestResult(r); this.runInfo = r.runInfo; return r; }; @@ -101,7 +98,6 @@ Kickstarter.prototype.cleanup = function () { JSON.stringify({"action": "cleanup", "clusterPlan": this.clusterPlan, "myname": this.myname})); - arangosh.checkRequestResult(r); return r; }; @@ -112,15 +108,12 @@ Kickstarter.prototype.isHealthy = function () { "clusterPlan": this.clusterPlan, "myname": this.myname, "runInfo": this.runInfo})); - arangosh.checkRequestResult(r); return r; }; exports.Planner = Planner; exports.Kickstarter = Kickstarter; - - // ----------------------------------------------------------------------------- // --SECTION-- END-OF-FILE // ----------------------------------------------------------------------------- From d92a5d9beaebbe8a33a0daa4fceafb41b5fd982b Mon Sep 17 00:00:00 2001 From: Max Neunhoeffer Date: Wed, 12 Feb 2014 09:37:18 +0100 Subject: [PATCH 3/9] Add authentication between dispatchers. --- .../org/arangodb/cluster/kickstarter.js | 46 +++++++++++++++++-- .../modules/org/arangodb/cluster/planner.js | 7 ++- 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/js/server/modules/org/arangodb/cluster/kickstarter.js b/js/server/modules/org/arangodb/cluster/kickstarter.js index ae5850767f..ca8cc813c9 100644 --- a/js/server/modules/org/arangodb/cluster/kickstarter.js +++ b/js/server/modules/org/arangodb/cluster/kickstarter.js @@ -36,6 +36,7 @@ var download = require("internal").download; var executeExternal = require("internal").executeExternal; var killExternal = require("internal").killExternal; var statusExternal = require("internal").statusExternal; +var base64Encode = require("internal").base64Encode; var fs = require("fs"); var wait = require("internal").wait; @@ -492,7 +493,14 @@ Kickstarter.prototype.launch = function () { "commands": [cmd] }, "myname": cmd.dispatcher }); var url = "http" + ep.substr(3) + "/_admin/clusterDispatch"; - var response = download(url, body, {"method": "POST"}); + var hdrs = {}; + if (dispatchers[cmd.dispatcher].username !== undefined && + dispatchers[cmd.dispatcher].passwd !== undefined) { + hdrs.Authorization = "Basic "+ + base64Encode(dispatchers[cmd.dispatcher].username+":"+ + dispatchers[cmd.dispatcher].passwd); + } + var response = download(url, body, {"method": "POST", "headers": hdrs}); if (response.code !== 200) { error = true; results.push({"error":true, "errorMessage": "bad HTTP response code", @@ -576,7 +584,14 @@ Kickstarter.prototype.relaunch = function () { "commands": [cmd] }, "myname": cmd.dispatcher }); var url = "http" + ep.substr(3) + "/_admin/clusterDispatch"; - var response = download(url, body, {"method": "POST"}); + var hdrs = {}; + if (dispatchers[cmd.dispatcher].username !== undefined && + dispatchers[cmd.dispatcher].passwd !== undefined) { + hdrs.Authorization = "Basic "+ + base64Encode(dispatchers[cmd.dispatcher].username+":"+ + dispatchers[cmd.dispatcher].passwd); + } + var response = download(url, body, {"method": "POST", "headers": hdrs}); if (response.code !== 200) { error = true; results.push({"error":true, "errorMessage": "bad HTTP response code", @@ -645,7 +660,14 @@ Kickstarter.prototype.shutdown = function() { "runInfo": [run], "myname": cmd.dispatcher }); var url = "http" + ep.substr(3) + "/_admin/clusterDispatch"; - var response = download(url, body, {"method": "POST"}); + var hdrs = {}; + if (dispatchers[cmd.dispatcher].username !== undefined && + dispatchers[cmd.dispatcher].passwd !== undefined) { + hdrs.Authorization = "Basic "+ + base64Encode(dispatchers[cmd.dispatcher].username+":"+ + dispatchers[cmd.dispatcher].passwd); + } + var response = download(url, body, {"method": "POST", "headers": hdrs}); if (response.code !== 200) { error = true; results.push({"error":true, "errorMessage": "bad HTTP response code", @@ -713,7 +735,14 @@ Kickstarter.prototype.cleanup = function() { "commands": [cmd] }, "myname": cmd.dispatcher }); var url = "http" + ep.substr(3) + "/_admin/clusterDispatch"; - var response = download(url, body, {"method": "POST"}); + var hdrs = {}; + if (dispatchers[cmd.dispatcher].username !== undefined && + dispatchers[cmd.dispatcher].passwd !== undefined) { + hdrs.Authorization = "Basic "+ + base64Encode(dispatchers[cmd.dispatcher].username+":"+ + dispatchers[cmd.dispatcher].passwd); + } + var response = download(url, body, {"method": "POST", "headers": hdrs}); if (response.code !== 200) { error = true; results.push({"error":true, "errorMessage": "bad HTTP response code", @@ -782,7 +811,14 @@ Kickstarter.prototype.isHealthy = function() { "runInfo": [run], "myname": cmd.dispatcher }); var url = "http" + ep.substr(3) + "/_admin/clusterDispatch"; - var response = download(url, body, {"method": "POST"}); + var hdrs = {}; + if (dispatchers[cmd.dispatcher].username !== undefined && + dispatchers[cmd.dispatcher].passwd !== undefined) { + hdrs.Authorization = "Basic "+ + base64Encode(dispatchers[cmd.dispatcher].username+":"+ + dispatchers[cmd.dispatcher].passwd); + } + var response = download(url, body, {"method": "POST", "headers": hdrs}); if (response.code !== 200) { error = true; results.push({"error":true, "errorMessage": "bad HTTP response code", diff --git a/js/server/modules/org/arangodb/cluster/planner.js b/js/server/modules/org/arangodb/cluster/planner.js index 938f5b9dda..15c28ccb7d 100644 --- a/js/server/modules/org/arangodb/cluster/planner.js +++ b/js/server/modules/org/arangodb/cluster/planner.js @@ -235,9 +235,12 @@ function fillConfigWithDefaults (config, defaultConfig) { /// whether or not DBservers should be started on this dispatcher, /// the default is `true` /// - `username`, which is a string that contains the user name -/// for authentication with this dispatcher, defaults to "root" +/// for authentication with this dispatcher /// - `passwd`, which is a string that contains the password -/// for authentication with this dispatcher, defaults to empty +/// for authentication with this dispatcher, if not both +/// `username` and `passwd` are set, then no authentication +/// is used between dispatchers. Note that this will not work +/// if the dispatchers are configured with authentication. /// /// If `.dispatchers` is empty (no property), then an entry for the /// local arangod itself is automatically added. Note that if the From 5c467148a32de770cc6413a62fbfb51c0f7e4130 Mon Sep 17 00:00:00 2001 From: Max Neunhoeffer Date: Wed, 12 Feb 2014 10:47:43 +0100 Subject: [PATCH 4/9] Add HTTP REST API call for shutdown. --- Documentation/ImplementorManual/HttpMisc.md | 4 + .../ImplementorManual/HttpMiscTOC.md | 1 + arangod/RestServer/ArangoServer.cpp | 12 +- lib/Admin/RestShutdownHandler.cpp | 112 ++++++++++++++++++ lib/Admin/RestShutdownHandler.h | 112 ++++++++++++++++++ lib/Makefile.files | 1 + 6 files changed, 240 insertions(+), 2 deletions(-) create mode 100644 lib/Admin/RestShutdownHandler.cpp create mode 100644 lib/Admin/RestShutdownHandler.h diff --git a/Documentation/ImplementorManual/HttpMisc.md b/Documentation/ImplementorManual/HttpMisc.md index f27b20ae3d..910f1b5fc5 100644 --- a/Documentation/ImplementorManual/HttpMisc.md +++ b/Documentation/ImplementorManual/HttpMisc.md @@ -18,4 +18,8 @@ This is an overview of ArangoDB's HTTP interface for miscellaneous functions. @anchor HttpMiscEcho @copydetails JSF_get_admin_echo +@CLEARPAGE +@anchor HttpMiscShutdown +@copydetails triagens::admin::RestShutdownHandler::execute + @BNAVIGATE_HttpMisc diff --git a/Documentation/ImplementorManual/HttpMiscTOC.md b/Documentation/ImplementorManual/HttpMiscTOC.md index 1c1c0823b2..eed1fb301c 100644 --- a/Documentation/ImplementorManual/HttpMiscTOC.md +++ b/Documentation/ImplementorManual/HttpMiscTOC.md @@ -5,4 +5,5 @@ TOC {#HttpMiscTOC} - @ref HttpMiscVersion "GET /_admin/version" - @ref HttpMiscTime "GET /_admin/time" - @ref HttpMiscEcho "GET /_admin/echo" + - @ref HttpMiscShutdown "GET /_admin/shutdown" diff --git a/arangod/RestServer/ArangoServer.cpp b/arangod/RestServer/ArangoServer.cpp index ca08ff692e..8152bd77e7 100644 --- a/arangod/RestServer/ArangoServer.cpp +++ b/arangod/RestServer/ArangoServer.cpp @@ -43,6 +43,7 @@ #include "Actions/actions.h" #include "Admin/ApplicationAdminServer.h" #include "Admin/RestHandlerCreator.h" +#include "Admin/RestShutdownHandler.h" #include "Basics/FileUtils.h" #include "Basics/Nonce.h" #include "Basics/ProgramOptions.h" @@ -154,13 +155,20 @@ static void DefineApiHandlers (HttpHandlerFactory* factory, static void DefineAdminHandlers (HttpHandlerFactory* factory, ApplicationAdminServer* admin, ApplicationDispatcher* dispatcher, - AsyncJobManager* jobManager) { + AsyncJobManager* jobManager), + ApplicationServer* applicationServer) { // add "/version" handler admin->addBasicHandlers(factory, "/_admin", (void*) jobManager); + // add "/_admin/shutdown" handler + factory->addPrefixHandler("/_admin/shutdown", + RestHandlerCreator::createData, + static_cast(applicationServer)); + // add admin handlers admin->addHandlers(factory, "/_admin"); + } //////////////////////////////////////////////////////////////////////////////// @@ -820,7 +828,7 @@ int ArangoServer::startupServer () { HttpHandlerFactory* handlerFactory = _applicationEndpointServer->getHandlerFactory(); DefineApiHandlers(handlerFactory, _applicationAdminServer, _applicationDispatcher, _jobManager); - DefineAdminHandlers(handlerFactory, _applicationAdminServer, _applicationDispatcher, _jobManager); + DefineAdminHandlers(handlerFactory, _applicationAdminServer, _applicationDispatcher, _jobManager, _applicationServer); // add action handler handlerFactory->addPrefixHandler( diff --git a/lib/Admin/RestShutdownHandler.cpp b/lib/Admin/RestShutdownHandler.cpp new file mode 100644 index 0000000000..b868efbec8 --- /dev/null +++ b/lib/Admin/RestShutdownHandler.cpp @@ -0,0 +1,112 @@ +//////////////////////////////////////////////////////////////////////////////// +/// @brief shutdown request handler +/// +/// @file +/// +/// DISCLAIMER +/// +/// Copyright 2004-2013 triAGENS GmbH, Cologne, Germany +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// +/// Copyright holder is triAGENS GmbH, Cologne, Germany +/// +/// @author Max Neunhoeffer +/// @author Copyright 2010-2013, triAGENS GmbH, Cologne, Germany +//////////////////////////////////////////////////////////////////////////////// + +#include "RestShutdownHandler.h" + +#include "BasicsC/json.h" +#include "BasicsC/tri-strings.h" +#include "Rest/HttpRequest.h" + +using namespace std; + +namespace triagens { + namespace admin { + +//////////////////////////////////////////////////////////////////////////////// +/// @brief name of the queue +//////////////////////////////////////////////////////////////////////////////// + +const string RestShutdownHandler::QUEUE_NAME = "STANDARD"; + +// ----------------------------------------------------------------------------- +// --SECTION-- constructors and destructors +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @brief constructor +//////////////////////////////////////////////////////////////////////////////// + +RestShutdownHandler::RestShutdownHandler (triagens::rest::HttpRequest* request, + void* applicationServer) + : RestBaseHandler(request), + _applicationServer( static_cast + (applicationServer) ) { +} + +// ----------------------------------------------------------------------------- +// --SECTION-- Handler methods +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// {@inheritDoc} +//////////////////////////////////////////////////////////////////////////////// + +bool RestShutdownHandler::isDirect () { + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +/// {@inheritDoc} +//////////////////////////////////////////////////////////////////////////////// + +string const& RestShutdownHandler::queue () const { + return QUEUE_NAME; +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief initiates the shutdown sequence +/// +/// @RESTHEADER{GET /_admin/shutdown,initiates the shutdown sequence} +/// +/// @RESTDESCRIPTION +/// This call initiates a clean shutdown sequence. +/// +/// @RESTRETURNCODES +/// +/// @RESTRETURNCODE{200} +/// is returned in all cases. +//////////////////////////////////////////////////////////////////////////////// + +triagens::rest::HttpHandler::status_e RestShutdownHandler::execute () { + + _applicationServer->beginShutdown(); + + TRI_json_t result; + TRI_InitStringJson(&result, TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, "OK")); + generateResult(&result); + TRI_DestroyJson(TRI_CORE_MEM_ZONE, &result); + + return HANDLER_DONE; +} + + } // end of namespace admin +} // end of namespace triagens + +// Local Variables: +// mode: outline-minor +// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}" +// End: diff --git a/lib/Admin/RestShutdownHandler.h b/lib/Admin/RestShutdownHandler.h new file mode 100644 index 0000000000..2b9535c900 --- /dev/null +++ b/lib/Admin/RestShutdownHandler.h @@ -0,0 +1,112 @@ +//////////////////////////////////////////////////////////////////////////////// +/// @brief shutdown request handler +/// +/// @file +/// +/// DISCLAIMER +/// +/// Copyright 2004-2013 triAGENS GmbH, Cologne, Germany +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// +/// Copyright holder is triAGENS GmbH, Cologne, Germany +/// +/// @author Max Neunhoeffer +/// @author Copyright 2014, triAGENS GmbH, Cologne, Germany +//////////////////////////////////////////////////////////////////////////////// + +#ifndef TRIAGENS_ADMIN_REST_SHUTDOWN_HANDLER_H +#define TRIAGENS_ADMIN_REST_SHUTDOWN_HANDLER_H 1 + +#include "ApplicationServer/ApplicationServer.h" + +#include "Admin/RestBaseHandler.h" + +#include "Rest/HttpResponse.h" + +namespace triagens { + namespace admin { + +// ----------------------------------------------------------------------------- +// --SECTION-- class RestShutdownHandler +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @brief shutdown request handler +//////////////////////////////////////////////////////////////////////////////// + + class RestShutdownHandler : public RestBaseHandler { + +// ----------------------------------------------------------------------------- +// --SECTION-- constructors and destructors +// ----------------------------------------------------------------------------- + + public: + +//////////////////////////////////////////////////////////////////////////////// +/// @brief constructor +//////////////////////////////////////////////////////////////////////////////// + + RestShutdownHandler (rest::HttpRequest*, void* applicationServer); + +// ----------------------------------------------------------------------------- +// --SECTION-- Handler methods +// ----------------------------------------------------------------------------- + + public: + +//////////////////////////////////////////////////////////////////////////////// +/// {@inheritDoc} +//////////////////////////////////////////////////////////////////////////////// + + bool isDirect (); + +//////////////////////////////////////////////////////////////////////////////// +/// {@inheritDoc} +//////////////////////////////////////////////////////////////////////////////// + + string const& queue () const; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief initiates the shutdown process +//////////////////////////////////////////////////////////////////////////////// + + status_e execute (); + +// ----------------------------------------------------------------------------- +// --SECTION-- private variables +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @brief name of the queue +//////////////////////////////////////////////////////////////////////////////// + + private: + + static const std::string QUEUE_NAME; + triagens::rest::ApplicationServer* _applicationServer; + + }; + } +} + +//////////////////////////////////////////////////////////////////////////////// +/// @} +//////////////////////////////////////////////////////////////////////////////// + +#endif + +// Local Variables: +// mode: outline-minor +// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}" +// End: diff --git a/lib/Makefile.files b/lib/Makefile.files index de37b254a4..d146fc5cd9 100644 --- a/lib/Makefile.files +++ b/lib/Makefile.files @@ -139,6 +139,7 @@ lib_libarango_fe_a_SOURCES = \ lib/Admin/RestAdminLogHandler.cpp \ lib/Admin/RestBaseHandler.cpp \ lib/Admin/RestJobHandler.cpp \ + lib/Admin/RestShutdownHandler.cpp \ lib/Admin/RestVersionHandler.cpp \ lib/ApplicationServer/ApplicationFeature.cpp \ lib/ApplicationServer/ApplicationServer.cpp \ From 7df42c547ebc439a117cfad228fd5bede7f5d1d2 Mon Sep 17 00:00:00 2001 From: Max Neunhoeffer Date: Wed, 12 Feb 2014 10:56:03 +0100 Subject: [PATCH 5/9] Lost a ). --- arangod/RestServer/ArangoServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arangod/RestServer/ArangoServer.cpp b/arangod/RestServer/ArangoServer.cpp index 8152bd77e7..dc242aec1a 100644 --- a/arangod/RestServer/ArangoServer.cpp +++ b/arangod/RestServer/ArangoServer.cpp @@ -155,7 +155,7 @@ static void DefineApiHandlers (HttpHandlerFactory* factory, static void DefineAdminHandlers (HttpHandlerFactory* factory, ApplicationAdminServer* admin, ApplicationDispatcher* dispatcher, - AsyncJobManager* jobManager), + AsyncJobManager* jobManager, ApplicationServer* applicationServer) { // add "/version" handler From 38db0842e569fda0d40984fa3f3c89743da9b55a Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Wed, 12 Feb 2014 11:23:24 +0100 Subject: [PATCH 6/9] A bit more styling in the planTest view --- .../plannerFrontend/js/router/router.js | 9 ++--- .../plannerFrontend/js/templates/testPlan.ejs | 36 ++++++++++++++++--- .../plannerFrontend/js/views/planTestView.js | 1 - 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/js/apps/system/aardvark/plannerFrontend/js/router/router.js b/js/apps/system/aardvark/plannerFrontend/js/router/router.js index d92dc1efb5..1dafd5b133 100644 --- a/js/apps/system/aardvark/plannerFrontend/js/router/router.js +++ b/js/apps/system/aardvark/plannerFrontend/js/router/router.js @@ -10,21 +10,22 @@ }, planTest: function() { - console.log("Startup"); if (!this.planTestView) { this.planTestView = new window.PlanTestView(); } - console.log("Renderung"); this.planTestView.render(); }, initialize: function () { - console.log("initio"); /* this.footerView = new window.FooterView(); this.footerView.render(); */ - } + }, + + handleResize: function() { + // Not needed here + } }); }()); diff --git a/js/apps/system/aardvark/plannerFrontend/js/templates/testPlan.ejs b/js/apps/system/aardvark/plannerFrontend/js/templates/testPlan.ejs index e14ec714b2..56180b4738 100644 --- a/js/apps/system/aardvark/plannerFrontend/js/templates/testPlan.ejs +++ b/js/apps/system/aardvark/plannerFrontend/js/templates/testPlan.ejs @@ -1,5 +1,33 @@ -
- : - - + + + +
+
+ +
+ : +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+ +
+
diff --git a/js/apps/system/aardvark/plannerFrontend/js/views/planTestView.js b/js/apps/system/aardvark/plannerFrontend/js/views/planTestView.js index 9abb3bb6d7..99d080e1fd 100644 --- a/js/apps/system/aardvark/plannerFrontend/js/views/planTestView.js +++ b/js/apps/system/aardvark/plannerFrontend/js/views/planTestView.js @@ -9,7 +9,6 @@ template: plannerTemplateEngine.createTemplate("testPlan.ejs", "planner"), render: function() { - console.log("Rendoror"); $(this.el).html(this.template.render({})); } }); From 3d48a5294a6465ed38207cfbbc7b44d8d867b019 Mon Sep 17 00:00:00 2001 From: Max Neunhoeffer Date: Wed, 12 Feb 2014 11:52:09 +0100 Subject: [PATCH 7/9] Please clang++ by using an explicit cast to unsigned long long. --- arangod/Cluster/ClusterComm.cpp | 5 +++-- arangod/V8Server/v8-actions.cpp | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/arangod/Cluster/ClusterComm.cpp b/arangod/Cluster/ClusterComm.cpp index b92fefd0b8..ac7d114506 100644 --- a/arangod/Cluster/ClusterComm.cpp +++ b/arangod/Cluster/ClusterComm.cpp @@ -211,7 +211,8 @@ ClusterCommResult* ClusterComm::asyncRequest ( list::iterator i = toSend.end(); toSendByOpID[op->operationID] = --i; } - LOG_DEBUG("In asyncRequest, put into queue %ld", op->operationID); + LOG_DEBUG("In asyncRequest, put into queue %llu", + (unsigned long long) op->operationID); somethingToSend.signal(); return res; @@ -791,7 +792,7 @@ bool ClusterComm::moveFromSendToReceived (OperationID operationID) { IndexIterator i; ClusterCommOperation* op; - LOG_DEBUG("In moveFromSendToReceived %ld", operationID); + LOG_DEBUG("In moveFromSendToReceived %llu", (unsigned long long) operationID); basics::ConditionLocker locker(&somethingReceived); basics::ConditionLocker sendlocker(&somethingToSend); i = toSendByOpID.find(operationID); // cannot fail diff --git a/arangod/V8Server/v8-actions.cpp b/arangod/V8Server/v8-actions.cpp index 4a4fd6ae33..f497d01658 100644 --- a/arangod/V8Server/v8-actions.cpp +++ b/arangod/V8Server/v8-actions.cpp @@ -809,8 +809,8 @@ class CallbackTest : public ClusterCommCallback { CallbackTest(string msg) : _msg(msg) {} virtual ~CallbackTest() {} virtual bool operator() (ClusterCommResult* res) { - LOG_DEBUG("ClusterCommCallback called on operation %ld", - res->operationID); + LOG_DEBUG("ClusterCommCallback called on operation %llu", + (unsigned long long) res->operationID); LOG_DEBUG("Message: %s", _msg.c_str()); return false; // Keep it in the queue } From dae77412a847c71d44f0ea0d005ffa1680fd4e1f Mon Sep 17 00:00:00 2001 From: scottashton Date: Wed, 12 Feb 2014 12:00:04 +0100 Subject: [PATCH 8/9] plannerFrontend Router setup and karma tests --- .../frontend/js/arango/templateEngine.js | 2 +- js/apps/system/aardvark/manifest.json | 5 +- .../router.js => routers/plannerRouter.js} | 17 ++- .../plannerFrontend/js/routers/startApp.js | 12 ++ .../js/templates/planScenarioSelector.ejs | 49 ++++++++ .../js/views/planScenarioSelectorView.js | 46 +++++++ .../system/aardvark/test/karma/karma.conf.js | 15 ++- .../system/aardvark/test/mocks/disableEJS.js | 8 +- js/apps/system/aardvark/test/runnerAll.html | 2 +- .../system/aardvark/test/runnerJSLint.html | 2 +- .../test/specs/planner/router/routerSpec.js | 119 ++++++++++++++++++ 11 files changed, 261 insertions(+), 16 deletions(-) rename js/apps/system/aardvark/plannerFrontend/js/{router/router.js => routers/plannerRouter.js} (59%) create mode 100644 js/apps/system/aardvark/plannerFrontend/js/routers/startApp.js create mode 100644 js/apps/system/aardvark/plannerFrontend/js/templates/planScenarioSelector.ejs create mode 100644 js/apps/system/aardvark/plannerFrontend/js/views/planScenarioSelectorView.js create mode 100644 js/apps/system/aardvark/test/specs/planner/router/routerSpec.js diff --git a/js/apps/system/aardvark/frontend/js/arango/templateEngine.js b/js/apps/system/aardvark/frontend/js/arango/templateEngine.js index 855cbf4626..5267ba6e6e 100644 --- a/js/apps/system/aardvark/frontend/js/arango/templateEngine.js +++ b/js/apps/system/aardvark/frontend/js/arango/templateEngine.js @@ -14,5 +14,5 @@ return exports; }; window.templateEngine = new TemplateEngine("js/templates/"); - window.plannerTemplateEngine = new TemplateEngine("js/plannerTemplates/"); + window.plannerTemplateEngine = new TemplateEngine("js/plannerTemplates/"); }()); diff --git a/js/apps/system/aardvark/manifest.json b/js/apps/system/aardvark/manifest.json index a5c6df69fc..71f0ab4d36 100644 --- a/js/apps/system/aardvark/manifest.json +++ b/js/apps/system/aardvark/manifest.json @@ -59,7 +59,7 @@ "frontend/js/models/**", "frontend/js/collections/**", "frontend/js/views/**", - "frontend/js/routers/router.js", + "frontend/js/routers/plannerRouter.js", "frontend/js/routers/startApp.js" ] }, @@ -183,8 +183,7 @@ "plannerFrontend/js/collections/**", "frontend/js/views/footerView.js", "plannerFrontend/js/views/**", - "plannerFrontend/js/router/**", - "frontend/js/routers/startApp.js" + "plannerFrontend/js/router/**" ] } }, diff --git a/js/apps/system/aardvark/plannerFrontend/js/router/router.js b/js/apps/system/aardvark/plannerFrontend/js/routers/plannerRouter.js similarity index 59% rename from js/apps/system/aardvark/plannerFrontend/js/router/router.js rename to js/apps/system/aardvark/plannerFrontend/js/routers/plannerRouter.js index d92dc1efb5..ac05148ef9 100644 --- a/js/apps/system/aardvark/plannerFrontend/js/router/router.js +++ b/js/apps/system/aardvark/plannerFrontend/js/routers/plannerRouter.js @@ -4,22 +4,29 @@ (function() { "use strict"; - window.Router = Backbone.Router.extend({ + window.plannerRouter = Backbone.Router.extend({ routes: { - "planTest" : "planTest" + "planTest" : "planTest", + "planScenarioSelector" : "planScenarioSelector" }, planTest: function() { - console.log("Startup"); if (!this.planTestView) { this.planTestView = new window.PlanTestView(); } - console.log("Renderung"); this.planTestView.render(); }, + planScenarioSelector: function() { + if (!this.PlanScenarioSelector) { + this.PlanScenarioSelector = new window.PlanScenarioSelectorView(); + } + this.PlanScenarioSelector.render(); + }, + + + initialize: function () { - console.log("initio"); /* this.footerView = new window.FooterView(); this.footerView.render(); diff --git a/js/apps/system/aardvark/plannerFrontend/js/routers/startApp.js b/js/apps/system/aardvark/plannerFrontend/js/routers/startApp.js new file mode 100644 index 0000000000..610fb29164 --- /dev/null +++ b/js/apps/system/aardvark/plannerFrontend/js/routers/startApp.js @@ -0,0 +1,12 @@ +/*jslint indent: 2, nomen: true, maxlen: 100, white: true, */ +/*global window, $, Backbone, document */ + +(function() { + "use strict"; + $(document).ready(function() { + window.App = new window.plannerRouter(); + Backbone.history.start(); + window.App.handleResize(); + }); + +}()); diff --git a/js/apps/system/aardvark/plannerFrontend/js/templates/planScenarioSelector.ejs b/js/apps/system/aardvark/plannerFrontend/js/templates/planScenarioSelector.ejs new file mode 100644 index 0000000000..c3c0a5a526 --- /dev/null +++ b/js/apps/system/aardvark/plannerFrontend/js/templates/planScenarioSelector.ejs @@ -0,0 +1,49 @@ +
+ + +
+
+
+
+ +
+ Please select a cluster scenario: + +
+ +
+ + +
+ +
+ +
+ +
+ + +
+ +
+
+ +
+
+
+
+
+
diff --git a/js/apps/system/aardvark/plannerFrontend/js/views/planScenarioSelectorView.js b/js/apps/system/aardvark/plannerFrontend/js/views/planScenarioSelectorView.js new file mode 100644 index 0000000000..049f41d430 --- /dev/null +++ b/js/apps/system/aardvark/plannerFrontend/js/views/planScenarioSelectorView.js @@ -0,0 +1,46 @@ +/*jslint indent: 2, nomen: true, maxlen: 100, vars: true, white: true, plusplus: true*/ +/*global Backbone, $, _, window, templateEngine, GraphViewerUI */ +/*global require*/ +(function() { + + "use strict"; + + window.PlanScenarioSelectorView = Backbone.View.extend({ + el: '#content', + + template: plannerTemplateEngine.createTemplate("planScenarioSelector.ejs", "planner"), + + + events: { + /* "click input[type='radio'][name='loadtype']": "toggleLoadtypeDisplay", + "click #createViewer": "createViewer", + "click #add_label": "insertNewLabelLine", + "click #add_colour": "insertNewColourLine", + "click #add_group_by": "insertNewGroupLine", + "click input[type='radio'][name='colour']": "toggleColourDisplay", + "click .gv_internal_remove_line": "removeAttrLine", + "click #manageGraphs": "showGraphManager"*/ + }, + + showGraphManager: function() { + window.App.navigate("graphManagement", {trigger: true}); + }, + +/* + removeAttrLine: function(e) { + var g = $(e.currentTarget) + .parent() + .parent(), + set = g.parent(); + set.get(0).removeChild(g.get(0)); + }, +*/ + + + + render: function() { + $(this.el).html(this.template.render({})); + } + + }); +}()); diff --git a/js/apps/system/aardvark/test/karma/karma.conf.js b/js/apps/system/aardvark/test/karma/karma.conf.js index 97cafa0959..64423f1207 100644 --- a/js/apps/system/aardvark/test/karma/karma.conf.js +++ b/js/apps/system/aardvark/test/karma/karma.conf.js @@ -189,11 +189,18 @@ module.exports = function(karma) { 'frontend/js/views/clusterCollectionView.js', 'frontend/js/views/clusterShardsView.js', + //Views Planner + 'plannerFrontend/js/views/planScenarioSelectorView.js', + 'plannerFrontend/js/views/planTestView.js', + + // Router 'frontend/js/routers/router.js', + 'plannerFrontend/js/routers/plannerRouter.js', //Templates {pattern: 'frontend/js/templates/*.ejs', served:true, included:false, watched: true}, + {pattern: 'plannerFrontend/js/templates/*.ejs', served:true, included:false, watched: true}, // Specs // GraphViewer 'test/specs/graphViewer/specColourMapper/colourMapperSpec.js', @@ -259,7 +266,13 @@ module.exports = function(karma) { // Router 'test/specs/router/routerSpec.js', // JSLint - 'test/specJSLint/jsLintSpec.js' + 'test/specJSLint/jsLintSpec.js', + + //Planner + + //Router + 'test/specs/planner/router/routerSpec.js' + ], diff --git a/js/apps/system/aardvark/test/mocks/disableEJS.js b/js/apps/system/aardvark/test/mocks/disableEJS.js index e0a2d20faf..fb3f1a7986 100644 --- a/js/apps/system/aardvark/test/mocks/disableEJS.js +++ b/js/apps/system/aardvark/test/mocks/disableEJS.js @@ -3,9 +3,8 @@ (function() { "use strict"; - var FakeTE = function() { - var prefix = "base/frontend/js/templates/", - exports = {}; + var FakeTE = function(prefix) { + var exports = {}; exports.createTemplate = function(path) { var param = { url: prefix + path @@ -14,5 +13,6 @@ }; return exports; }; - window.templateEngine = new FakeTE(); + window.templateEngine = new FakeTE("base/frontend/js/templates/"); + window.plannerTemplateEngine = new FakeTE("base/plannerFrontend/js/templates/"); }()); diff --git a/js/apps/system/aardvark/test/runnerAll.html b/js/apps/system/aardvark/test/runnerAll.html index e4c23b6add..ce8665eb68 100644 --- a/js/apps/system/aardvark/test/runnerAll.html +++ b/js/apps/system/aardvark/test/runnerAll.html @@ -114,7 +114,7 @@ - + diff --git a/js/apps/system/aardvark/test/runnerJSLint.html b/js/apps/system/aardvark/test/runnerJSLint.html index 0bc2069ad3..0d1f727459 100644 --- a/js/apps/system/aardvark/test/runnerJSLint.html +++ b/js/apps/system/aardvark/test/runnerJSLint.html @@ -32,7 +32,7 @@ - + diff --git a/js/apps/system/aardvark/test/specs/planner/router/routerSpec.js b/js/apps/system/aardvark/test/specs/planner/router/routerSpec.js new file mode 100644 index 0000000000..7d1b57de74 --- /dev/null +++ b/js/apps/system/aardvark/test/specs/planner/router/routerSpec.js @@ -0,0 +1,119 @@ +/*jslint indent: 2, nomen: true, maxlen: 100, white: true plusplus: true, browser: true*/ +/*global describe, beforeEach, afterEach, it, spyOn, expect*/ +/*global $, jasmine, _*/ + +(function() { + "use strict"; + + describe("The router", function() { + + describe("navigation", function () { + + var r, + simpleNavigationCheck; + + beforeEach(function() { + r = new window.plannerRouter(); + simpleNavigationCheck = function(url, viewName, initObject, funcList, shouldNotRender) { + var route, + view = {}, + checkFuncExec = function() { + _.each(funcList, function(v, f) { + if (v !== undefined) { + expect(view[f]).toHaveBeenCalledWith(v); + } else { + expect(view[f]).toHaveBeenCalled(); + } + }); + }; + funcList = funcList || {}; + if (_.isObject(url)) { + route = function() { + r[r.routes[url.url]].apply(r, url.params); + }; + } else { + route = r[r.routes[url]].bind(r); + } + if (!funcList.hasOwnProperty("render") && !shouldNotRender) { + funcList.render = undefined; + } + _.each(_.keys(funcList), function(f) { + view[f] = function(){}; + spyOn(view, f); + }); + expect(route).toBeDefined(); + spyOn(window, viewName).andReturn(view); + route(); + if (initObject) { + expect(window[viewName]).toHaveBeenCalledWith(initObject); + } else { + expect(window[viewName]).toHaveBeenCalled(); + } + checkFuncExec(); + // Check if the view is loaded from cache + window[viewName].reset(); + _.each(_.keys(funcList), function(f) { + view[f].reset(); + }); + route(); + expect(window[viewName]).not.toHaveBeenCalled(); + checkFuncExec(); + }; + }); + + it("should offer all necessary routes", function() { + var available = _.keys(r.routes), + expected = [ + "planTest", + "planScenarioSelector" + ], + diff = _.difference(available, expected); + this.addMatchers({ + toDefineTheRoutes: function(exp) { + var avail = this.actual, + leftDiff = _.difference(avail, exp), + rightDiff = _.difference(exp, avail); + this.message = function() { + var msg = ""; + if (rightDiff.length) { + msg += "Expect routes: " + + rightDiff.join(' & ') + + " to be available.\n"; + } + if (leftDiff.length) { + msg += "Did not expect routes: " + + leftDiff.join(" & ") + + " to be available."; + } + return msg; + }; + return true; + /* Not all routes are covered by tests yet + * real execution would fail + return leftDiff.length === 0 + && rightDiff.length === 0; + */ + } + }); + expect(available).toDefineTheRoutes(expected); + }); + + it("should route to planTest", function() { + simpleNavigationCheck( + { + url: "planTest" + }, + "PlanTestView" + ); + }); + it("should route to planScenarioSelector", function() { + simpleNavigationCheck( + { + url: "planScenarioSelector" + }, + "PlanScenarioSelectorView" + ); + }); + }); + }); +}()); From 2f1b0fe0615b827d2fd6b343bb1992f295c01016 Mon Sep 17 00:00:00 2001 From: Max Neunhoeffer Date: Wed, 12 Feb 2014 12:17:52 +0100 Subject: [PATCH 9/9] Use API to shut down servers. --- js/server/modules/org/arangodb/cluster/kickstarter.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/js/server/modules/org/arangodb/cluster/kickstarter.js b/js/server/modules/org/arangodb/cluster/kickstarter.js index ca8cc813c9..95853818d6 100644 --- a/js/server/modules/org/arangodb/cluster/kickstarter.js +++ b/js/server/modules/org/arangodb/cluster/kickstarter.js @@ -325,8 +325,16 @@ shutdownActions.sendConfiguration = function (dispatchers, cmd, run) { shutdownActions.startServers = function (dispatchers, cmd, run) { var i; + var url; + for (i = 0;i < run.endpoints.length;i++) { + console.info("Using API to shutdown %s", run.pids[i].toString()); + url = "http://"+run.endpoints[i].substr(6)+"/_admin/shutdown"; + download(url); + } + console.info("Waiting 10 seconds for servers to shutdown gracefully..."); + wait(10); for (i = 0;i < run.pids.length;i++) { - console.info("Shutting down %s", run.pids[i].toString()); + console.info("Shutting down %s the hard way...", run.pids[i].toString()); killExternal(run.pids[i]); } return {"error": false, "isStartServers": true};