1
0
Fork 0

Merge branch 'devel' of https://github.com/arangodb/arangodb into devel

This commit is contained in:
jsteemann 2017-01-16 14:48:18 +01:00
commit 5566e6bb8f
10 changed files with 180 additions and 158 deletions

View File

@ -56,6 +56,8 @@ edge attribute `label`.
v3.1.9 (XXXX-XX-XX) v3.1.9 (XXXX-XX-XX)
------------------- -------------------
* ui: fixed re-login issue within a non system db, when tab was closed
* fixed a race in the VelocyStream Commtask implementation * fixed a race in the VelocyStream Commtask implementation
* fixed issue #2256 * fixed issue #2256

View File

@ -650,6 +650,8 @@ trans_ret_t Agent::transact(query_t const& queries) {
// Non-persistent write to non-persisted key-value store // Non-persistent write to non-persisted key-value store
write_ret_t Agent::vacillant(query_t const& query) { write_ret_t Agent::vacillant(query_t const& query) {
write_ret_t ret;
return ret;
} }

View File

@ -304,7 +304,7 @@ bool CleanOutServer::scheduleMoveShards() {
// Among those a random destination // Among those a random destination
std::string toServer; std::string toServer;
if (servers.empty()) { if (servers.empty()) {
LOG_TOPIC(ERR, Logger::AGENCY) LOG_TOPIC(DEBUG, Logger::AGENCY)
<< "No servers remain as target for MoveShard"; << "No servers remain as target for MoveShard";
return false; return false;
} }

View File

@ -692,12 +692,16 @@ void Supervision::enforceReplication() {
// Shrink cluster if applicable, guarded by caller // Shrink cluster if applicable, guarded by caller
void Supervision::shrinkCluster() { void Supervision::shrinkCluster() {
// Get servers from plan
std::vector<std::string> availServers; auto const& todo = _snapshot(toDoPrefix).children();
Node::Children const& dbservers = _snapshot("/Plan/DBServers").children(); auto const& pending = _snapshot(pendingPrefix).children();
for (auto const& srv : dbservers) {
availServers.push_back(srv.first); if (!todo.empty() || !pending.empty()) { // This is low priority
return;
} }
// Get servers from plan
std::vector<std::string> availServers = Job::availableServers(_snapshot);
size_t targetNumDBServers; size_t targetNumDBServers;
try { try {
@ -708,50 +712,6 @@ void Supervision::shrinkCluster() {
return; return;
} }
// If there are any cleanOutServer jobs todo or pending do nothing
Node::Children const& todos = _snapshot(toDoPrefix).children();
Node::Children const& pends = _snapshot(pendingPrefix).children();
for (auto const& job : todos) {
try {
if ((*job.second)("type").getString() == "cleanOutServer") {
return;
}
if ((*job.second)("type").getString() == "removeServer") {
return;
}
} catch (std::exception const& e) {
LOG_TOPIC(WARN, Logger::AGENCY) << "Failed to get job type of job "
<< job.first << ": " << e.what();
return;
}
}
for (auto const& job : pends) {
try {
if ((*job.second)("type").getString() == "cleanOutServer") {
return;
}
if ((*job.second)("type").getString() == "removeServer") {
return;
}
} catch (std::exception const& e) {
LOG_TOPIC(WARN, Logger::AGENCY) << "Failed to get job type of job "
<< job.first << ": " << e.what();
return;
}
}
// Remove cleaned from ist
if (_snapshot.exists("/Target/CleanedServers").size() == 2) {
for (auto const& srv :
VPackArrayIterator(_snapshot("/Target/CleanedServers").slice())) {
availServers.erase(std::remove(availServers.begin(), availServers.end(),
srv.copyString()),
availServers.end());
}
}
// Only if number of servers in target is smaller than the available // Only if number of servers in target is smaller than the available
if (targetNumDBServers < availServers.size()) { if (targetNumDBServers < availServers.size()) {
// Minimum 1 DB server must remain // Minimum 1 DB server must remain

View File

@ -48,8 +48,13 @@
return localStorage.getItem('jwt'); return localStorage.getItem('jwt');
}, },
setCurrentJwt: function (jwt) { getCurrentJwtUsername: function () {
return localStorage.getItem('jwtUser');
},
setCurrentJwt: function (jwt, username) {
localStorage.setItem('jwt', jwt); localStorage.setItem('jwt', jwt);
localStorage.setItem('jwtUser', username);
}, },
lastNotificationMessage: null, lastNotificationMessage: null,

View File

@ -51,9 +51,8 @@ window.ArangoUsers = Backbone.Collection.extend({
dataType: 'json' dataType: 'json'
}).success( }).success(
function (data) { function (data) {
arangoHelper.setCurrentJwt(data.jwt);
var jwtParts = data.jwt.split('.'); var jwtParts = data.jwt.split('.');
if (!jwtParts[1]) { if (!jwtParts[1]) {
throw new Error('Invalid JWT'); throw new Error('Invalid JWT');
} }
@ -61,14 +60,21 @@ window.ArangoUsers = Backbone.Collection.extend({
if (!window.atob) { if (!window.atob) {
throw new Error('base64 support missing in browser'); throw new Error('base64 support missing in browser');
} }
var payload = JSON.parse(atob(jwtParts[1]));
var payload = JSON.parse(atob(jwtParts[1]));
self.activeUser = payload.preferred_username; self.activeUser = payload.preferred_username;
if (self.activeUser === undefined) {
arangoHelper.setCurrentJwt(data.jwt, null);
} else {
arangoHelper.setCurrentJwt(data.jwt, self.activeUser);
}
callback(false, self.activeUser); callback(false, self.activeUser);
} }
).error( ).error(
function () { function () {
arangoHelper.setCurrentJwt(null); arangoHelper.setCurrentJwt(null, null);
self.activeUser = null; self.activeUser = null;
callback(true, null); callback(true, null);
} }

View File

@ -23,17 +23,17 @@
render: function (loggedIn) { render: function (loggedIn) {
var self = this; var self = this;
$(this.el).html(this.template.render({})); $(this.el).html(this.template.render({}));
$(this.el2).hide(); $(this.el2).hide();
$(this.el3).hide(); $(this.el3).hide();
if (frontendConfig.authenticationEnabled && loggedIn !== true) { var continueRender = function (user, errCallback) {
window.setTimeout(function () { var url;
$('#loginUsername').focus(); if (!user) {
}, 300); url = arangoHelper.databaseUrl('/_api/database/user');
} else { } else {
var url = arangoHelper.databaseUrl('/_api/database/user'); url = arangoHelper.databaseUrl('/_api/user/' + encodeURIComponent(user) + '/database', '_system');
}
if (frontendConfig.authenticationEnabled === false) { if (frontendConfig.authenticationEnabled === false) {
$('#logout').hide(); $('#logout').hide();
@ -47,17 +47,45 @@
// enable db select and login button // enable db select and login button
$('#loginDatabase').html(''); $('#loginDatabase').html('');
// fill select with allowed dbs // fill select with allowed dbs
_.each(permissions.result, function (rule, db) {
_.each(permissions.result, function (db) { if (errCallback) {
$('#loginDatabase').append( $('#loginDatabase').append(
'<option>' + db + '</option>' '<option>' + db + '</option>'
); );
} else {
$('#loginDatabase').append(
'<option>' + rule + '</option>'
);
}
}); });
self.renderDBS(); self.renderDBS();
}).error(function () { }).error(function () {
console.log('could not fetch user db data'); if (errCallback) {
errCallback();
} else {
console.log('could not fetch user db data');
}
}); });
};
if (frontendConfig.authenticationEnabled && loggedIn !== true) {
var usr = arangoHelper.getCurrentJwtUsername();
if (usr !== null && usr !== 'undefined' && usr !== undefined) {
// try if existent jwt is valid
var errCallback = function () {
window.setTimeout(function () {
$('#loginUsername').focus();
}, 300);
};
continueRender(arangoHelper.getCurrentJwtUsername(), errCallback);
} else {
window.setTimeout(function () {
$('#loginUsername').focus();
}, 300);
}
} else {
continueRender();
} }
$('.bodyWrapper').show(); $('.bodyWrapper').show();
@ -132,44 +160,49 @@
'<option>_system</option>' '<option>_system</option>'
); );
} else { } else {
var url = arangoHelper.databaseUrl('/_api/user/' + encodeURIComponent(username) + '/database', '_system'); self.renderDBSelection(username);
if (frontendConfig.authenticationEnabled === false) {
url = arangoHelper.databaseUrl('/_api/database/user');
}
$('.wrong-credentials').hide();
self.loggedIn = true;
// get list of allowed dbs
$.ajax(url).success(function (permissions) {
// HANDLE PERMISSIONS
_.each(permissions.result, function (value, key) {
if (value !== 'rw') {
delete permissions.result[key];
}
});
$('#loginForm').hide();
$('.login-window #databases').show();
// enable db select and login button
$('#loginDatabase').html('');
// fill select with allowed dbs
_.each(permissions.result, function (db, key) {
$('#loginDatabase').append(
'<option>' + key + '</option>'
);
});
self.renderDBS();
}).error(function () {
$('.wrong-credentials').show();
});
} }
}, },
renderDBSelection: function (username) {
var self = this;
var url = arangoHelper.databaseUrl('/_api/user/' + encodeURIComponent(username) + '/database', '_system');
if (frontendConfig.authenticationEnabled === false) {
url = arangoHelper.databaseUrl('/_api/database/user');
}
$('.wrong-credentials').hide();
self.loggedIn = true;
// get list of allowed dbs
$.ajax(url).success(function (permissions) {
// HANDLE PERMISSIONS
_.each(permissions.result, function (value, key) {
if (value !== 'rw') {
delete permissions.result[key];
}
});
$('#loginForm').hide();
$('.login-window #databases').show();
// enable db select and login button
$('#loginDatabase').html('');
// fill select with allowed dbs
_.each(permissions.result, function (db, key) {
$('#loginDatabase').append(
'<option>' + key + '</option>'
);
});
self.renderDBS();
}).error(function () {
$('.wrong-credentials').show();
});
},
renderDBS: function () { renderDBS: function () {
if ($('#loginDatabase').children().length === 0) { if ($('#loginDatabase').children().length === 0) {
$('#dbForm').remove(); $('#dbForm').remove();

View File

@ -46,15 +46,32 @@ function agencyTestSuite () {
var agencyServers = instanceInfo.arangods.map(arangod => { var agencyServers = instanceInfo.arangods.map(arangod => {
return arangod.url; return arangod.url;
}); });
var whoseTurn = 0; var agencyLeader = agencyServers[0];
var request = require("@arangodb/request"); var request = require("@arangodb/request");
function accessAgency(api, list) { function accessAgency(api, list) {
// We simply try all agency servers in turn until one gives us an HTTP // We simply try all agency servers in turn until one gives us an HTTP
// response: // response:
var res = request({url: agencyServers[whoseTurn] + "/_api/agency/" + api, method: "POST", var res;
followRedirects: true, body: JSON.stringify(list), while (true) {
headers: {"Content-Type": "application/json"}}); res = request({url: agencyLeader + "/_api/agency/" + api,
method: "POST", followRedirect: false,
body: JSON.stringify(list),
headers: {"Content-Type": "application/json"}});
if(res.statusCode === 307) {
agencyLeader = res.headers.location;
var l = 0;
for (var i = 0; i < 3; ++i) {
l = agencyLeader.indexOf('/', l+1);
}
agencyLeader = agencyLeader.substring(0,l);
require('internal').print('Redirected to ' + agencyLeader);
} else if (res.statusCode !== 503) {
break;
} else {
require('internal').print('Waiting for leader ... ');
}
}
res.bodyParsed = JSON.parse(res.body); res.bodyParsed = JSON.parse(res.body);
return res; return res;
} }
@ -98,17 +115,7 @@ function agencyTestSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testStartup : function () { testStartup : function () {
while (true) { assertEqual(readAndCheck([["/"]]), [{}]);
var res = request({
url: agencyServers[whoseTurn] + "/_api/agency/config",
method: "GET"
});
res.bodyParsed = JSON.parse(res.body);
if (res.bodyParsed.leaderId !== "") {
break;
}
wait(0.1);
}
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -78,7 +78,8 @@ function clusterRequest(req) {
}, req); }, req);
delete pathObj.auth; delete pathObj.auth;
} }
let query = typeof req.qs === 'string' ? req.qs : querystringify(req.qs, req.useQuerystring); let query = typeof req.qs === 'string' ?
req.qs : querystringify(req.qs, req.useQuerystring);
if (query) { if (query) {
pathObj.search = query; pathObj.search = query;
} }

View File

@ -116,6 +116,8 @@ function MovingShardsSuite () {
return body; return body;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief test whether or not a server is clean /// @brief test whether or not a server is clean
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -127,56 +129,60 @@ function MovingShardsSuite () {
if (toCollNr === undefined) { if (toCollNr === undefined) {
toCollNr = c.length - 1; toCollNr = c.length - 1;
} }
var count; var count = 100;
var ok; var ok = false;
for (var i = fromCollNr; i <= toCollNr; ++i) {
count = 100;
ok = false;
while (--count > 0) {
wait(1.0);
global.ArangoClusterInfo.flush();
var servers = findCollectionServers("_system", c[i].name());
console.info("Seeing servers:", i, c[i].name(), servers);
if (servers.indexOf(id) === -1) {
// Now check current as well:
var collInfo = global.ArangoClusterInfo.getCollectionInfo(
"_system", c[i].name());
var shards = collInfo.shards;
var collInfoCurr = Object.keys(shards).map(s =>
global.ArangoClusterInfo.getCollectionInfoCurrent(
"_system", c[i].name(), s).servers);
var idxs = collInfoCurr.map(l => l.indexOf(id));
ok = true;
for (var j = 0; j < idxs.length; j++) {
if (idxs[j] !== -1) {
ok = false;
}
}
if (ok) {
break;
}
}
}
if (!ok) {
return false;
}
}
if (checkList) { if (checkList) {
// Wait until the server appears in the list of cleanedOutServers: // Wait until the server appears in the list of cleanedOutServers:
count = 100; count = 100;
while (--count > 0) { while (--count > 0) {
var obj = getCleanedOutServers(); var obj = getCleanedOutServers();
if (obj.cleanedServers.indexOf(id) >= 0) { if (obj.cleanedServers.indexOf(id) >= 0) {
ok = true;
break; break;
} }
wait(1.0); wait(1.0);
} }
if (count <= 0) {
ok = false;
}
}
} else {
for (var i = fromCollNr; i <= toCollNr; ++i) {
while (--count > 0) {
wait(1.0);
global.ArangoClusterInfo.flush();
var servers = findCollectionServers("_system", c[i].name());
console.info("Seeing servers:", i, c[i].name(), servers);
if (servers.indexOf(id) === -1) {
// Now check current as well:
var collInfo =
global.ArangoClusterInfo.getCollectionInfo("_system", c[i].name());
var shards = collInfo.shards;
var collInfoCurr =
Object.keys(shards).map(
s => global.ArangoClusterInfo.getCollectionInfoCurrent(
"_system", c[i].name(), s).servers);
var idxs = collInfoCurr.map(l => l.indexOf(id));
ok = true;
for (var j = 0; j < idxs.length; j++) {
if (idxs[j] !== -1) {
ok = false;
}
}
if (ok) {
break;
}
}
}
if (!ok) {
return false;
}
}
}
return ok; return ok;
} }
@ -379,7 +385,7 @@ function MovingShardsSuite () {
testShrinkNoReplication : function() { testShrinkNoReplication : function() {
assertTrue(waitForSynchronousReplication("_system")); assertTrue(waitForSynchronousReplication("_system"));
var _dbservers = dbservers; var _dbservers = global.ArangoClusterInfo.getDBServers();
_dbservers.sort(); _dbservers.sort();
assertTrue(shrinkCluster(4)); assertTrue(shrinkCluster(4));
assertTrue(testServerEmpty(_dbservers[4], true)); assertTrue(testServerEmpty(_dbservers[4], true));