message-relay-services
Version:
A simple server to route message to other services, such as email, admin, etc.
1,622 lines (1,363 loc) • 47.8 kB
JavaScript
const test = require('ava');
let JSONMessageQueue = require("../json-message-queue")
let path_constuctor = require("../path-handler/path-handler")
let PathHandler = path_constuctor.PathHandler
//
//
let MessageEndpoint = require('../lib/message_endpoint')
let MessageRelay = require('../lib/message_relay')
let MessageRelayClient = require('../lib/message_relay_client');
let RelayCommunicator = MessageRelay.Communicator
const { EventEmitter } = require('events');
//
test('json message queue: create class', t => {
let mod = new JSONMessageQueue(false)
if ( mod ) {
t.is(mod.message_decoder,mod.default_decoder)
return
}
t.fail("no class instance")
})
test('json message queue: default parser is JSON.parse', t => {
let mod = new JSONMessageQueue(false)
if ( mod ) {
let b = mod.message_decoder("this is some junk")
t.is(b,false)
let obj = {
"b" : [ "a", 1, true],
"c" : "q"
}
b = mod.message_decoder(JSON.stringify(obj))
t.is(b.b[0],"a")
return
}
t.fail("no class instance")
})
test('json message queue: add strings ', t => {
let mod = new JSONMessageQueue(false)
if ( mod ) {
let obj_array = [
{ "b" : [ "a", 1, true], "c" : "q" },
{ "b" : [ "g", 3, false], "c" : "r" },
{ "b" : [ "g", 5, true], "c" : "s" }
]
for ( let obj of obj_array ) {
let obj_str = JSON.stringify(obj)
let buf = Buffer.from(obj_str)
mod.add_data(buf)
}
t.is(mod.last_message,`{"b":["a",1,true],"c":"q"}{"b":["g",3,false],"c":"r"}{"b":["g",5,true],"c":"s"}`)
t.pass("to string")
return
}
t.fail("no class instance")
})
test('json message queue: message complete ', t => {
let mod = new JSONMessageQueue(false)
if ( mod ) {
let obj_array = [
{ "b" : [ "a", 1, true], "c" : "q" },
{ "b" : [ "g", 3, false], "c" : "r" },
{ "b" : [ "g", 5, true], "c" : "s" }
]
let sep = ""
for ( let obj of obj_array ) {
let obj_str = JSON.stringify(obj) + sep
sep += " "
let buf = Buffer.from(obj_str)
mod.add_data(buf)
}
let rest = mod.message_complete()
t.is(rest,undefined)
t.is(mod.last_message,"")
t.is(mod.message_queue.length,3)
rest = mod.message_complete()
t.is(rest,undefined)
t.is(mod.last_message,"")
t.is(mod.message_queue.length,3)
//
for ( let obj of obj_array ) {
let obj_str = JSON.stringify(obj) + sep
sep += " "
let buf = Buffer.from(obj_str)
mod.add_data(buf)
}
let buf = Buffer.from(`{ "b" : [ "g", 5, true`)
mod.add_data(buf)
//
mod.message_complete()
t.is(mod.last_message,`{ "b" : [ "g", 5, true`)
t.is(mod.message_queue.length,6)
buf = Buffer.from(`], "c" : "s" }`)
mod.add_data(buf)
buf = Buffer.from(`{ "b" : [ "g", 3, false], "c" : "r" }`)
mod.add_data(buf)
mod.message_complete()
t.is(mod.message_queue.length,8)
t.is(mod.last_message,"")
return
}
t.fail("no class instance")
})
test('json message queue: dequeue message complete ', t => {
let mod = new JSONMessageQueue(false)
if ( mod ) {
let obj_array = [
{ "b" : [ "e", 1, true], "c" : "q" },
{ "b" : [ "f", 3, false], "c" : "r" },
{ "b" : [ "g", 5, true], "c" : "s" }
]
let sep = ""
for ( let obj of obj_array ) {
let obj_str = JSON.stringify(obj) + sep
sep += " "
let buf = Buffer.from(obj_str)
mod.add_data(buf)
}
let rest = mod.message_complete()
t.is(rest,undefined)
t.is(mod.last_message,"")
t.is(mod.message_queue.length,3)
let obj = mod.dequeue()
t.is(obj.b[0],"e")
t.is(mod.message_queue.length,2)
obj = mod.dequeue()
t.is(obj.b[0],"f")
t.is(mod.message_queue.length,1)
obj = mod.dequeue()
t.is(obj.b[0],"g")
t.is(mod.message_queue.length,0)
return
}
t.fail("no class instance")
})
// */
let T_test_message_lookup = {
}
class TestRelayClass {
constructor(conf) {
this.test_parameters = conf.test_parameters
this.subcriptions = {}
}
send_on_path(message,path) {
message._m_path = path
T_test_message_lookup[message._test_lookup] = message
return message
}
send_op_on_path(message,path,op) {
message._m_path = path
message._tx_op = op
T_test_message_lookup[message._test_lookup] = message
return message
}
subscribe(topic,path,msg,handler) {
msg._ps_op = "sub"
msg.topic = topic
msg._m_path = path
this.subcriptions[`update-${topic}-${path}`] = handler
}
unsubscribe(topic,path) {
let handler = this.subcriptions[`update-${topic}-${path}`]
delete this.subcriptions[`update-${topic}-${path}`]
this.removeListener(`update-${topic}-${path}`,handler)
let message = {
"_ps_op" : "unsub",
"topic" : topic
}
message._m_path = path
return message
}
removeListener(tag,handler) {
}
}
test('PathHandler - create', async t => {
//
let pconf = {
"relay" : {
"test_parameters" : {
}
}
}
//
let p_handler = new PathHandler('tests',pconf,TestRelayClass)
//
t.is(p_handler.message_relayer.constructor.name,"TestRelayClass")
// SEND
let resp = await p_handler.send({ "text" : "a", "name" : "this is me" }) // must use await...
t.is(resp.name,"this is me")
t.is(resp._m_path,'tests')
// GET
resp = await p_handler.get({ "text" : "a", "name" : "this is me" }) // must use await...
t.is(resp.name,"this is me")
t.is(resp._m_path,'tests')
t.is(resp._tx_op,'G')
// DEL
resp = await p_handler.del({ "text" : "a", "name" : "this is me" }) // must use await...
t.is(resp.name,"this is me")
t.is(resp._m_path,'tests')
t.is(resp._tx_op,'D')
let msg = {
"name" : "SUB TEST"
}
let topic = "SUB-TEST"
let path = p_handler.path
let handler = 42
await p_handler.subscribe("SUB-TEST",msg,handler)
t.is(msg.name,"SUB TEST")
t.is(msg.topic,"SUB-TEST")
t.is(msg._m_path,'tests')
t.is(msg._ps_op,'sub')
t.is(p_handler.topic_listeners["SUB-TEST"][0],handler)
//
msg = {
"name" : "SUB TEST"
}
resp = await p_handler.unsubscribe("SUB-TEST")
t.is(resp.topic,"SUB-TEST")
t.is(resp._m_path,'tests')
t.is(resp.topic,"SUB-TEST")
t.is(resp._ps_op,'unsub')
t.is(p_handler.topic_listeners["SUB-TEST"],undefined)
//
let expected_keys = {
"user" : "UserHandler",
"persistence" : "PersistenceHandler",
"outgo_email" : "OutgoingEmailHandler",
"contact" : "ContactHandler",
"notify" : "NotificationHandler"
}
//
for ( let classky in path_constuctor.classes ) {
if ( classky in expected_keys ) {
t.is(path_constuctor.classes[classky].name,expected_keys[classky])
}
}
let path_handler = path_constuctor("user",pconf,TestRelayClass)
t.is(path_handler.path,"user")
t.is(path_handler.message_relayer.constructor.name,"TestRelayClass")
let deleted = path_handler.del({})
t.is(deleted,"none")
// path,path_conf,FanoutRelayerClass
//
t.pass("used path handler class")
})
test("Message Endpoint - functional", async t => {
class TestClass extends MessageEndpoint {
constructor(conf) {
super(conf)
}
_init() {
// do nothing...
}
app_message_handler(msg_obj) {
return msg_obj
}
app_subscription_handler(topic,msg_obj) {
}
}
let call_results = {}
class testSock {
constructor(name) {
this.readyState = "open"
this.test_name = name
}
write(msg) {
call_results[this.test_name] = JSON.parse(msg)
}
end() {}
}
let conf = {
"port" : 500,
"address" : "my address",
"app_handles_subscriptions" : true
}
let inert = new TestClass(conf)
let all_socks = []
for ( let i = 0; i < 10; i++ ) {
let client_name = `ACLIENT_${i}`
let sock = new testSock(client_name)
inert.add_connection(client_name,sock)
all_socks.push(sock)
}
for ( let i = 0; i < 10; i++ ) {
let msg = {
"name" : "SUB TEST",
"_response_id" : i
}
let client_name = `ACLIENT_${i}`
try {
let data = Buffer.from(JSON.stringify(msg))
await inert.add_data_and_react(client_name,data)
} catch (e) {
console.error(e)
}
}
for ( let i = 0; i < 10; i++ ) {
let client_name = `ACLIENT_${i}`
t.is(call_results[client_name]._response_id,i)
}
// _ps_op
for ( let i = 0; i < 10; i++ ) {
let msg = {
"name" : "SUB TEST",
"_ps_op" : "sub",
"_response_id" : i,
"topic" : "test"
}
let client_name = `ACLIENT_${i}`
try {
let data = Buffer.from(JSON.stringify(msg))
await inert.add_data_and_react(client_name,data)
} catch (e) {
console.error(e)
}
}
let t_set = inert.all_topics["test"]
t.is(typeof t_set,"object")
for ( let ty in t_set ) {
t.is(t_set[ty].constructor.name,"Replier")
}
let i = 5
let client_name = `ACLIENT_${i}`
let msg = {
"name" : "SUB TEST",
"_ps_op" : "pub",
"_response_id" : i,
"topic" : "test"
}
try {
let data = Buffer.from(JSON.stringify(msg))
await inert.add_data_and_react(client_name,data)
} catch (e) {
console.error(e)
}
for ( let i = 0; i < 10; i++ ) {
let client_name = `ACLIENT_${i}`
if ( i !== 5 ) {
t.is(call_results[client_name]._response_id,undefined)
t.is(call_results[client_name].name,"SUB TEST")
t.is(call_results[client_name].topic,"test")
} else {
t.is(call_results[client_name]._response_id,5)
}
}
let j = 5
let un_client_name = `ACLIENT_${j}`
let msg_un = {
"name" : "SUB TEST",
"_ps_op" : "unsub",
"_response_id" : j,
"topic" : "test"
}
try {
let data = Buffer.from(JSON.stringify(msg_un))
await inert.add_data_and_react(un_client_name,data)
} catch (e) {
console.error(e)
}
let un_t_set = inert.all_topics["test"]
t.is(typeof t_set,"object")
for ( let ty in un_t_set ) {
t.true(ty !== 'ACLIENT_5')
}
t.pass("end point without crash")
})
// * /
// ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
test("message_relay service", async t => {
//
let call_results = {}
class testSock {
constructor(name) {
this.readyState = "open"
this.test_name = name
this.remoteAddress = "wiggly"
this.remotePort = "pigly"
}
write(msg) {
call_results[this.test_name] = JSON.parse(msg)
}
end() {}
}
// ---- ---- ---- ---- ---- ---- ----
class test_Relay extends MessageRelay {
constructor(conf,fanoutRelayer) {
super(conf,fanoutRelayer)
}
_init() {
}
}
let conf = {
"port" : "wine",
"address" : "101 home st",
"tls" : undefined,
"path_types" : {
"winding" : {
"relay" : {
"files_only" : false,
"output_dir" : "fail_over_user",
"output_file" : "/user_data.json",
"port" : 5114,
"address" : "localhost",
"max_pending_messages" : false,
"file_shunting" : false,
"max_reconnect" : 24,
"reconnect_wait" : 5,
"attempt_reconnect" : true
}
}
},
"path_handler_factory" : __dirname + "/helpers/faux_paths"
}
let sock = new testSock("wiggly-pigly")
let relay_class_obj = new test_Relay(conf,TestRelayClass)
relay_class_obj.add_connection(sock.test_name,sock)
//
//
let path = Object.keys(relay_class_obj.message_paths)[0]
t.is(path,"winding")
//
let m_handler = relay_class_obj.messenger_connections['wiggly-pigly']
let message = {
"_m_path" : path,
"data" : "this is a test",
"_response_id" : 23,
"_test_lookup" : "A"
}
let data = Buffer.from(JSON.stringify(message))
await m_handler.data_handler(data)
//
t.is(T_test_message_lookup[message._test_lookup]._response_id,23)
t.is(call_results[sock.test_name].msg.data,"this is a test")
//
message = {
"_m_path" : path,
"_tx_op" : "G",
"data" : "this is a test",
"_response_id" : 24,
"_test_lookup" : "B"
}
data = Buffer.from(JSON.stringify(message))
await m_handler.data_handler(data)
//
t.is(T_test_message_lookup[message._test_lookup]._response_id,24)
t.is(call_results[sock.test_name].msg.data,"this is a test")
//
message = {
"_m_path" : path,
"_tx_op" : "D",
"data" : "this was a test",
"_response_id" : 25,
"_test_lookup" : "C"
}
data = Buffer.from(JSON.stringify(message))
await m_handler.data_handler(data)
//
t.is(T_test_message_lookup[message._test_lookup]._response_id,25)
t.is(call_results[sock.test_name].msg.data,"this was a test")
//
message = {
"_m_path" : path,
"_tx_op" : "S",
"_ps_op" : "sub",
"data" : "this was a test",
"_response_id" : 25,
"_test_lookup" : "C"
}
data = Buffer.from(JSON.stringify(message))
await m_handler.data_handler(data)
//
message = {
"_m_path" : path,
"_tx_op" : "S",
"_ps_op" : "unsub",
"data" : "this was a test",
"_response_id" : 25,
"_test_lookup" : "C"
}
data = Buffer.from(JSON.stringify(message))
await m_handler.data_handler(data)
//
t.pass("framework OK")
})
test("MessageRelayClient", async t => {
let call_results = {}
class testSock extends EventEmitter {
constructor(name) {
super()
this.readyState = "open"
this.test_name = name
this.remoteAddress = "wiggly"
this.remotePort = "pigly"
}
write(msg) {
console.log(msg)
call_results[this.test_name] = JSON.parse(msg)
}
end() {}
}
class test_RC extends MessageRelayClient {
constructor(conf) {
super(conf)
this.socket = new testSock("wiggly-pigly")
this.writer = this.socket
}
//
_connect() {}
_setup_connection_handlers(client,conf) {}
}
let conf = {
"port" : "wine",
"address" : "211 memoryville",
"send_on_reconnect" : true,
"tls" : undefined,
"files_only" : false,
"shunt_file" : "message_relay.txt",
"file_shunting" : true,
"file_per_message" : false,
"attempt_reconnect" : false
}
let relayer = new test_RC(conf)
let message = {
"you" : "are",
"here" : true
}
let p = relayer.send_on_path(message,"twisty")
let resp_id = call_results["wiggly-pigly"]._response_id
message = {
"_response_id" : resp_id
}
let p2 = new Promise((resolve,reject) => {
setImmediate(() => {
let data = Buffer.from(JSON.stringify(message))
relayer.client_add_data_and_react(data)
resolve(true)
})
})
await p2
await p
t.pass("client class OK")
})
// * /
test("MessageRelayClient - files", async t => {
let call_results = {}
class testSock extends EventEmitter {
constructor(name) {
super()
this.readyState = "open"
this.test_name = name
this.remoteAddress = "wiggly"
this.remotePort = "pigly"
}
write(msg) {
console.log("testSock." + "write ..." + msg)
call_results[this.test_name] = JSON.parse(msg)
this.emit('test-call-results-ok')
}
end() {}
}
class test_RC extends MessageRelayClient {
constructor(conf) {
super(conf)
this.socket = new testSock("wiggly-pigly")
this.writer = this.socket
}
//
_connect() {}
_setup_connection_handlers(client,conf) {}
}
let conf = {
"port" : "wine",
"address" : "211 memoryville",
"send_on_reconnect" : true,
"tls" : undefined,
"files_only" : false,
"shunt_file" : "message_relay.txt",
"output_dir" : __dirname + "/messages",
"file_shunting" : true,
"ensure_directories" : true,
"file_per_message" : false,
"attempt_reconnect" : false
}
let relayer = new test_RC(conf)
await relayer._start_file_shunting(conf)
let hold_promises = []
relayer.socket.on('test-call-results-ok',async () => {
await relayer._shutdown_files_going(hold_promises,true)
let resp_id = call_results["wiggly-pigly"]._response_id
message = {
"_response_id" : resp_id
}
})
let message = {
"you" : "are 2",
"here" : true
}
await relayer.send_on_path(message,"twisty")
let p2 = new Promise((resolve,reject) => {
setImmediate(() => {
let data = Buffer.from(JSON.stringify(message))
relayer.client_add_data_and_react(data)
resolve(true)
})
})
await p2
console.dir(hold_promises)
await Promise.all(hold_promises)
t.pass("client class OK")
})
test('PathHandler - pub/sub', async t => {
let call_results = {}
class testSock extends EventEmitter {
constructor(name) {
super()
this.readyState = "open"
this.test_name = name
this.remoteAddress = "wiggly"
this.remotePort = "pigly"
}
write(msg) {
console.log("testSock." + "write ..." + msg)
let mm = JSON.parse(msg)
let a_topic = mm.topic
if ( call_results[a_topic] === undefined ) {
call_results[a_topic] = {}
console.log("strange topic: " + a_topic)
}
call_results[a_topic][this.test_name] = mm
}
end() {}
}
class test_RC extends MessageRelayClient {
constructor(conf) {
super(conf)
this.socket = new testSock("wiggly-pigly")
this.writer = this.socket
}
//
_connect() {}
_setup_connection_handlers(client,conf) {}
}
//
let pconf = {
"relay" : {
"test_parameters" : {
}
}
}
//
let p_handler = new PathHandler('tests',pconf,test_RC)
t.is(p_handler.message_relayer.constructor.name,"test_RC")
//
// make an array of writers
let writer_names = [ "A", "B", "C", "D", "E", "F", "G", "H", "I"]
let all_writers = writer_names.map(w_name => {
return new testSock(w_name)
})
let topics = ["SUB-TEST1", "SUB-TEST2"]
let listeners = {"SUB-TEST1" : [], "SUB-TEST2" : []}
for ( let topic of topics ) {
//
let msg = {
"name" : topic
}
//
all_writers.forEach ( async a_writer => {
let listener = ((wrtr,tt) => { // forward publication to the client (this socket)
return (msg) => {
msg.topic = tt
let forwarded = JSON.stringify(msg)
//wrtr.write(forwarded)
return wrtr.test_name
}
}
)(a_writer,topic)
listeners[topic][a_writer.test_name] = listener // for a generic cleanup
await p_handler.subscribe(topic,msg,listener)
//
t.is(msg.name,topic)
t.is(msg.topic,topic)
t.is(msg._m_path,'tests')
t.is(msg._ps_op,'sub')
})
//
}
for ( let topic of topics ) {
let listens = p_handler.topic_listeners[topic]
for ( let i = 0; i < listens.length; i++ ) {
let msg = {
"name" : topic
}
let w_name = writer_names[i]
let listener = p_handler.topic_listeners[topic][i]
let tst_name = listener(msg)
t.is(w_name,tst_name)
}
}
for ( let topic of topics ) {
//
all_writers.forEach ( async a_writer => {
let listener = listeners[topic][a_writer.test_name] // for a generic cleanup
await p_handler.unsubscribe(topic,listener)
})
//
}
for ( let topic of topics ) {
// initialize here
call_results[topic] = {}
//
let msg = {
"name" : topic
}
//
all_writers.forEach ( async a_writer => {
let listener = ((wrtr,tt) => { // forward publication to the client (this socket)
return (msg) => {
msg.topic = tt
let forwarded = JSON.stringify(msg)
wrtr.write(forwarded)
}
}
)(a_writer,topic)
listeners[topic][a_writer.test_name] = listener // for a generic cleanup
await p_handler.subscribe(topic,msg,listener)
//
t.is(msg.name,topic)
t.is(msg.topic,topic)
t.is(msg._m_path,'tests')
t.is(msg._ps_op,'sub')
})
//
}
for ( let a_topic of topics ) {
let P_msg = {
"topic" : a_topic,
"_m_path" : 'tests'
}
let topic = P_msg.topic
let path = P_msg._m_path
p_handler.message_relayer.emit(`update-${topic}-${path}`,P_msg)
}
let p = new Promise((resolve,reject) => {
setTimeout(() => {
resolve(call_results)
},5)
})
let final_results = await p;
console.dir(final_results)
for ( let test_topic of topics ) {
t.is(final_results[test_topic]["B"].topic,test_topic)
t.is(final_results[test_topic]["D"]._m_path,"tests")
}
// path,path_conf,FanoutRelayerClass
//
t.pass("used path handler class")
})
test('Relay - pub/sub', async t => {
let call_results = {}
class testSock extends EventEmitter {
constructor(name) {
super()
this.readyState = "open"
this.test_name = name
this.remoteAddress = "wiggly"
this.remotePort = "pigly"
}
write(msg) {
console.log("testSock." + "write ..." + msg)
let mm = JSON.parse(msg)
let a_topic = mm.topic
if ( call_results[a_topic] === undefined ) {
call_results[a_topic] = {}
console.log("strange topic: " + a_topic)
}
call_results[a_topic][this.test_name] = mm
}
end() {}
}
class test_RC extends MessageRelayClient {
constructor(conf) {
super(conf)
this.socket = new testSock("wiggly-pigly")
this.writer = this.socket
}
//
_connect() {}
_setup_connection_handlers(client,conf) {}
}
class test_RelayCommunicator extends RelayCommunicator {
//
constructor(conf) {
super(conf,test_RC)
this.socket = new testSock("wiggly-pigly")
this.writer = this.socket
}
_init() {
// what goes here? for a test
}
}
let path_handler_factory = (path,path_conf,FanoutRelayerClass) => {
//
let pc = new PathHandler(path,path_conf,FanoutRelayerClass)
return pc
}
let conf = {
"path_types" : {
"test" : {
"relay" :{
"files_only" : false,
"output_dir" : "fail_over_user",
"output_file" : "/user_data.json",
"port" : 5114,
"address" : "localhost",
"max_pending_messages" : false,
"file_shunting" : false,
"max_reconnect" : 24,
"reconnect_wait" : 5,
"attempt_reconnect" : false
}
},
"best" : {
"relay" : {
"files_only" : false,
"output_dir" : "fail_over_user",
"output_file" : "/user_data.json",
"port" : 5116,
"address" : "localhost",
"max_pending_messages" : false,
"file_shunting" : false,
"max_reconnect" : 24,
"reconnect_wait" : 5,
"attempt_reconnect" : false
}
},
"jest" : {
"relay" : {
"files_only" : false,
"output_dir" : "fail_over_user",
"output_file" : "/user_data.json",
"port" : 5118,
"address" : "localhost",
"max_pending_messages" : false,
"file_shunting" : false,
"max_reconnect" : 24,
"reconnect_wait" : 5,
"attempt_reconnect" : false
}
}
},
"path_handler_factory" : path_handler_factory
}
let test_rc = new test_RelayCommunicator(conf)
t.is(Object.keys(test_rc.message_paths).length,3)
for ( let path in test_rc.message_paths ) {
let p_handler = test_rc.message_paths[path]
t.is(p_handler.path,path)
t.is(p_handler.message_relayer.constructor.name, "test_RC")
t.is(p_handler.message_relayer.writer.constructor.name, "testSock")
}
let subscription_results = {}
class subSock extends testSock {
constructor(name) {
super(name)
this.remoteAddress = "humpdee"
this.remotePort = "dumpdee"
}
write(msg) {
console.log("testSock." + "write ..." + msg)
let mm = JSON.parse(msg)
let a_topic = mm.topic
if ( subscription_results[a_topic] === undefined ) {
subscription_results[a_topic] = {}
console.log("strange topic: " + a_topic)
}
subscription_results[a_topic][this.test_name] = mm
}
end() {}
}
let all_socks = []
for ( let i = 0; i < 10; i++ ) {
let client_name = `ACLIENT_${i}`
let sock = new subSock(client_name)
test_rc.add_connection(client_name,sock)
all_socks.push(sock)
}
let topics = ["SUB-TEST1", "SUB-TEST2"]
for ( let sock of all_socks ) {
let name = sock.test_name
for ( let topic of topics ) {
for ( let path in test_rc.message_paths ) {
let sub_message = {
"topic" : topic,
"_m_path" : path,
"_ps_op" : 'sub'
}
let sub_message_bytes = Buffer.from(JSON.stringify(sub_message))
test_rc.add_data_and_react(name,sub_message_bytes)
}
}
}
//
console.dir(test_rc.messenger_connections)
for ( let path in test_rc.message_paths ) {
let mpath = test_rc.message_paths[path]
t.is(mpath.path,path)
let subs = mpath.message_relayer.subcriptions
for ( let topic of topics ) {
let ev_name = `update-${topic}-${path}`
t.true(ev_name in subs)
//
let m_relayer = mpath.message_relayer
let pub_message = {
"topic" : topic,
"_m_path" : path,
"message" : "have a nice day"
}
let publish_buffer = Buffer.from(JSON.stringify(pub_message))
m_relayer.client_add_data_and_react(publish_buffer)
//
}
}
setImmediate(() => {
console.dir(subscription_results)
},1000)
t.pass("link relay to path handler to message-relay-client")
})
test('Connecting class intialization', async t => {
class test_EndPoint extends MessageEndpoint {
constructor(conf) {
super(conf)
}
/**
*
* @returns {object}
*/
_load_tls_keys() {
//
let base = process.cwd()
//
// allow exceptions to be thrown
if ( this.tls_conf ) {
// //
// let server_key = false
// if ( this.tls_conf.preloaded && this.tls_conf.preloaded.server_key ) {
// server_key = this.tls_conf.preloaded.server_key
// } else {
// server_key = fs.readFileSync(`${base}/${this.tls_conf.server_key}`)
// }
// //
// let server_cert = false
// if ( this.tls_conf.preloaded && this.tls_conf.preloaded.server_cert ) {
// server_cert = this.tls_conf.preloaded.server_cert
// } else {
// server_cert = fs.readFileSync(`${base}/${this.tls_conf.server_cert}`)
// }
// //
// let client_cert = false
// if ( this.tls_conf.preloaded && this.tls_conf.preloaded.client_cert ) {
// client_cert = this.tls_conf.preloaded.client_cert
// } else {
// client_cert = fs.readFileSync(`${base}/${this.tls_conf.client_cert}`)
// }
let tls_options = {
key: "server_key",
cert: "client_cert",
requestCert: true,
ca: [ "client_cert" ]
};
return tls_options
}
//
return false
}
/**
*
*/
_create_connection() {
if ( (this.UDS_path !== undefined) || (this.uds_path_count == 0) ) {
if ( !(this.use_tls) ) {
//this.connection = net.createServer((sock) => { this.onClientConnected_func(sock) })
} else {
if ( this.default_tls ) {
//this.connection = tls.createServer((sock) => { this.onClientConnected_func(sock) });
} else {
const options = this.preloaded_tls_keys;
if ( this.extended_tls_options !== false ) {
options = Object.assign({},options,this.extended_tls_options)
}
//this.connection = tls.createServer(options,((sock) => { this.onClientConnected_func(sock) }));
}
}
} else {
for ( let i = 0; i < this.uds_path_count; i++ ) {
let uds_path = `${this.UDS_path}-$[i]`
if ( !(this.use_tls) ) {
//this.connection = net.createServer((sock) => { this.onClientConnected_func(sock,uds_path) })
} else {
if ( this.default_tls ) {
//this.connection = tls.createServer((sock) => { this.onClientConnected_func(sock,uds_path) });
} else {
const options = this.preloaded_tls_keys;
if ( this.extended_tls_options !== false ) {
options = Object.assign({},options,this.extended_tls_options)
}
//this.connection = tls.createServer(options,((sock) => { this.onClientConnected_func(sock,uds_path) }));
}
}
}
this.uds_server_list[uds_path] = this.connection
}
// UDS
if ( this.UDS_path !== undefined ) {
if ( this.uds_path_count == 0 ) {
// this.connection.listen({ 'path' : this.UDS_path }, () => {
// console.log(`Server started at: ${this.UDS_path}`);
// });
} else {
for ( let i = 0; i < this.uds_path_count; i++ ) {
let uds_path = `${this.UDS_path}-$[i]`
let connection = this.uds_server_list[uds_path]
// connection.listen({ 'path' : uds_path }, () => {
// console.log(`Server started at: ${uds_path}`);
// });
}
}
} else {
// this.connection.listen(this.port, this.address, () => {
// console.log(`Server started at: ${this.address}:${this.port}`);
// });
}
}
_create_connection() {
if ( !(this.use_tls) ) {
//this.connection = net.createServer((sock) => { this.onClientConnected_func(sock) })
} else {
this.options = {
key: (typeof this.tls_conf.server_key === "string"), // fs.readFileSync(this.tls_conf.server_key),
cert: (typeof this.tls_conf.server_cert === "string"), // fs.readFileSync(this.tls_conf.server_cert),
requestCert: true, // using client certificate authentication
ca: [ (typeof this.tls_conf.client_cert === "string") ] // fs.readFileSync(this.tls_conf.client_cert) client uses a self-signed certificate
};
//this.connection = tls.createServer(options,((sock) => { this.onClientConnected_func(sock) }));
}
/*
this.connection.listen(this.port, this.address, () => {
console.log(`Server started at: ${this.address}:${this.port}`);
});
*/
}
}
class test_MessageRelay extends MessageRelay {
constructor(conf) {
super(conf)
}
/**
*
* @returns {object}
*/
_load_tls_keys() {
//
let base = process.cwd()
//
// allow exceptions to be thrown
if ( this.tls_conf ) {
// //
// let server_key = false
// if ( this.tls_conf.preloaded && this.tls_conf.preloaded.server_key ) {
// server_key = this.tls_conf.preloaded.server_key
// } else {
// server_key = fs.readFileSync(`${base}/${this.tls_conf.server_key}`)
// }
// //
// let server_cert = false
// if ( this.tls_conf.preloaded && this.tls_conf.preloaded.server_cert ) {
// server_cert = this.tls_conf.preloaded.server_cert
// } else {
// server_cert = fs.readFileSync(`${base}/${this.tls_conf.server_cert}`)
// }
// //
// let client_cert = false
// if ( this.tls_conf.preloaded && this.tls_conf.preloaded.client_cert ) {
// client_cert = this.tls_conf.preloaded.client_cert
// } else {
// client_cert = fs.readFileSync(`${base}/${this.tls_conf.client_cert}`)
// }
let tls_options = {
key: "server_key",
cert: "client_cert",
requestCert: true,
ca: [ "client_cert" ]
};
return tls_options
}
//
return false
}
_create_connection() {
if ( !(this.use_tls) ) {
this.net_con = "simples server" // net.createServer(this.onClientConnected_func);
} else {
this.options = {
key: (typeof this.tls_conf.server_key === "string"), // fs.readFileSync(this.tls_conf.server_key),
cert: (typeof this.tls_conf.server_cert === "string"), // fs.readFileSync(this.tls_conf.server_cert),
requestCert: true, // using client certificate authentication
ca: [ (typeof this.tls_conf.client_cert === "string") ] // fs.readFileSync(this.tls_conf.client_cert) client uses a self-signed certificate
};
this.net_con = "tls server"
//this.net_con = tls.createServer(options,this.onClientConnected_func);
}
//
/*
if ( this.net_con ) {
this.net_con.listen(this.port, this.address, () => {
console.log(`Server started at: ${this.address}:${this.port}`);
});
}
*/
}
}
class test_MessageRelayClient extends MessageRelayClient {
constructor(conf) {
super(conf)
}
_setup_connection_handlers(client,conf) {}
/**
*
* @returns {object} - tls options use in the call to `connect`
*/
_load_tls_keys() {
//
let base = process.cwd()
//
// allow exceptions to be thrown
if ( this.tls_conf ) {
// //
// let client_key = false
// if ( this.tls_conf.preloaded && this.tls_conf.preloaded.client_key ) {
// client_key = this.tls_conf.preloaded.client_key
// } else {
// client_key = fs.readFileSync(`${base}/${this.tls_conf.client_key}`)
// }
// //
// let client_cert = false
// if ( this.tls_conf.preloaded && this.tls_conf.preloaded.client_cert ) {
// client_cert = this.tls_conf.preloaded.client_cert
// } else {
// client_cert = fs.readFileSync(`${base}/${this.tls_conf.client_cert}`)
// }
// //
// let server_cert = false
// if ( this.tls_conf.preloaded && this.tls_conf.preloaded.server_cert ) {
// server_cert = this.tls_conf.preloaded.server_cert
// } else {
// if ( Array.isArray(this.tls_conf.server_cert) ) {
// server_cert = []
// for ( let cert_file of this.tls_conf.server_cert ) {
// let one_cert = fs.readFileSync(`${base}/${cert_file}`)
// server_cert.push(one_cert)
// }
// } else {
// server_cert = fs.readFileSync(`${base}/${this.tls_conf.server_cert}`)
// }
// }
let server_cert = false
let tls_options = {
// Necessary only if the server requires client certificate authentication.
key: "client_key",
cert: "client_cert",
// Necessary only if the server uses a self-signed certificate.
ca: Array.isArray(server_cert) ? server_cert : [ "server_cert" ],
// Necessary only if the server's cert isn't for "localhost".
checkServerIdentity: () => { return null; },
};
return tls_options
}
//
return false
}
_create_connection() {
if ( !(this.use_tls) ) {
this.net_con = "simples server" // net.createServer(this.onClientConnected_func);
} else {
this.options = {
key: (typeof this.tls_conf.server_key === "string"), // fs.readFileSync(this.tls_conf.server_key),
cert: (typeof this.tls_conf.server_cert === "string"), // fs.readFileSync(this.tls_conf.server_cert),
requestCert: true, // using client certificate authentication
ca: [ (typeof this.tls_conf.client_cert === "string") ] // fs.readFileSync(this.tls_conf.client_cert) client uses a self-signed certificate
};
this.net_con = "tls server"
//this.net_con = tls.createServer(options,this.onClientConnected_func);
}
//
/*
if ( this.net_con ) {
this.net_con.listen(this.port, this.address, () => {
console.log(`Server started at: ${this.address}:${this.port}`);
});
}
*/
}
}
let endpoint = new test_EndPoint({
app_handles_subscriptions : true,
port : 5111,
address : "192.168.1.1",
tls : false
})
t.is(endpoint.port,5111)
t.is(endpoint.options,undefined)
t.is(endpoint.use_tls,false)
let endpoint_tls = new test_EndPoint({
app_handles_subscriptions : true,
port : 5111,
address : "192.168.1.1",
tls : {
server_key : "A file name",
server_cert : "A file name",
client_cert : "A file name"
}
})
t.is(endpoint_tls.port,5111)
t.is(endpoint_tls.options.key,true)
t.is(endpoint_tls.options.cert,true)
t.is(endpoint_tls.options.ca[0],true)
t.is(endpoint_tls.tls_conf.server_key,"A file name")
t.is(endpoint_tls.tls_conf.server_cert,"A file name")
t.is(endpoint_tls.tls_conf.client_cert,"A file name")
t.is(endpoint_tls.use_tls,true)
// RELAY
let relay = new test_MessageRelay({
app_handles_subscriptions : true,
port : 5111,
address : "192.168.1.1",
tls : false,
"path_types" : {
"winding" : {
"relay" : {
"junk" : "junk"
}
}
},
"path_handler_factory" : (a_path,conf,anythinv) => {
return a_path + " from path_handler_factory"
}
})
t.is(relay.port,5111)
t.is(relay.options,undefined)
t.is(relay.use_tls,false)
let relay_tls = new test_MessageRelay({
port : 5111,
address : "192.168.1.1",
tls : {
server_key : "A file name",
server_cert : "A file name",
client_cert : "A file name"
},
"path_types" : {
"winding" : {
"relay" : {
"junk" : "junk"
}
}
},
"path_handler_factory" : (a_path,conf,anythinv) => {
return a_path + " from path_handler_factory"
}
})
t.is(relay_tls.port,5111)
t.is(relay_tls.options.key,true)
t.is(relay_tls.options.cert,true)
t.is(relay_tls.options.ca[0],true)
t.is(relay_tls.tls_conf.server_key,"A file name")
t.is(relay_tls.tls_conf.server_cert,"A file name")
t.is(relay_tls.tls_conf.client_cert,"A file name")
t.is(relay_tls.use_tls,true)
let mrc = new test_MessageRelayClient({
attempt_reconnect : false,
port : 5111,
address : "192.168.1.1",
tls : false
})
t.is(mrc.port,5111)
t.is(mrc.options,undefined)
t.is(mrc.use_tls,false)
let mrc_tls = new test_MessageRelayClient({
attempt_reconnect : false,
port : 5111,
address : "192.168.1.1",
tls : {
server_key : "A file name",
server_cert : "A file name",
client_cert : "A file name"
}
})
t.is(mrc_tls.port,5111)
t.is(mrc_tls.options.key,true)
t.is(mrc_tls.options.cert,true)
t.is(mrc_tls.options.ca[0],true)
t.is(mrc_tls.tls_conf.server_key,"A file name")
t.is(mrc_tls.tls_conf.server_cert,"A file name")
t.is(mrc_tls.tls_conf.client_cert,"A file name")
t.is(mrc_tls.use_tls,true)
})
test('Message via Unix domain sockets -- configuration special', async t => {
class UDSEndpoint extends MessageEndpoint {
constructor(conf) {
super(conf)
}
app_message_handler(msg_obj) {
console.log("UDS ENDPOINT!!")
console.dir(msg_obj)
return({ "status" : "OK" })
}
}
class UDSMEssenger extends MessageRelayClient {
constructor(conf) {
console.log("BEFORE MessageRelayClient CONSCTRUCTOR")
super(conf)
console.log("UDS MESSENGR CONSCTRUCTOR")
}
}
let test_path = `${__dirname}/my_test_pipe`
let conf = {
"uds_path" : test_path,
"uds_path_count" : 0
}
let epoint = new UDSEndpoint(conf)
let p = new Promise((resolve,reject) => {
epoint.on('SERVER-READY_test',async () => {
console.log("RECEIVED SERVER READY")
let messngr = new UDSMEssenger(conf)
messngr.on('client-ready',async (pipe,should_be_UDS) => {
//
console.log(`CAN SEND MESSAGES ON ${should_be_UDS} pipe ${pipe}`)
//
console.log("Sending messages UDS TEST")
//
await messngr.send_op_on_path({
"data" : "this is the message",
"client" : "client 1"
},"tests-uds","W");
//
let response = await messngr.send_op_on_path({
"data" : "this is the second message",
"client" : "client 1"
},"tests-uds","W");
console.dir(response)
//
console.log("closing client")
messngr.closeAll();
console.log("closing server")
epoint.closeAll();
resolve(true)
//
})
})
})
try {
await p;
t.pass("handlers ran")
} catch (e) {
t.fail("handler promeise error caught")
}
})