Skip to content

Commit

Permalink
refactor: unravel hapi server configuration
Browse files Browse the repository at this point in the history
This touches and changes a lot of things, so that the hapi server creation is now at the heart and center of this module (where it belongs).
Because the tests aren't really tests – they just check if certain internal functions exist – this has to touch and delete tests as well.
While that totally looks like it's breaking everything the surfacing API remains exactly the same.

The function signature of `require('hoodie-server')` changed, so that it doesn't auto start the hoodie-server, but it just passes it to the callback.
This way the CLI actually takes care of starting it, and some logging could already be separated out of the logic.
This will eventually make testing easier.

This is an API that was never documented or public and therefor this is not a breaking change.

* * *

This commit was sponsored by The Hoodie Firm.
You can hire The Hoodie Firm:

http://go.hood.ie/thehoodiefirm

* * *

This commit was sponsored by The Hoodie Firm.
You can hire The Hoodie Firm:

http://go.hood.ie/thehoodiefirm
  • Loading branch information
boennemann committed Aug 12, 2015
1 parent 619bab9 commit f6d7c0e
Show file tree
Hide file tree
Showing 21 changed files with 145 additions and 196 deletions.
46 changes: 17 additions & 29 deletions bin/start
@@ -1,14 +1,7 @@
#!/usr/bin/env node

/**
* Dependencies
*/

var environment = require('../lib/core/environment')
var hconsole = require('../lib/utils/hconsole')
var app = require('../lib')


// parse command-line arguments
var argv = require('optimist')
.usage('Usage: $0 [options]')
Expand All @@ -24,31 +17,26 @@ var argv = require('optimist')
.describe('debug', 'Shows hapi internal debug output')
.argv


if (require.main !== module) return

/**
* Start a Hoodie server configured for the current
* platform and environment
*/

