-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(sse): add server-sent events endpoint
- Loading branch information
1 parent
c0a3863
commit 3b11e32
Showing
15 changed files
with
199 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,10 @@ | ||
const config = require('./config'); | ||
const jobs = require('./jobs'); | ||
const control = require('./control'); | ||
const sse = require('./sse'); | ||
|
||
const test = (ctx) => { | ||
ctx.body = { breeExists: Boolean(ctx.bree) }; | ||
}; | ||
|
||
module.exports = { config, test, jobs, control }; | ||
module.exports = { config, test, jobs, control, sse }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
async function connect(ctx) { | ||
if (ctx.sse) { | ||
// send bree events over sse | ||
for (const event of ['worker created', 'worker deleted']) { | ||
ctx.bree.on(event, (name) => { | ||
ctx.sse.send({ event, data: { name } }); | ||
}); | ||
} | ||
|
||
ctx.sse.on('close', () => { | ||
ctx.logger.error('SSE closed'); | ||
}); | ||
} | ||
} | ||
|
||
module.exports = { connect }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,54 @@ | ||
const sharedConfig = require('@ladjs/shared-config'); | ||
const jwt = require('koa-jwt'); | ||
const sse = require('koa-sse-stream'); | ||
|
||
const logger = require('../helpers/logger'); | ||
const routes = require('../routes'); | ||
const config = require('../config'); | ||
|
||
module.exports = { | ||
...sharedConfig('API'), | ||
routes: routes.api, | ||
logger, | ||
hookBeforeRoutes(app) { | ||
app.use(jwt(config.jwt)); | ||
} | ||
module.exports = (opts = {}) => { | ||
const sseMiddleware = sse({ ...config.sse, ...opts.sse }); | ||
const jwtMiddleware = jwt({ | ||
...config.jwt, | ||
...opts.jwt, | ||
getToken(ctx, _) { | ||
// pull token off of url if it is the sse endpoint | ||
if (ctx.url.indexOf('/v1/sse') === 0) { | ||
const splitUrl = ctx.url.split('/'); | ||
|
||
if (splitUrl.length === 4) { | ||
return splitUrl[3]; | ||
} | ||
} | ||
|
||
return null; | ||
} | ||
}); | ||
|
||
return { | ||
...sharedConfig('API'), | ||
port: config.port, | ||
...opts, | ||
routes: routes.api, | ||
logger, | ||
hookBeforeRoutes(app) { | ||
app.use((ctx, next) => { | ||
// return early if jwt is set to false | ||
if (!opts.jwt && typeof opts.jwt === 'boolean') { | ||
return next(); | ||
} | ||
|
||
return jwtMiddleware(ctx, next); | ||
}); | ||
|
||
app.use((ctx, next) => { | ||
// only do this on sse route | ||
if (ctx.url.indexOf('/v1/sse') === 0) { | ||
return sseMiddleware(ctx, next); | ||
} | ||
|
||
return next(); | ||
}); | ||
} | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
const test = require('ava'); | ||
|
||
const utils = require('../../utils'); | ||
|
||
test.before(async (t) => { | ||
await utils.setupApiServer(t, {}, { jwt: false }); | ||
}); | ||
|
||
test('works when no creds are presented', async (t) => { | ||
const { api } = t.context; | ||
const res = await api.get('/v1/test'); | ||
|
||
t.is(res.status, 200); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
const path = require('path'); | ||
const { once } = require('events'); | ||
const test = require('ava'); | ||
const jwt = require('jsonwebtoken'); | ||
|
||
const config = require('../../../config'); | ||
|
||
const utils = require('../../utils'); | ||
|
||
const rootUrl = '/v1/sse'; | ||
|
||
test.before(async (t) => { | ||
await utils.setupApiServer(t, { | ||
jobs: [ | ||
{ name: 'done', path: path.join(utils.root, 'basic.js') }, | ||
{ | ||
name: 'delayed', | ||
path: path.join(utils.root, 'basic.js'), | ||
timeout: 100 | ||
}, | ||
{ | ||
name: 'waiting', | ||
path: path.join(utils.root, 'basic.js'), | ||
interval: 100 | ||
}, | ||
{ | ||
name: 'active', | ||
path: path.join(utils.root, 'long.js') | ||
} | ||
] | ||
}); | ||
t.context.token = jwt.sign({}, config.jwt.secret); | ||
|
||
t.context.api = t.context.api.auth(t.context.token, { type: 'bearer' }); | ||
|
||
t.context.bree.start(); | ||
}); | ||
|
||
test('successfully connect to sse', async (t) => { | ||
const es = utils.setupEventSource(t, rootUrl); | ||
|
||
await once(es, 'open'); | ||
|
||
t.pass(); | ||
}); | ||
|
||
const eventsMacro = test.macro({ | ||
async exec(t, event) { | ||
const es = utils.setupEventSource(t, rootUrl); | ||
|
||
await once(es, event); | ||
|
||
t.pass(); | ||
}, | ||
title(_, event) { | ||
return `successfully listen to "${event}" messages`; | ||
} | ||
}); | ||
|
||
test(eventsMacro, 'worker created'); | ||
test(eventsMacro, 'worker deleted'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters