mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'sharding' of https://github.com/triAGENS/ArangoDB into sharding
This commit is contained in:
commit
f11577d952
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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`
|
||||
|
|
|
@ -211,7 +211,8 @@ ClusterCommResult* ClusterComm::asyncRequest (
|
|||
list<ClusterCommOperation*>::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
|
||||
|
|
|
@ -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<RestShutdownHandler>::createData<void*>,
|
||||
static_cast<void*>(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(
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -14,5 +14,5 @@
|
|||
return exports;
|
||||
};
|
||||
window.templateEngine = new TemplateEngine("js/templates/");
|
||||
window.plannerTemplateEngine = new TemplateEngine("js/plannerTemplates/");
|
||||
window.plannerTemplateEngine = new TemplateEngine("js/plannerTemplates/");
|
||||
}());
|
||||
|
|
|
@ -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/**"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
|
|
@ -4,27 +4,38 @@
|
|||
(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();
|
||||
*/
|
||||
}
|
||||
},
|
||||
|
||||
handleResize: function() {
|
||||
// Not needed here
|
||||
}
|
||||
});
|
||||
|
||||
}());
|
|
@ -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();
|
||||
});
|
||||
|
||||
}());
|
|
@ -0,0 +1,49 @@
|
|||
<div id="background">
|
||||
<ul class="thumbnails2">
|
||||
<div class="headerBar">
|
||||
<a class="arangoHeader">Cluster Management</a>
|
||||
</div>
|
||||
</ul>
|
||||
|
||||
<div class="content">
|
||||
<form action="javascript:void(0);" autocomplete="on" class="form-horizontal" id="planSelectionDialog">
|
||||
<fieldset>
|
||||
<div class="control-group">
|
||||
|
||||
<fieldset id="scenario">
|
||||
<legend class="gv_inner">Please select a cluster scenario:</legend>
|
||||
|
||||
<div class="controls">
|
||||
<label class="radio">
|
||||
<input type="radio" name="scenario" id="singleServer" checked>
|
||||
Lorem Ipsum
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="controls">
|
||||
<label class="radio">
|
||||
<input type="radio" name="scenario" id="multiServerAsymmetrical">
|
||||
Lorem Ipsum
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="controls">
|
||||
<label class="radio">
|
||||
<input type="radio" name="scenario" id="multiServerSymmetrical">
|
||||
Lorem Ipsum
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
||||
</fieldset>
|
||||
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<button type="submit" class="btn btn-primary" id="createViewer" >Start</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
|
@ -1,5 +1,33 @@
|
|||
<form>
|
||||
<label>Server:</label><input type="text" id="host" placeholder="Server" class="serverInput" ></input>:<input type="text" class="portInput" id="port" placeholder="port"></input>
|
||||
<label>Coordinators:</label><input type="text" id="coordintors" placeholder="1"></input>
|
||||
<label>DBServers:</label><input type="text" id="dbs"placeholder="1"></input>
|
||||
<ul class="thumbnails2">
|
||||
<div class="headerBar">
|
||||
<a class="arangoHeader">Plan a single server test configuration</a>
|
||||
</div>
|
||||
</ul>
|
||||
|
||||
<form action="javascript:void(0);" autocomplete="on" class="form-horizontal">
|
||||
<fieldset>
|
||||
<div class="control-group">
|
||||
<label for="host" class="control-label">Server:</label>
|
||||
<div class="controls">
|
||||
<input type="text" id="host" placeholder="Server" class="input-xlarge"></input>:<input type="text" maxlength="5" class="input-small" id="port" placeholder="port"></input>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label for="coordinators" class="control-label">Coordinators:</label>
|
||||
<div class="controls">
|
||||
<input type="text" id="coordinators" placeholder="1" class="input-xlarge"></input>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label for="coordinators" class="control-label">DB Servers:</label>
|
||||
<div class="controls">
|
||||
<input type="text" id="dbs" placeholder="1" class="input-xlarge"></input>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<button class="btn btn-success" id="startPlan">Create Cluster</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -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({}));
|
||||
}
|
||||
|
||||
});
|
||||
}());
|
|
@ -9,7 +9,6 @@
|
|||
template: plannerTemplateEngine.createTemplate("testPlan.ejs", "planner"),
|
||||
|
||||
render: function() {
|
||||
console.log("Rendoror");
|
||||
$(this.el).html(this.template.render({}));
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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'
|
||||
|
||||
],
|
||||
|
||||
|
||||
|
|
|
@ -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/");
|
||||
}());
|
||||
|
|
|
@ -114,7 +114,7 @@
|
|||
<script src="../js/views/graphView.js"></script>
|
||||
|
||||
<!-- router -->
|
||||
<!-- <script src="../js/routers/router.js"></script> --!>
|
||||
<!-- <script src="../js/routers/plannerRouter.js"></script> --!>
|
||||
|
||||
<!-- specs helper --!>
|
||||
<script type="text/javascript" src="specs/arango/arangoSpec.js"></script>
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
<!-- helper: checked @ 31.05.2013 --!>
|
||||
<!--<script type="text/javascript" src="../js/arango/arango.js"></script> --!>
|
||||
<!-- routers --!>
|
||||
<script type="text/javascript" src="../js/routers/router.js"></script>
|
||||
<script type="text/javascript" src="../js/routers/plannerRouter.js"></script>
|
||||
<!-- models --!>
|
||||
<script type="text/javascript" src="../js/models/arangoCollection.js"></script>
|
||||
<script type="text/javascript" src="../js/models/arangoDocument.js"></script>
|
||||
|
|
|
@ -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"
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
}());
|
|
@ -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
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -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;
|
||||
|
@ -324,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};
|
||||
|
@ -492,7 +501,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 +592,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 +668,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 +743,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 +819,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",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<triagens::rest::ApplicationServer*>
|
||||
(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:
|
|
@ -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:
|
|
@ -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 \
|
||||
|
|
Loading…
Reference in New Issue