Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Composer #561

Merged
merged 3 commits into from
Feb 20, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions bin/hapi
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/env node

var Optimist = require('optimist');
var Hapi = require('../');

var argv = Optimist.usage('Usage: $0 -c config.json')
.demand(['c'])
.argv;

var options = null;
try {
options = require(process.cwd() + '/' + argv.c);
}
catch (err) {
console.log('Failed loading configuration file: ' + argv.c + ' (' + err.message + ')');
process.exit(1);
}

var composer = new Hapi.Composer(options);
composer.compose(function (err) {

Hapi.utils.assert(!err, 'Failed loading plugins: ' + (err && err.message));
composer.start(function (err) {

Hapi.utils.assert(!err, 'Failed starting server: ' + (err && err.message));
});
});




27 changes: 27 additions & 0 deletions examples/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"servers": {
"ren": {
"host": "localhost",
"port": 8001,
"labels": ["api", "nasty"],
"config": {
"monitor": {
"subscribers": {
"console": ["ops", "request", "log"]
}
},
"cache": "redis"
}
},
"stimpy": {
"port": 8002,
"labels": ["api", "nice"]
}
},
"plugins": {
"furball": {
"version": false,
"plugins": "/"
}
}
}
118 changes: 118 additions & 0 deletions lib/composer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
// Load modules

var Async = require('async');
var Server = require('./server');
var Pack = require('./pack');
var Utils = require('./utils');


// Declare internals

var internals = {};

/*
var options = [{
servers: {
ren: {
port: 8001,
labels: ['api', 'nasty'],
config: {
monitor: {
subscribers: {
console: ['ops', 'request', 'log']
}
},
cache: 'redis'
}
},
stimpy: {
host: 'localhost',
port: 8002,
labels: ['api', 'nice']
}
},
plugins: {
furball: {
version: false,
plugins: '/'
}
},
permissions: {
ext: true
}
}];
*/

exports = module.exports = internals.Composer = function (options) {

this.settings = Utils.clone(options);
if (this.settings instanceof Array === false) {
this.settings = [this.settings];
}

this.packs = [];

return this;
};


internals.Composer.prototype.compose = function (callback) {

var self = this;

// Create packs

var sets = [];
this.settings.forEach(function (set) {

Utils.assert(set.servers && Object.keys(set.servers).length, 'Pack missing servers definition');

var pack = new Pack();
Object.keys(set.servers).forEach(function (serverName) {

// Load servers

var serverOptions = set.servers[serverName];
pack.server(serverName, new Server(serverOptions.host, serverOptions.port, serverOptions.config), { labels: serverOptions.labels });
});

sets.push({ pack: pack, plugins: set.plugins });
self.packs.push(pack);
});

// Register plugins

Async.forEachSeries(sets, function (set, next) {

set.pack.allow(set.permissions || {}).require(set.plugins, next);
},
function (err) {

return callback(err);
});
};


internals.Composer.prototype.start = function (callback) {

Async.forEachSeries(this.packs, function (pack, next) {

pack.start(next);
},
function (err) {

Utils.assert(!err, 'Failed starting plugins: ' + (err && err.message));
return callback();
});
};


internals.Composer.prototype.stop = function () {

this.packs.forEach(function (pack) {

pack.stop();
});
};


3 changes: 2 additions & 1 deletion lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ var internals = {
response: require('./response'),
utils: require('./utils'),
types: require('joi').Types,
pack: require('./pack')
pack: require('./pack'),
composer: require('./composer')
}
};

Expand Down
2 changes: 1 addition & 1 deletion lib/pack.js
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ internals.Pack.prototype._require = function (name, permissions, options, callba
itemName = callerPath + '/' + itemName;
}
else if (itemName[0] !== '/') {
itemName = require.main.paths[0] + '/' + itemName;
itemName = process.cwd() + '/node_modules/' + itemName;
}

var plugin = null;
Expand Down
3 changes: 3 additions & 0 deletions lib/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ module.exports = internals.Server = function (/* host, port, options */) {
var args = {};

for (var a = 0, al = arguments.length; a < al; ++a) {
if (arguments[a] === undefined) {
continue;
}
var type = typeof arguments[a];
var key = argMap[type];
Utils.assert(key, 'Bad server constructor arguments: no match for arg type ' + type);
Expand Down
9 changes: 7 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
"catbox": "0.1.x",
"cryptiles": "0.1.x",
"iron": "0.2.x",
"lru-cache": "2.2.x"
"lru-cache": "2.2.x",
"optimist": "0.3.x"
},
"devDependencies": {
"mocha": "1.x.x",
Expand All @@ -44,7 +45,11 @@
"jade": "0.28.x",
"blanket": "1.0.x",
"travis-cov": "0.2.x",
"complexity-report": "0.x.x"
"complexity-report": "0.x.x",
"furball": "0.0.x"
},
"bin": {
"hapi": "./bin/hapi"
},
"scripts": {
"test": "make test && make test-cov",
Expand Down
69 changes: 69 additions & 0 deletions test/integration/composer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Load modules

var Chai = require('chai');
var Hapi = require('../helpers');


// Declare internals

var internals = {};


// Test shortcuts

var expect = Chai.expect;


describe('Composer', function () {

it('composes pack', function (done) {

var options = {
servers: {
ren: {
port: 0,
labels: ['api', 'nasty'],
config: {
monitor: {
subscribers: {
console: ['ops', 'request', 'log']
}
},
cache: 'redis'
}
},
stimpy: {
host: 'localhost',
port: 0,
labels: ['api', 'nice']
}
},
plugins: {
furball: {
version: false,
plugins: '/'
}
},
permissions: {
ext: true
}
};

var composer = new Hapi.Composer(options);
composer.compose(function (err) {

expect(err).to.not.exist;
composer.start(function (err) {

expect(err).to.not.exist;
composer.stop();

composer.packs[0].servers[0].inject({ method: 'GET', url: '/' }, function (res) {

expect(res.result).to.deep.equal([{ "name": "furball", "version": "0.0.7" }]);
done();
});
});
});
});
});