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

Extend hooks config endpoint #256

Merged
merged 9 commits into from
May 29, 2017
3 changes: 2 additions & 1 deletion config/config.test.json.sample
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@
},
"paths": {
"collections": "test/acceptance/workspace/collections",
"endpoints": "test/acceptance/workspace/endpoints"
"endpoints": "test/acceptance/workspace/endpoints",
"hooks": "test/acceptance/workspace/hooks"
},
"logging": {
"enabled": true,
Expand Down
147 changes: 147 additions & 0 deletions dadi/lib/controller/hooks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
'use strict'

const fs = require('fs')
const path = require('path')
const help = require(path.join(__dirname, '/../help'))

const HOOK_PREFIX = 'hook:'

const HooksController = function (parameters) {
this.components = parameters.components
this.docs = parameters.docs
this.path = parameters.path
}

HooksController.prototype._deleteHook = function (name) {
const filePath = path.join(this.path, name + '.js')

return new Promise((resolve, reject) => {
fs.unlink(filePath, err => {
if (err) return reject(err)

resolve()
})
})
}

HooksController.prototype._findHooks = function (filterByName) {
let hooks = []

Object.keys(this.components).find(key => {
if (key.indexOf(HOOK_PREFIX) === 0) {
const hookName = key.replace(HOOK_PREFIX, '')

if (filterByName && filterByName !== hookName) {
return
}

hooks.push(hookName)

if (filterByName) {
return true
}
}
})

return hooks.sort()
}

HooksController.prototype._writeHook = function (name, content) {
const filePath = path.join(this.path, name + '.js')

return new Promise((resolve, reject) => {
fs.writeFile(filePath, content, err => {
if (err) return reject(err)

resolve()
})
})
}

HooksController.prototype.delete = function (req, res, next) {
const name = req.params.hookName
const hook = this._findHooks(name)[0]

if (!hook) {
return help.sendBackText(404, res, next)(null, '')
}

this._deleteHook(name).then(() => {
return help.sendBackText(200, res, next)(null, '')
}).catch(err => {
return help.sendBackText(200, res, next)(err, '')
})
}

HooksController.prototype.get = function (req, res, next) {
// Return the content of a specific hook
if (req.params.hookName) {
const name = req.params.hookName
const hook = this._findHooks(name)[0]

if (!hook) {
return help.sendBackText(404, res, next)(null, '')
}

fs.readFile(this.components[HOOK_PREFIX + name], (err, content) => {
return help.sendBackText(200, res, next)(err, content.toString())
})
} else {
// List all hooks
const hooks = this._findHooks().map(key => {
let hook = {
name: key
}

const docs = this.docs[HOOK_PREFIX + key]

if (docs && docs[0]) {
hook.description = docs[0].description
hook.params = docs[0].params
hook.returns = docs[0].returns
}

return hook
})

const data = {
hooks: hooks
}

return help.sendBackJSON(200, res, next)(null, data)
}
}

HooksController.prototype.post = function (req, res, next) {
const name = req.params.hookName
const hook = this._findHooks(name)[0]

if (hook) {
return help.sendBackJSON(409, res, next)(null, {
err: 'Hook already exists'
})
}

return this._writeHook(name, req.body).then(() => {
return help.sendBackText(200, res, next)(null, '')
}).catch(err => {
return help.sendBackText(200, res, next)(err, '')
})
}

HooksController.prototype.put = function (req, res, next) {
const name = req.params.hookName
const hook = this._findHooks(name)[0]

if (!hook) {
return help.sendBackText(404, res, next)(null, '')
}

return this._writeHook(name, req.body).then(() => {
return help.sendBackText(200, res, next)(null, '')
}).catch(err => {
return help.sendBackText(200, res, next)(err, '')
})
}

module.exports = HooksController
78 changes: 29 additions & 49 deletions dadi/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ var api = require(path.join(__dirname, '/api'))
var auth = require(path.join(__dirname, '/auth'))
var cache = require(path.join(__dirname, '/cache'))
var Controller = require(path.join(__dirname, '/controller'))
var HooksController = require(path.join(__dirname, '/controller/hooks'))
var MediaController = require(path.join(__dirname, '/controller/media'))
var dadiStatus = require('@dadi/status')
var help = require(path.join(__dirname, '/help'))
Expand Down Expand Up @@ -214,7 +215,7 @@ Server.prototype.start = function (done) {

this.loadCollectionRoute()
this.loadEndpointsRoute()
this.loadHooksRoute()
this.loadHooksRoute(options)

this.readyState = 1

Expand Down Expand Up @@ -379,6 +380,10 @@ Server.prototype.loadConfigApi = function () {
// handler if required.
if (url.parse(req.url).pathname.indexOf('endpoints') > 0) return next()

// the hooks config endpoint also shares this structure, so if the
// URL starts with /api, we move on to the next handler.
if (req.params.version === 'api') return next()

var method = req.method && req.method.toLowerCase()
if (method !== 'post') return next()

Expand Down Expand Up @@ -476,7 +481,7 @@ Server.prototype.loadCollectionRoute = function () {
this.app.use('/api/collections', function (req, res, next) {
var method = req.method && req.method.toLowerCase()

if (method !== 'get') return help.sendBackJSON(400, res, next)(null, {'error': 'Invalid method'})
if (method !== 'get') return help.sendBackJSON(405, res, next)(null, {'error': 'Invalid method'})

var data = {}
var collections = []
Expand Down Expand Up @@ -557,7 +562,7 @@ Server.prototype.loadEndpointsRoute = function () {
this.app.use('/api/endpoints', function (req, res, next) {
var method = req.method && req.method.toLowerCase()

if (method !== 'get') return help.sendBackJSON(400, res, next)(null, {'error': 'Invalid method'})
if (method !== 'get') return help.sendBackJSON(405, res, next)(null, {'error': 'Invalid method'})

var data = {}
var endpoints = []
Expand Down Expand Up @@ -599,54 +604,31 @@ Server.prototype.loadEndpointsRoute = function () {
}

// route to retrieve list of available hooks
Server.prototype.loadHooksRoute = function () {
var self = this

this.app.use('/api/hooks', function (req, res, next) {
var method = req.method && req.method.toLowerCase()
if (method !== 'get') return help.sendBackJSON(400, res, next)(null, {'error': 'Invalid method'})

var data = {}
var hooks = []

_.each(self.components, function (value, key) {
if (key.indexOf('hook:') === 0) {
var hook = {
name: key.replace('hook:', '')
}
Server.prototype.loadHooksRoute = function (options) {
const hooksController = new HooksController({
components: this.components,
docs: this.docs,
path: options.hookPath
})

var docs = self.docs[key]
if (docs && docs[0]) {
hook.description = docs[0].description
hook.params = docs[0].params
hook.returns = docs[0].returns
}
this.app.use('/api/hooks', (req, res, next) => {
const method = req.method && req.method.toLowerCase()

hooks.push(hook)
}
})

data.hooks = _.sortBy(hooks, 'name')
if (method === 'get') {
return hooksController[method](req, res, next)
}

return help.sendBackJSON(200, res, next)(null, data)
return help.sendBackJSON(405, res, next)(null, {'error': 'Invalid method'})
})

this.app.use('/api/hooks/:hook/config', function (req, res, next) {
var method = req.method && req.method.toLowerCase()
if (method !== 'get') return help.sendBackJSON(400, res, next)(null, {'error': 'Invalid method'})

_.each(self.components, function (value, key) {
if (key.indexOf('hook:') === 0) {
var hook = key.replace('hook:', '')
this.app.use('/api/hooks/:hookName/config', (req, res, next) => {
const method = req.method && req.method.toLowerCase()

if (hook === req.params.hook) {
var content = fs.readFileSync(value)
return help.sendBackText(200, res, next)(null, content.toString())
}
}
})
if (typeof hooksController[method] === 'function') {
return hooksController[method](req, res, next)
}

return help.sendBackJSON(404, res, next)(null, {})
return help.sendBackJSON(405, res, next)(null, {'error': 'Invalid method'})
})
}

Expand Down Expand Up @@ -941,12 +923,10 @@ Server.prototype.addHook = function (options) {

try {
opts.component = require(filepath)
} catch (e) {
} catch (err) {
// if file was removed "un-use" this component
if (e && e.code === 'ENOENT') {
self.removeMonitor(filepath)
self.removeComponent(opts.route)
}
self.removeMonitor(filepath)
self.removeComponent(opts.route)
}
})

Expand Down
Loading