if (require.main === module) {

var env_config = environment.getConfig(
process.platform, // platform
process.env, // environment vars
process.cwd(), // project directory
argv // command-line arguments
)

if (argv.help) {
// show usage information
return require('optimist').showHelp()
}

app.start(env_config, function (err) {
if (err) {
hconsole.error(err)
process.exit(1)
}
// line break before logs
console.log('')
})
if (argv.help) {
return require('optimist').showHelp()
}

console.log('Initializing Hoodie')
app.start({
argv: argv
}, function (err, server, env_config) {
if (err) return console.error(err)

server.start(function () {
console.log('WWW: ', env_config.www_link)
console.log('Admin: ', env_config.admin_link)
})
})
10 changes: 6 additions & 4 deletions lib/core/environment.js → lib/core/config.js
@@ -1,7 +1,6 @@
/**
* This module returns appropriate config values for the provided
* platform, environment and project. It is used directly by the start
* script in the bin directory.
* platform, environment and project.
*/

var path = require('path')
Expand All @@ -16,8 +15,11 @@ var couchUtils = require('../utils/couch')
* Returns all config values for current environment
*/

exports.getConfig = function (platform, env, cwd, argv) {
cwd = path.resolve(cwd)
module.exports = function (options) {
var platform = options.platform || process.platform
var env = options.env || process.env
var cwd = options.cwd || process.cwd()
var argv = options.argv || {}

// location of project's package.json
var pkgfile = require(cwd + '/package.json')
Expand Down
@@ -1,7 +1,7 @@
var _ = require('lodash')

var internals = require('./internals')
var plugins = require('../../../helpers/plugin_api')
var plugins = require('../../helpers/plugin_api')

exports.register = register
exports.register.attributes = {
Expand Down
Expand Up @@ -2,7 +2,7 @@ var path = require('path')

var Wreck = require('wreck')

var hoodiejs = require('../../../helpers/pack_hoodie')
var hoodiejs = require('../../helpers/pack_hoodie')

module.exports = {
addCorsAndBearerToken: function (err, res, request, reply) {
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
105 changes: 71 additions & 34 deletions lib/index.js
Expand Up @@ -5,60 +5,97 @@

var domain = require('domain')

var _ = require('lodash')
var async = require('async')
var Hapi = require('hapi')

var config = require('./core/config.js')
var couch = require('./couchdb')
var environment = require('./core/environment')
var hapi_plugins = require('./hapi_plugins')
var hooks = require('./core/hooks')
var installer = require('./couchdb/installer')
var plugins = require('./core/plugins')
var server = require('./server')
var utils = require('./utils')

/**
* Initializes and starts a new Hoodie app server
*/

exports.init = function (env_config, callback) {
exports.start = function (options, callback) {
var app_domain = domain.create()

var env_config = config(options)

// wrap in top-level domain, otherwise we sometimes don't get uncaught
// exceptions printed in node 0.10.x
app_domain.run(function () {
var hoodieServer = server(env_config)

// start the app
console.log('Initializing...')

async.applyEachSeries([
utils.ensurePaths,
utils.showConfigPath,
couch.start,
installer.install,
plugins.load,
hooks,
hoodieServer,
plugins.startAll,
utils.processSend
], env_config, callback)
})
app_domain.run(exports.init.bind(null, env_config, callback))

// make sure we print a stack trace in node 0.10.x
app_domain.on('error', function (err) {
console.error(err.stack || err.toString())
process.exit(1)
})
}

var options = {
connections: {
routes: {
cors: {override: false},
payload: {maxBytes: 1048576 * 10} // 10 MB
}
}
}

exports.start = function (config, callback) {
var env_config = environment.getConfig(
process.platform, // platform
process.env, // environment vars
process.cwd(), // project directory
[] // command-line arguments
)
exports.init = function (env_config, callback) {
if (env_config.debug) {
options.debug = {
log: ['error'],
request: ['error']
}
}

var server = new Hapi.Server(options)

async.applyEachSeries([
utils.ensurePaths,
utils.showConfigPath,
couch.start,
installer.install,
plugins.load,
hooks,
exports.configureServer.bind(null, server),
plugins.startAll,
utils.processSend
], env_config, function (err) {
if (err) return callback(err)

exports.init(_.merge(env_config, config), callback)
callback(null, server, env_config)
})
}

exports.configureServer = function (server, env_config, callback) {
env_config.hooks.runStatic('server.pack.pre', [server])

server.connection({
port: env_config.www_port,
labels: ['web']
})

server.connection({
port: env_config.admin_port,
labels: ['admin']
})

server.register(
hapi_plugins.map(function (plugin) {
return {
register: plugin,
options: {
app: env_config
}
}
}),
function (err) {
if (err) return callback(err)

env_config.hooks.runStatic('server.pack.post', [server])

callback(null)
}
)
}
64 changes: 0 additions & 64 deletions lib/server/index.js

This file was deleted.

5 changes: 2 additions & 3 deletions test/integration/assets.js
Expand Up @@ -2,10 +2,9 @@ var request = require('request')
var test = require('tap').test

var startServerTest = require('../lib/start-server-test')
var config = require('../lib/config')

startServerTest(test, 'should get asset path', config, function (t, end) {
request.get(config.url + '/_api/_plugins/_assets/index.html', function (error, res) {
startServerTest(test, 'should get asset path', function (t, env_config, end) {
request.get(env_config.www_link + '/_api/_plugins/_assets/index.html', function (error, res) {
if (error) throw error
t.is(res.statusCode, 200)
end()
Expand Down
7 changes: 3 additions & 4 deletions test/integration/cors.js
Expand Up @@ -2,11 +2,10 @@ var request = require('request')
var test = require('tap').test

var startServerTest = require('../lib/start-server-test')
var config = require('../lib/config')

startServerTest(test, 'setting CORS headers', config, function (t, end) {
startServerTest(test, 'setting CORS headers', function (t, env_config, end) {
t.test('should respond to OPTIONS with the right CORS headers when no origin is given', function (tt) {
request.get(config.url + '/_api/_session/', {
request.get(env_config.www_link + '/_api/_session/', {
headers: {
'transfer-encoding': 'chunked'
}
Expand All @@ -22,7 +21,7 @@ startServerTest(test, 'setting CORS headers', config, function (t, end) {
})
})
t.test('should echo the origin back if one is given', function (tt) {
request.get(config.url + '/_api/_session/', {
request.get(env_config.www_link + '/_api/_session/', {
headers: {
origin: 'http://some.app.com/',
'transfer-encoding': 'chunked'
Expand Down
9 changes: 4 additions & 5 deletions test/integration/force-gzip.js
Expand Up @@ -5,12 +5,11 @@ var request = require('request')
var test = require('tap').test

var startServerTest = require('../lib/start-server-test')
var config = require('../lib/config')

startServerTest(test, 'handle forced gzip', config, function (t, end) {
startServerTest(test, 'handle forced gzip', function (t, env_config, end) {
t.test('should receive gzip when gzip accept header sent', function (tt) {
tt.plan(3)
request.get(config.url + '/_api/', {
request.get(env_config.www_link + '/_api/', {
headers: {
'Accept-Encoding': 'gzip, deflate'
}
Expand All @@ -27,15 +26,15 @@ startServerTest(test, 'handle forced gzip', config, function (t, end) {
}))
})
t.test('should receive no gzip when no gzip accept header sent', function (tt) {
request.get(config.url + '/_api/')
request.get(env_config.www_link + '/_api/')
.on('response', function (res) {
tt.notOk(res.headers['content-encoding'])
tt.end()
})
})
t.test('should receive gzip when no gzip accept header sent but force query param', function (tt) {
tt.plan(3)
request.get(config.url + '/_api/?force_gzip=true')
request.get(env_config.www_link + '/_api/?force_gzip=true')
.on('response', function (res) {
tt.is(res.headers['content-encoding'], 'gzip')
})
Expand Down
7 changes: 3 additions & 4 deletions test/integration/handle_404.js
Expand Up @@ -2,11 +2,10 @@ var request = require('request')
var test = require('tap').test

var startServerTest = require('../lib/start-server-test')
var config = require('../lib/config')

startServerTest(test, 'handle 404', config, function (t, end) {
startServerTest(test, 'handle 404', function (t, env_config, end) {
t.test('should send index.html on accept: text/html', function (tt) {
request.get(config.url + '/does_not_exist', {
request.get(env_config.www_link + '/does_not_exist', {
headers: {
accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
}
Expand All @@ -18,7 +17,7 @@ startServerTest(test, 'handle 404', config, function (t, end) {
})
})
t.test('should send a JSON 404 on anything but accept: text/html*', function (tt) {
request.get(config.url + '/does_not_exist', {
request.get(env_config.www_link + '/does_not_exist', {
json: true
}, function (error, res, data) {
if (error) throw error
Expand Down

0 comments on commit f6d7c0e

Please sign in to comment.