ironbar/services/gateway/index.js
2018-12-23 07:57:32 -06:00

83 lines
2.4 KiB
JavaScript

const http = require('http');
const debug = require('debug')('truss:gateway');
const {createDispatcher, sendActionToService} = require('@truss/comm');
let listener = require('./listener').default;
// ---
if (!process.env.SERVICES) {
console.error('$SERVICES must be defined!');
process.exit(1);
}
const services = process.env.SERVICES.split(',');
// get all schemas
const schemas$ = services.map((service) => {
return sendActionToService({type: 'truss/schema'}, service);
});
// build service map
const reduceServiceMap$ = Promise.all(schemas$).then((schemas) => {
return schemas.reduce((serviceMap, schema, i) => {
const service = services[i];
for (const type of (schema.executors || [])) {
if (serviceMap.executors[type]) {
throw new RangeError(`
Only one executor may be specified per action type! "${service}"
tried to register an executor but "${serviceMap.executors[type]}"
already registered one for "${type}".
`.replace(/\s+/g, ' ').trim());
}
serviceMap.executors[type] = service;
}
for (const type of (schema.listeners || [])) {
serviceMap.listeners[type] = serviceMap.listeners[type] || [];
serviceMap.listeners[type].push(service);
}
for (const hook of (schema.hooks || [])) {
serviceMap.hooks[hook] = serviceMap.hooks[hook] || [];
serviceMap.hooks[hook].push(service);
}
return serviceMap;
}, {
executors: {},
hooks: {},
listeners: {},
});
});
// hey, listen
const httpServer = http.createServer();
reduceServiceMap$.then((serviceMap) => {
debug(`service map: ${JSON.stringify(serviceMap, null, ' ')}`);
const dispatcher = createDispatcher();
dispatcher.setArgs(serviceMap);
dispatcher.lookupActions(require('./actions'));
if (module.hot) {
module.hot.accept('./actions', () => {
dispatcher.lookupActions(require('./actions'));
});
}
const server = dispatcher.connect();
server.on('listening', () => {
const port = process.env.GATEWAY_PORT || 8000;
httpServer.listen(port);
httpServer.on('listening', () => {
debug(`HTTP listening on port ${port}...`);
})
httpServer.on('request', (req, res) => {
listener(serviceMap, req, res);
});
});
}).catch(console.error);
if (module.hot) {
module.hot.accept('./listener', () => {
listener = require('./listener').default;
});
}