Skip to content

Instantly share code, notes, and snippets.

@mcvella
Last active December 16, 2015 02:50
Show Gist options
  • Select an option

  • Save mcvella/5365877 to your computer and use it in GitHub Desktop.

Select an option

Save mcvella/5365877 to your computer and use it in GitHub Desktop.
Here is a test where a replica set is brought up with auth, a collection is queried, the primary is brought down, then back up, and the primary is queried again. After the primary is brought back up, the query fails due to non-authentication. NOTE: I actually could not replicate this without performing two queries on either side, I am not sure i…
/*
Note that you will need to do the following prior to running this script:
- Create an auth user in the admin database and update the username and password variables in the script.
- Instantiate replica set:
rs.initiate( { _id: "test", members: [ { _id: 0, host : "localhost:27017", priority : 10 }, { _id: 1, host : "localhost:27027", priority : 5 }, { _id : 2, host : "localhost:27037", priority : 2 } ] } );
- Bring mongo down.
- Create directories /data/test-0,data/test-1,data/test-2
- Create ~/keyFile for replica set auth
- Bring mongo back up on the correct ports for each member of the replica set.
*/
/* DEPS */
var MongoClient = require('mongodb').MongoClient;
var async = require('async');
var exec = require('child_process').exec;
// GLOBALS FOR TESTING
var servers = ["127.0.0.1:27017","127.0.0.1:27027","127.0.0.1:27037"];
var username = 'user';
var password = 'password';
var replset = 'test';
var database = 'test';
var collection = 'test';
/*
*
* SETUP
*
*/
bringUpReplMember(27017, '/data/test-0');
bringUpReplMember(27027, '/data/test-1');
bringUpReplMember(27037, '/data/test-2');
// wait 20 secs for repl set to be up and running
setTimeout( function(){ main() }, 20000 );
function main()
{
var authString = username + ':' + password + '@';
var rtServerString = new Array();
for ( i = 0; i < servers.length; i++ )
{
rtServerString[i] = servers[i] ;
}
rtServerString = authString + rtServerString.join();
var connectStringPre = "mongodb://" + rtServerString + "/";
var connectStringEnd = "?w=0&readPreference=nearest&authSource=admin&maxPoolSize=1&replicaSet=" + replset;
console.log( "Will connect to: " + connectStringPre + database + connectStringEnd );
MongoClient.connect( connectStringPre + database + connectStringEnd, function(err, db)
{
if ( err )
{
console.log( "Error connecting to db", err );
}
else
{
var testCollection = db.collection( collection );
async.series([
function( callback )
{
doFind( testCollection, callback );
},
function( callback )
{
doFind( testCollection, callback );
},
function( callback )
{
console.log("Bringing down primary");
killReplMember( 27017 );
setTimeout( function() { return callback() }, 10000 );
},
function( callback )
{
console.log("Bringing primary back up");
bringUpReplMember(27017, '/data/test-0');
setTimeout( function() { return callback() }, 10000 );
},
function( callback )
{
doFind( testCollection, callback );
},
function( callback )
{
doFind( testCollection, callback );
}
],
function( err, results ) {});
}
} );
}
function bringUpReplMember( port, path )
{
var command = 'mongod --replSet ' + replset + ' --keyFile ~/keyFile --port ' + port + ' --dbpath ' + path;
exec(command);
}
function killReplMember( port )
{
var member_kill = "ps ax|grep mongod|grep " + port + " |awk '{print $1}'| xargs kill";
exec(member_kill);
}
function doFind( collection, callback )
{
collection.findOne({},
function(err, item) {
if ( err )
{
console.log( "Error getting data from mongodb: ", err );
}
else
{
console.log( "Successful findOne()" );
}
return callback();
});
}
@christkv
Copy link

the whole ha is refactored and merged into 1.3-dev so you can test it. I'm still not done merging other stuff but it passes all the tests now. One thing to make sure is that you use the same name in the replicaset config file as the ones you use in your connection string. you can't mix 127.0.0.1 and localhost or there is no way to match and check if a server is down or not. I'm considering maybe implementing reverse dns support but not yet as it would bring a lot of complications.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment