exocom-dev
Advanced tools
Comparing version 0.15.2 to 0.21.0
// Generated by LiveScript 1.5.0 | ||
var ref$, cyan, dim, green, red, magenta, yellow, docopt, N, name, version, path, ExoCom, doc, onWebsocketBound, onHttpBound, onError, onWarn, run, options; | ||
ref$ = require('chalk'), cyan = ref$.cyan, dim = ref$.dim, green = ref$.green, red = ref$.red, magenta = ref$.magenta, yellow = ref$.yellow; | ||
var CliLogger, docopt, ref$, name, version, ExoCom, logger, doc, options; | ||
CliLogger = require('./cli-logger'); | ||
docopt = require('docopt').docopt; | ||
N = require('nitroglycerin'); | ||
ref$ = require('../package.json'), name = ref$.name, version = ref$.version; | ||
version = require('../package.json').version; | ||
path = require('path'); | ||
ExoCom = require('./exocom'); | ||
console.log(dim("Exosphere Development Communications server " + version + "\n")); | ||
doc = "Provides Exosphere communication infrastructure services in development mode.\n\nUsage:\n " + name + " [PORT=<port>]\n " + name + " -h | --help\n " + name + " -v | --version"; | ||
onWebsocketBound = function(port){ | ||
console.log(dim("Ctrl-C to stop")); | ||
return console.log("ExoCom " + version + " WebSocket listener online at port " + cyan(port)); | ||
}; | ||
onHttpBound = function(port){ | ||
console.log(dim("Ctrl-C to stop")); | ||
return console.log("ExoCom " + version + " HTTP service online at port " + magenta(port)); | ||
}; | ||
onError = function(err){ | ||
console.log(red("Error: " + err)); | ||
return process.exit(1); | ||
}; | ||
onWarn = function(warning){ | ||
return console.log(yellow("Warning: " + warning)); | ||
}; | ||
run = function(){ | ||
logger = new CliLogger; | ||
logger.header("Exocom " + version + "\n"); | ||
doc = "Provides Exosphere communication infrastructure services in development mode.\nExpects the following environment variables:\n- SERVICE_ROUTES: list of messages that the different service types are allowed to send and receive\n- PORT: the port to listen on\n\nUsage:\n " + name + "\n " + name + " -h | --help\n " + name + " -v | --version"; | ||
switch (options = docopt(doc, { | ||
help: false | ||
})) { | ||
case options['-h'] || options['--help']: | ||
logger.log(doc); | ||
break; | ||
case options['-v'] || options['--version']: | ||
break; | ||
default: | ||
run(); | ||
} | ||
function run(){ | ||
var x$, exocom; | ||
x$ = exocom = new ExoCom({ | ||
serviceMessages: process.env.SERVICE_MESSAGES | ||
serviceRoutes: process.env.SERVICE_ROUTES, | ||
logger: logger | ||
}); | ||
x$.on('websocket-bound', onWebsocketBound); | ||
x$.on('http-bound', onHttpBound); | ||
x$.on('error', onError); | ||
x$.on('warn', onWarn); | ||
x$.on('error', logger.error); | ||
x$.listen(+process.env.PORT || 3100); | ||
x$.on('routing-setup', function(){ | ||
var command, ref$, routing, text, res$, i$, ref1$, len$, receiver, results$ = []; | ||
console.log('receiving routing setup:'); | ||
for (command in ref$ = exocom.clientRegistry.routes) { | ||
routing = ref$[command]; | ||
process.stdout.write(" --[ " + command + " ]-> "); | ||
res$ = []; | ||
for (i$ = 0, len$ = (ref1$ = routing.receivers).length; i$ < len$; ++i$) { | ||
receiver = ref1$[i$]; | ||
res$.push(receiver.name + ""); | ||
} | ||
text = res$; | ||
results$.push(process.stdout.write(text.join(' + ') + "\n")); | ||
} | ||
return results$; | ||
}); | ||
x$.on('message', function(arg$){ | ||
var messages, receivers, i$, len$, message, responseTime, results$ = []; | ||
messages = arg$.messages, receivers = arg$.receivers; | ||
for (i$ = 0, len$ = messages.length; i$ < len$; ++i$) { | ||
message = messages[i$]; | ||
responseTime = ''; | ||
if (message.responseTo) { | ||
responseTime = " (" + (message.responseTime * 1e-6).toFixed(2) + " ms)"; | ||
} | ||
if (message.name === message.originalName) { | ||
console.log(message.sender + " --[ " + message.name + " ]-> " + receivers.join(' and ') + responseTime); | ||
} else { | ||
console.log(message.sender + " --[ " + message.originalName + " ]-[ " + message.name + " ]-> " + receivers.join(' and ') + responseTime); | ||
} | ||
results$.push(console.log(message.payload)); | ||
} | ||
return results$; | ||
}); | ||
return x$; | ||
}; | ||
options = docopt(doc, { | ||
help: false | ||
}); | ||
switch (false) { | ||
case !(options['-h'] || options['--help']): | ||
console.log(doc); | ||
break; | ||
case !(options['-v'] || options['--version']): | ||
break; | ||
default: | ||
run(); | ||
} |
// Generated by LiveScript 1.5.0 | ||
var jsonic, removeValue, requireYaml, ClientRegistry; | ||
var jsonic, removeValue, requireYaml, SubscriptionManager, ClientRegistry; | ||
jsonic = require('jsonic'); | ||
removeValue = require('remove-value'); | ||
requireYaml = require('require-yaml'); | ||
SubscriptionManager = require('./subscription-manager'); | ||
ClientRegistry = (function(){ | ||
@@ -10,110 +11,63 @@ ClientRegistry.displayName = 'ClientRegistry'; | ||
function ClientRegistry(arg$){ | ||
var ref$, res$, i$, len$, service; | ||
this.serviceMessages = (ref$ = (arg$ != null | ||
var serviceRoutes, ref$; | ||
serviceRoutes = (ref$ = (arg$ != null | ||
? arg$ | ||
: {}).serviceMessages) != null ? ref$ : '{}'; | ||
res$ = {}; | ||
for (i$ = 0, len$ = (ref$ = jsonic(this.serviceMessages)).length; i$ < len$; ++i$) { | ||
service = ref$[i$]; | ||
res$[service.name] = { | ||
receives: service.receives, | ||
sends: service.sends, | ||
internalNamespace: service.namespace | ||
}; | ||
} | ||
this.routing = res$; | ||
: {}).serviceRoutes) != null ? ref$ : '{}'; | ||
this.routing = this._parseServiceRoutes(serviceRoutes); | ||
this.clients = {}; | ||
this.routes = {}; | ||
this.subscriptions = new SubscriptionManager(this.routing); | ||
} | ||
ClientRegistry.prototype.reset = function(){ | ||
this.clients = {}; | ||
return this.subscribers = {}; | ||
}; | ||
ClientRegistry.prototype.setRoutingConfig = function(services){ | ||
var i$, len$, service, results$ = []; | ||
this.reset(); | ||
for (i$ = 0, len$ = services.length; i$ < len$; ++i$) { | ||
service = services[i$]; | ||
results$.push(this.addRoutingConfig(service)); | ||
} | ||
return results$; | ||
}; | ||
ClientRegistry.prototype.addRoutingConfig = function(service){ | ||
var i$, ref$, len$, message, externalMessage, ref1$, results$ = []; | ||
this.clients[service.name] = { | ||
name: service.name, | ||
internalNamespace: this.routing[service.name].internalNamespace | ||
}; | ||
for (i$ = 0, len$ = (ref$ = this.routing[service.name].receives || {}).length; i$ < len$; ++i$) { | ||
message = ref$[i$]; | ||
externalMessage = this.externalMessageName({ | ||
message: message, | ||
serviceName: service.name, | ||
internalNamespace: this.routing[service.name].internalNamespace | ||
}); | ||
(ref1$ = this.routes)[externalMessage] || (ref1$[externalMessage] = {}); | ||
(ref1$ = this.routes[externalMessage]).receivers || (ref1$.receivers = []); | ||
results$.push(this.routes[externalMessage].receivers.push({ | ||
name: service.name, | ||
internalNamespace: this.routing[service.name].internalNamespace | ||
})); | ||
} | ||
return results$; | ||
}; | ||
ClientRegistry.prototype.removeRoutingConfig = function(arg$){ | ||
var serviceName, i$, ref$, len$, message, externalMessage, ref1$; | ||
serviceName = arg$.serviceName; | ||
for (i$ = 0, len$ = (ref$ = this.routing[serviceName].receives || {}).length; i$ < len$; ++i$) { | ||
message = ref$[i$]; | ||
externalMessage = this.externalMessageName({ | ||
message: message, | ||
serviceName: serviceName, | ||
internalNamespace: this.clients[serviceName].internalNamespace | ||
}); | ||
delete this.routes[externalMessage]; | ||
} | ||
return ref1$ = (ref$ = this.clients)[serviceName], delete ref$[serviceName], ref1$; | ||
}; | ||
ClientRegistry.prototype.subscribersTo = function(messageName){ | ||
switch (false) { | ||
case !this.routes[messageName]: | ||
return this.routes[messageName].receivers; | ||
} | ||
}; | ||
ClientRegistry.prototype.canSend = function(sender, message){ | ||
ClientRegistry.prototype.canSend = function(senderName, messageName){ | ||
var this$ = this; | ||
return function(it){ | ||
return it.includes(message); | ||
return it.includes(messageName); | ||
}( | ||
this.routing[sender].sends); | ||
this.routing[senderName].sends); | ||
}; | ||
ClientRegistry.prototype.externalMessageName = function(arg$){ | ||
var message, serviceName, internalNamespace, messageParts; | ||
message = arg$.message, serviceName = arg$.serviceName, internalNamespace = arg$.internalNamespace; | ||
messageParts = message.split('.'); | ||
switch (false) { | ||
case !!internalNamespace: | ||
return message; | ||
case messageParts.length !== 1: | ||
return message; | ||
case messageParts[0] !== serviceName: | ||
return message; | ||
default: | ||
return serviceName + "." + messageParts[1]; | ||
} | ||
ClientRegistry.prototype.deregisterClient = function(clientName){ | ||
var ref$, ref1$; | ||
this.subscriptions.remove(clientName); | ||
return ref1$ = (ref$ = this.clients)[clientName], delete ref$[clientName], ref1$; | ||
}; | ||
ClientRegistry.prototype.outgoingMessageName = function(message, service){ | ||
ClientRegistry.prototype.outgoingMessageName = function(messageName, service){ | ||
var messageParts; | ||
messageParts = message.split('.'); | ||
messageParts = messageName.split('.'); | ||
switch (false) { | ||
case messageParts.length !== 1: | ||
return message; | ||
return messageName; | ||
case messageParts[0] !== service.internalNamespace: | ||
return service.name + "." + messageParts[1]; | ||
return service.serviceType + "." + messageParts[1]; | ||
default: | ||
return message; | ||
return messageName; | ||
} | ||
}; | ||
ClientRegistry.prototype.registerClient = function(client){ | ||
this.clients[client.clientName] = { | ||
clientName: client.clientName, | ||
serviceType: client.clientName, | ||
internalNamespace: this.routing[client.clientName].internalNamespace | ||
}; | ||
return this.subscriptions.addAll({ | ||
clientName: client.clientName, | ||
serviceType: client.clientName | ||
}); | ||
}; | ||
ClientRegistry.prototype.subscribersFor = function(messageName){ | ||
return this.subscriptions.subscribersFor(messageName); | ||
}; | ||
ClientRegistry.prototype._parseServiceRoutes = function(serviceRoutes){ | ||
var result, i$, ref$, len$, serviceRoute; | ||
result = {}; | ||
for (i$ = 0, len$ = (ref$ = jsonic(serviceRoutes)).length; i$ < len$; ++i$) { | ||
serviceRoute = ref$[i$]; | ||
result[serviceRoute.role] = { | ||
receives: serviceRoute.receives, | ||
sends: serviceRoute.sends, | ||
internalNamespace: serviceRoute.namespace | ||
}; | ||
} | ||
return result; | ||
}; | ||
return ClientRegistry; | ||
}()); | ||
module.exports = ClientRegistry; |
// Generated by LiveScript 1.5.0 | ||
var ClientRegistry, EventEmitter, ListenerSubsystem, MessageCache, nanoseconds, process, ref$, delegate, delegateEvent, WebSocketSubsystem, debug, ExoCom; | ||
var ClientRegistry, EventEmitter, HttpSubsystem, MessageCache, nanoseconds, process, ref$, delegate, delegateEvent, WebSocketSubsystem, debug, ExoCom; | ||
ClientRegistry = require('./client-registry/client-registry'); | ||
EventEmitter = require('events').EventEmitter; | ||
ListenerSubsystem = require('./listener-subsystem/listener-subsystem'); | ||
HttpSubsystem = require('./http-subsystem/http-subsystem'); | ||
MessageCache = require('./message-cache/message-cache'); | ||
@@ -15,73 +15,100 @@ nanoseconds = require('nanoseconds'); | ||
function ExoCom(arg$){ | ||
this.serviceMessages = (arg$ != null | ||
var ref$, serviceRoutes, x$, y$, this$ = this; | ||
ref$ = arg$ != null | ||
? arg$ | ||
: {}).serviceMessages; | ||
: {}, serviceRoutes = ref$.serviceRoutes, this.logger = ref$.logger; | ||
this.sendMessage = bind$(this, 'sendMessage', prototype); | ||
this.removeRoutingConfig = bind$(this, 'removeRoutingConfig', prototype); | ||
this.addRoutingConfig = bind$(this, 'addRoutingConfig', prototype); | ||
this.setRoutingConfig = bind$(this, 'setRoutingConfig', prototype); | ||
this.getConfig = bind$(this, 'getConfig', prototype); | ||
this.deregisterClient = bind$(this, 'deregisterClient', prototype); | ||
this.clientRegistry = new ClientRegistry({ | ||
serviceMessages: this.serviceMessages | ||
serviceRoutes: serviceRoutes | ||
}); | ||
this.listenerSubsystem = new ListenerSubsystem(this); | ||
x$ = this.httpSubsystem = new HttpSubsystem({ | ||
exocom: this, | ||
logger: this.logger | ||
}); | ||
x$.on('online', function(port){ | ||
return this$.emit('http-online', port); | ||
}); | ||
x$.on('config-request', function(responseStream){ | ||
return this$.handleConfigRequest(responseStream); | ||
}); | ||
this.messageCache = new MessageCache(); | ||
this.websocket = new WebSocketSubsystem(this); | ||
delegate('httpPort', { | ||
from: this, | ||
to: this.listenerSubsystem | ||
y$ = this.websocket = new WebSocketSubsystem({ | ||
exocom: this, | ||
logger: this.logger | ||
}); | ||
delegateEvent('http-bound', 'error', { | ||
from: this.listenerSubsystem, | ||
to: this | ||
y$.on('online', function(port){ | ||
return this$.emit('websockets-online', port); | ||
}); | ||
delegateEvent('websocket-bound', 'error', 'warn', { | ||
from: this.websocket, | ||
to: this | ||
y$.on('deregister-client', function(clientName){ | ||
return this$.deregisterClient(clientName); | ||
}); | ||
y$.on('message', function(message){ | ||
return this$.handleIncomingMessage(message); | ||
}); | ||
} | ||
ExoCom.prototype.close = function(){ | ||
this.httpSubsystem.close(); | ||
return this.websocket.close(); | ||
}; | ||
ExoCom.prototype.deregisterClient = function(clientName){ | ||
this.clientRegistry.deregisterClient(clientName); | ||
return this.websocket.deregisterClient(clientName); | ||
}; | ||
ExoCom.prototype.getConfig = function(){ | ||
return { | ||
services: this.clientRegistry.clients, | ||
routes: this.clientRegistry.routes | ||
clients: this.clientRegistry.clients, | ||
routes: this.clientRegistry.routing | ||
}; | ||
}; | ||
ExoCom.prototype.close = function(){ | ||
this.listenerSubsystem.close(); | ||
return this.websocket.close(); | ||
ExoCom.prototype.hasInvalidSender = function(message){ | ||
return !this.clientRegistry.canSend(message.sender, message.name); | ||
}; | ||
ExoCom.prototype.listen = function(port){ | ||
var expressServer; | ||
expressServer = this.listenerSubsystem.listen(port); | ||
expressServer = this.httpSubsystem.listen(port); | ||
this.websocket.listen(port, expressServer); | ||
return debug("Listening at port " + port); | ||
}; | ||
ExoCom.prototype.setRoutingConfig = function(routingConfig){ | ||
debug('receiving service setup'); | ||
this.clientRegistry.setRoutingConfig(routingConfig); | ||
this.emit('routing-setup'); | ||
return 'success'; | ||
ExoCom.prototype.handleConfigRequest = function(responseStream){ | ||
return this.httpSubsystem.sendConfiguration({ | ||
configuration: this.getConfig(), | ||
responseStream: responseStream | ||
}); | ||
}; | ||
ExoCom.prototype.addRoutingConfig = function(routingConfig){ | ||
this.clientRegistry.addRoutingConfig(routingConfig); | ||
return 'success'; | ||
ExoCom.prototype.handleIncomingMessage = function(arg$){ | ||
var message, websocket; | ||
message = arg$.message, websocket = arg$.websocket; | ||
switch (false) { | ||
case message.name !== 'exocom.register-service': | ||
return this.registerClient({ | ||
message: message, | ||
websocket: websocket | ||
}); | ||
case !this.hasInvalidSender(message): | ||
return this.logger.error("Service '" + message.sender + "' is not allowed to broadcast the message '" + message.name + "'"); | ||
default: | ||
return this.sendMessage(message); | ||
} | ||
}; | ||
ExoCom.prototype.removeRoutingConfig = function(arg$){ | ||
var serviceName; | ||
serviceName = arg$.serviceName; | ||
this.clientRegistry.removeRoutingConfig({ | ||
serviceName: serviceName | ||
ExoCom.prototype.registerClient = function(arg$){ | ||
var message, websocket; | ||
message = arg$.message, websocket = arg$.websocket; | ||
this.clientRegistry.registerClient(message.payload); | ||
return this.websocket.registerClient({ | ||
clientName: message.payload.clientName, | ||
websocket: websocket | ||
}); | ||
return 'success'; | ||
}; | ||
ExoCom.prototype.sendMessage = function(messageData){ | ||
var sender, externalMessageName, subscribers, subscriberNames, res$, i$, len$, subscriber, originalTimestamp, sentMessages; | ||
var sender, publicMessageName, subscribers, subscriberNames, res$, i$, len$, subscriber, originalTimestamp, sentMessages; | ||
sender = this.clientRegistry.clients[messageData.sender]; | ||
externalMessageName = this.clientRegistry.outgoingMessageName(messageData.name, sender); | ||
publicMessageName = this.clientRegistry.outgoingMessageName(messageData.name, sender); | ||
messageData.originalName = messageData.name; | ||
messageData.name = externalMessageName; | ||
messageData.name = publicMessageName; | ||
messageData.timestamp = nanoseconds(process.hrtime()); | ||
subscribers = this.clientRegistry.subscribersTo(externalMessageName); | ||
subscribers = this.clientRegistry.subscribersFor(publicMessageName); | ||
if (!subscribers) { | ||
return 'no receivers'; | ||
return this.logger.warning("No receivers for message '" + messageData.name + "' registered"); | ||
} | ||
@@ -91,3 +118,3 @@ res$ = []; | ||
subscriber = subscribers[i$]; | ||
res$.push(subscriber.name); | ||
res$.push(subscriber.clientName); | ||
} | ||
@@ -102,4 +129,4 @@ subscriberNames = res$; | ||
debug("sending '" + messageData.name + "' to " + subscriberNames); | ||
sentMessages = this.websocket.sendToServices(messageData, subscribers); | ||
this.emit('message', { | ||
sentMessages = this.websocket.sendMessageToServices(messageData, subscribers); | ||
this.logger.messages({ | ||
messages: sentMessages, | ||
@@ -106,0 +133,0 @@ receivers: subscriberNames |
@@ -10,31 +10,32 @@ // Generated by LiveScript 1.5.0 | ||
var this$ = this instanceof ctor$ ? this : new ctor$; | ||
cleanupInterval == null && (cleanupInterval = 60000); | ||
this$.getOriginalTimestamp = bind$(this$, 'getOriginalTimestamp', prototype); | ||
this$.cleanupInterval = cleanupInterval != null ? cleanupInterval : 60000; | ||
this$.remove = bind$(this$, 'remove', prototype); | ||
this$.push = bind$(this$, 'push', prototype); | ||
this$.cleanupInterval = cleanupInterval; | ||
this$.getOriginalTimestamp = bind$(this$, 'getOriginalTimestamp', prototype); | ||
this$.cleanup = bind$(this$, 'cleanup', prototype); | ||
this$.cache = {}; | ||
repeat(this$.cleanupInterval, function(){ | ||
var now, id, ref$, timestamp, results$ = []; | ||
now = nanoseconds(process.hrtime()); | ||
for (id in ref$ = this.cache) { | ||
timestamp = ref$[id]; | ||
if (timestamp - now >= this.cleanupInterval * 1e9) { | ||
results$.push(this.remove(id)); | ||
} | ||
} | ||
return results$; | ||
}); | ||
repeat(this$.cleanupInterval, this$.cleanup); | ||
return this$; | ||
} function ctor$(){} ctor$.prototype = prototype; | ||
MessageCache.prototype.push = function(id, timestamp){ | ||
return this.cache[id] = timestamp; | ||
MessageCache.prototype.cleanup = function(){ | ||
var now, id, ref$, timestamp, results$ = []; | ||
now = nanoseconds(process.hrtime()); | ||
for (id in ref$ = this.cache) { | ||
timestamp = ref$[id]; | ||
if (timestamp - now >= this.cleanupInterval * 1e9) { | ||
results$.push(this.remove(id)); | ||
} | ||
} | ||
return results$; | ||
}; | ||
MessageCache.prototype.remove = function(id){ | ||
MessageCache.prototype.getOriginalTimestamp = function(messageId){ | ||
return this.cache[messageId]; | ||
}; | ||
MessageCache.prototype.push = function(messageId, timestamp){ | ||
return this.cache[messageId] = timestamp; | ||
}; | ||
MessageCache.prototype.remove = function(messageId){ | ||
var ref$, ref1$; | ||
return ref1$ = (ref$ = this.cache)[id], delete ref$[id], ref1$; | ||
return ref1$ = (ref$ = this.cache)[messageId], delete ref$[messageId], ref1$; | ||
}; | ||
MessageCache.prototype.getOriginalTimestamp = function(id){ | ||
return this.cache[id]; | ||
}; | ||
return MessageCache; | ||
@@ -41,0 +42,0 @@ }()); |
// Generated by LiveScript 1.5.0 | ||
var EventEmitter, MessageCache, WebSocketServer, debug, WebSocketSubsystem; | ||
var cyan, EventEmitter, MessageCache, MessageTranslator, WebSocketServer, debug, WebSocketSubsystem; | ||
cyan = require('chalk').cyan; | ||
EventEmitter = require('events').EventEmitter; | ||
MessageCache = require('../message-cache/message-cache'); | ||
MessageTranslator = require('../message-translator/message-translator'); | ||
WebSocketServer = require('ws').Server; | ||
@@ -9,32 +11,12 @@ debug = require('debug')('exocom:websocket-subsystem'); | ||
var prototype = extend$((import$(WebSocketSubsystem, superclass).displayName = 'WebSocketSubsystem', WebSocketSubsystem), superclass).prototype, constructor = WebSocketSubsystem; | ||
function WebSocketSubsystem(exocom){ | ||
this.exocom = exocom; | ||
this._parseRequest = bind$(this, '_parseRequest', prototype); | ||
function WebSocketSubsystem(arg$){ | ||
this.logger = (arg$ != null | ||
? arg$ | ||
: {}).logger; | ||
this.onConnection = bind$(this, 'onConnection', prototype); | ||
this.messageTranslator = new MessageTranslator; | ||
this.server = null; | ||
this.port = null; | ||
this.serviceSockets = {}; | ||
this.sockets = {}; | ||
} | ||
WebSocketSubsystem.prototype.registerServiceInstance = function(arg$){ | ||
var serviceName, websocket, x$, this$ = this; | ||
serviceName = arg$.serviceName, websocket = arg$.websocket; | ||
x$ = this.serviceSockets[serviceName] = websocket; | ||
x$.on('close', function(){ | ||
this$.exocom.removeRoutingConfig({ | ||
serviceName: serviceName | ||
}); | ||
return this$.deregisterServiceInstance({ | ||
serviceName: serviceName | ||
}); | ||
}); | ||
return x$; | ||
}; | ||
WebSocketSubsystem.prototype.deregisterServiceInstance = function(arg$){ | ||
var serviceName, ref$, ref1$, ref2$; | ||
serviceName = arg$.serviceName; | ||
if ((ref$ = this.serviceSockets[serviceName]) != null) { | ||
ref$.close(); | ||
} | ||
return ref2$ = (ref1$ = this.serviceSockets)[serviceName], delete ref1$[serviceName], ref2$; | ||
}; | ||
WebSocketSubsystem.prototype.close = function(){ | ||
@@ -45,10 +27,17 @@ switch (false) { | ||
} | ||
debug("WebSockets no longer bound at port " + this.port); | ||
debug('websockets going offline'); | ||
return this.server.close(); | ||
}; | ||
WebSocketSubsystem.prototype.listen = function(port, expressServer){ | ||
WebSocketSubsystem.prototype.deregisterClient = function(clientName){ | ||
var ref$, ref1$, ref2$; | ||
if ((ref$ = this.sockets[clientName]) != null) { | ||
ref$.close(); | ||
} | ||
return ref2$ = (ref1$ = this.sockets)[clientName], delete ref1$[clientName], ref2$; | ||
}; | ||
WebSocketSubsystem.prototype.listen = function(port, server){ | ||
var x$, this$ = this; | ||
this.port = port; | ||
x$ = this.server = new WebSocketServer({ | ||
server: expressServer, | ||
server: server, | ||
path: '/services' | ||
@@ -58,6 +47,7 @@ }); | ||
x$.on('listening', function(){ | ||
return this$.emit('websocket-bound', this$.port); | ||
this$.logger.log("ExoCom WebSocket listener online at port " + cyan(port)); | ||
return this$.emit('online', this$.port); | ||
}); | ||
x$.on('error', function(error){ | ||
return this$.emit('error', error); | ||
x$.on('error', function(err){ | ||
return this$.logger.error(err); | ||
}); | ||
@@ -68,123 +58,71 @@ return x$; | ||
var this$ = this; | ||
return websocket.on('message', function(message){ | ||
return this$.onMessage(message, websocket); | ||
return websocket.on('message', function(messageText){ | ||
var message; | ||
message = JSON.parse(messageText); | ||
this$._logReceived(message); | ||
return this$.emit('message', { | ||
message: message, | ||
websocket: websocket | ||
}); | ||
}); | ||
}; | ||
WebSocketSubsystem.prototype.onMessage = function(message, websocket){ | ||
var requestData; | ||
requestData = this._parseRequest(JSON.parse(message)); | ||
this._logReceived(requestData); | ||
switch (false) { | ||
case requestData.name !== 'exocom.register-service': | ||
return this.onRegistrationReceive(requestData.payload, websocket); | ||
case !this.invalidSender(requestData.sender, requestData.name): | ||
return this.emit('error', "Service '" + requestData.sender + "' is not allowed to broadcast the message '" + requestData.name + "'"); | ||
default: | ||
return this.onMessageReceive(requestData); | ||
} | ||
}; | ||
WebSocketSubsystem.prototype.onRegistrationReceive = function(payload, websocket){ | ||
this.exocom.addRoutingConfig(payload, websocket); | ||
return this.registerServiceInstance({ | ||
serviceName: payload.name, | ||
websocket: websocket | ||
WebSocketSubsystem.prototype.registerClient = function(arg$){ | ||
var clientName, websocket, x$, this$ = this; | ||
clientName = arg$.clientName, websocket = arg$.websocket; | ||
x$ = this.sockets[clientName] = websocket; | ||
x$.on('close', function(){ | ||
return this$.emit('deregister-client', clientName); | ||
}); | ||
return x$; | ||
}; | ||
WebSocketSubsystem.prototype.onMessageReceive = function(data){ | ||
var result; | ||
switch (result = this.exocom.sendMessage(data)) { | ||
case 'success': | ||
break; | ||
case 'no receivers': | ||
return this.emit('warn', "No receivers for message '" + data.name + "' registered"); | ||
case 'missing request id': | ||
return this.emit('error', 'missing request id'); | ||
case 'unknown message': | ||
return this.emit('error', "unknown message: '" + requestData.message + "'"); | ||
default: | ||
return this.emit('error', "unknown result code: '" + this.result + "'"); | ||
} | ||
}; | ||
WebSocketSubsystem.prototype.sendToServices = function(messageData, services){ | ||
var i$, len$, service, results$ = []; | ||
for (i$ = 0, len$ = services.length; i$ < len$; ++i$) { | ||
service = services[i$]; | ||
results$.push(this.sendToService(messageData, service)); | ||
} | ||
return results$; | ||
}; | ||
WebSocketSubsystem.prototype.sendToService = function(messageData, service){ | ||
var translatedMessageName, requestData, result, res$, key, value; | ||
translatedMessageName = this._translate(messageData.name, { | ||
WebSocketSubsystem.prototype.sendMessageToService = function(message, service){ | ||
var internalMessageName, requestData, result, res$, key, value; | ||
internalMessageName = this.messageTranslator.internalMessageName(message.name, { | ||
'for': service | ||
}); | ||
requestData = { | ||
name: translatedMessageName, | ||
id: messageData.id, | ||
payload: messageData.payload, | ||
timestamp: messageData.timestamp | ||
name: internalMessageName, | ||
id: message.id, | ||
payload: message.payload, | ||
timestamp: message.timestamp | ||
}; | ||
if (messageData.responseTo) { | ||
requestData.responseTime = messageData.responseTime; | ||
requestData.responseTo = messageData.responseTo; | ||
if (message.responseTo) { | ||
requestData.responseTime = message.responseTime; | ||
requestData.responseTo = message.responseTo; | ||
} | ||
this._logSending(messageData, service); | ||
this.serviceSockets[service.name].send(JSON.stringify(requestData)); | ||
this._logSending(message, service); | ||
this.sockets[service.clientName].send(JSON.stringify(requestData)); | ||
res$ = {}; | ||
for (key in messageData) { | ||
value = messageData[key]; | ||
for (key in message) { | ||
value = message[key]; | ||
res$[key] = value; | ||
} | ||
result = res$; | ||
result.name = translatedMessageName; | ||
result.name = internalMessageName; | ||
return result; | ||
}; | ||
WebSocketSubsystem.prototype._logReceived = function(arg$){ | ||
var name, id, responseTo; | ||
name = arg$.name, id = arg$.id, responseTo = arg$.responseTo; | ||
switch (false) { | ||
case !responseTo: | ||
return debug("received '" + name + "' with id '" + id + "' in response to '" + responseTo + "'"); | ||
default: | ||
return debug("received '" + name + "' with id '" + id + "'"); | ||
WebSocketSubsystem.prototype.sendMessageToServices = function(messageData, services){ | ||
var i$, len$, service, results$ = []; | ||
for (i$ = 0, len$ = services.length; i$ < len$; ++i$) { | ||
service = services[i$]; | ||
results$.push(this.sendMessageToService(messageData, service)); | ||
} | ||
return results$; | ||
}; | ||
WebSocketSubsystem.prototype._logSending = function(arg$, service){ | ||
var name, id, responseTo; | ||
name = arg$.name, id = arg$.id, responseTo = arg$.responseTo; | ||
WebSocketSubsystem.prototype._logReceived = function(message){ | ||
switch (false) { | ||
case !responseTo: | ||
return debug("sending '" + name + "' with id '" + id + "' in response to '" + responseTo + "' to '" + service.name + "'"); | ||
case !message.responseTo: | ||
return debug("received '" + message.name + "' with id '" + message.id + "' in response to '" + message.responseTo + "'"); | ||
default: | ||
return debug("sending '" + name + "' with id '" + id + "' to '" + service.name + "'"); | ||
return debug("received '" + message.name + "' with id '" + message.id + "'"); | ||
} | ||
}; | ||
WebSocketSubsystem.prototype._parseRequest = function(req){ | ||
return { | ||
sender: req.sender, | ||
name: req.name, | ||
payload: req.payload, | ||
responseTo: req.responseTo, | ||
timestamp: req.timestamp, | ||
id: req.id | ||
}; | ||
}; | ||
WebSocketSubsystem.prototype._translate = function(messageName, arg$){ | ||
var service, messageParts; | ||
service = arg$['for']; | ||
messageParts = messageName.split('.'); | ||
WebSocketSubsystem.prototype._logSending = function(message, service){ | ||
switch (false) { | ||
case !!service.internalNamespace: | ||
return messageName; | ||
case messageParts.length !== 1: | ||
return messageName; | ||
case messageParts[0] !== service.internalNamespace: | ||
return messageName; | ||
case !message.responseTo: | ||
return debug("sending '" + message.name + "' with id '" + message.id + "' in response to '" + message.responseTo + "' to '" + service.name + "'"); | ||
default: | ||
return service.internalNamespace + "." + messageParts[1]; | ||
return debug("sending '" + message.name + "' with id '" + message.id + "' to '" + service.name + "'"); | ||
} | ||
}; | ||
WebSocketSubsystem.prototype.invalidSender = function(sender, message){ | ||
return !this.exocom.clientRegistry.canSend(sender, message); | ||
}; | ||
return WebSocketSubsystem; | ||
@@ -191,0 +129,0 @@ }(EventEmitter)); |
{ | ||
"name": "exocom-dev", | ||
"version": "0.15.2", | ||
"version": "0.21.0", | ||
"author": "Kevin Goslar", | ||
"dependencies": { | ||
"body-parser": "1.15.2", | ||
"body-parser": "1.16.0", | ||
"chalk": "1.1.3", | ||
"debug": "2.3.3", | ||
"debug": "2.6.0", | ||
"docopt": "0.6.2", | ||
@@ -13,3 +13,2 @@ "express": "4.14.0", | ||
"nanoseconds": "0.1.0", | ||
"nitroglycerin": "1.1.2", | ||
"rails-delegate": "0.6.2", | ||
@@ -27,3 +26,3 @@ "remove-value": "1.0.0", | ||
"cucumber-snippets-livescript": "1.0.1", | ||
"dependency-lint": "4.3.0", | ||
"dependency-lint": "4.3.1", | ||
"dim-console": "0.4.4", | ||
@@ -35,5 +34,6 @@ "exosphere-shared": "0.9.4", | ||
"mocha-circleci-reporter": "0.0.2", | ||
"nitroglycerin": "1.1.2", | ||
"o-tools": "0.7.0", | ||
"o-tools-livescript": "1.2.3", | ||
"observable-process": "3.2.0", | ||
"observable-process": "3.2.2", | ||
"port-reservation": "0.3.2", | ||
@@ -40,0 +40,0 @@ "prelude-ls": "1.1.2", |
# Exosphere Communication Server | ||
[![Circle CI](https://circleci.com/gh/Originate/exocom-dev.svg?style=shield&circle-token=0f68f90da677a3c5bffc88d9d41910c00f10b81e)](https://circleci.com/gh/Originate/exocom-dev) | ||
[![Dependency Status](https://david-dm.org/originate/exocom-dev.svg)](https://david-dm.org/originate/exocom-dev) | ||
@@ -5,0 +4,0 @@ [![devDependency Status](https://david-dm.org/originate/exocom-dev/dev-status.svg)](https://david-dm.org/originate/exocom-dev#info=devDependencies) |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
12
31784
19
742
29
3
+ Addedbody-parser@1.16.0(transitive)
+ Addeddebug@2.6.0(transitive)
+ Addediconv-lite@0.4.15(transitive)
+ Addedqs@6.2.1(transitive)
+ Addedraw-body@2.2.0(transitive)
- Removednitroglycerin@1.1.2
- Removedbody-parser@1.15.2(transitive)
- Removeddebug@2.3.3(transitive)
- Removediconv-lite@0.4.13(transitive)
- Removednitroglycerin@1.1.2(transitive)
- Removedraw-body@2.1.7(transitive)
Updatedbody-parser@1.16.0
Updateddebug@2.6.0