systemlynx 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/API.md +142 -0
  2. package/LICENSE +21 -0
  3. package/README.md +180 -0
  4. package/index.js +40 -0
  5. package/index.test.js +121 -0
  6. package/package.json +41 -0
  7. package/systemlynx/App/App.js +76 -0
  8. package/systemlynx/App/components/SystemObject.js +9 -0
  9. package/systemlynx/App/components/initializeApp.js +33 -0
  10. package/systemlynx/App/components/loadModules.js +14 -0
  11. package/systemlynx/App/components/loadServices.js +28 -0
  12. package/systemlynx/App/tests/App.test.js +354 -0
  13. package/systemlynx/Client/Client.js +42 -0
  14. package/systemlynx/Client/components/ClientModule.js +28 -0
  15. package/systemlynx/Client/components/ServiceRequestHandler.js +62 -0
  16. package/systemlynx/Client/components/SocketDispatcher.js +20 -0
  17. package/systemlynx/Client/components/loadConnectionData.js +18 -0
  18. package/systemlynx/Client/tests/Client.test.js +208 -0
  19. package/systemlynx/Client/tests/SocketDispatcher.test.js +54 -0
  20. package/systemlynx/Dispatcher/Dispatcher.js +21 -0
  21. package/systemlynx/Dispatcher/Dispatcher.test.js +21 -0
  22. package/systemlynx/HttpClient/HttpClient.js +44 -0
  23. package/systemlynx/HttpClient/HttpClient.test.js +143 -0
  24. package/systemlynx/HttpClient/test.file.json +1 -0
  25. package/systemlynx/HttpClient/test.server.js +34 -0
  26. package/systemlynx/LoadBalancer/LoadBalancer.js +7 -0
  27. package/systemlynx/LoadBalancer/components/CloneManager.js +49 -0
  28. package/systemlynx/LoadBalancer/components/Router.js +37 -0
  29. package/systemlynx/LoadBalancer/tests/LoadBalancer.test.js +142 -0
  30. package/systemlynx/ServerManager/ServerManager.js +113 -0
  31. package/systemlynx/ServerManager/components/Router.js +89 -0
  32. package/systemlynx/ServerManager/components/Server.js +52 -0
  33. package/systemlynx/ServerManager/components/SocketEmitter.js +19 -0
  34. package/systemlynx/ServerManager/components/WebSocketServer.js +7 -0
  35. package/systemlynx/ServerManager/components/parseMethods.js +19 -0
  36. package/systemlynx/ServerManager/tests/ServerManager.test.js +197 -0
  37. package/systemlynx/ServerManager/tests/SocketEmitter.test.js +29 -0
  38. package/systemlynx/Service/Service.js +28 -0
  39. package/systemlynx/Service/Service.test.js +176 -0
  40. package/temp/.gitignore +4 -0
  41. package/utils/ProcessChecker.js +18 -0
@@ -0,0 +1,142 @@
1
+ const { expect } = require("chai");
2
+ const LoadBalancer = require("../LoadBalancer")();
3
+ const ServiceFactory = require("../../Service/Service");
4
+ const HttpClient = require("../../HttpClient/HttpClient")();
5
+ const lbPort = 5030;
6
+ const route = "loadbalancer";
7
+
8
+ describe("LoadBalancerFactory", () => {
9
+ it("should return a SystemLynx LoadBalancer", () => {
10
+ expect(LoadBalancer)
11
+ .to.be.an("object")
12
+ .that.has.all.keys(
13
+ "startService",
14
+ "Server",
15
+ "WebSocket",
16
+ "defaultModule",
17
+ "ServerModule",
18
+ "clones"
19
+ )
20
+ .that.respondsTo("startService")
21
+ .that.respondsTo("Server")
22
+ .that.respondsTo("WebSocket")
23
+ .that.respondsTo("ServerModule");
24
+ expect(LoadBalancer.clones)
25
+ .to.be.an("object")
26
+ .that.has.all.keys("on", "emit", "clones", "register", "dispatch", "assignDispatch")
27
+ .that.respondsTo("emit")
28
+ .that.respondsTo("on")
29
+ .that.respondsTo("register")
30
+ .that.respondsTo("dispatch")
31
+ .that.respondsTo("assignDispatch")
32
+ .that.has.property("clones")
33
+ .that.is.an("array");
34
+ });
35
+ });
36
+ describe("LoadBalancer", () => {
37
+ it("should return an object with properties: startService (fn), clones (Service)", () => {
38
+ expect(LoadBalancer).to.be.an("object");
39
+ expect(typeof LoadBalancer.startService).to.equal("function");
40
+ });
41
+
42
+ it("should be able to start the LoadBalancer Service using the LoadBalancer.startService method", async () => {
43
+ await LoadBalancer.startService({ port: lbPort, route });
44
+ const url = `http://localhost:${lbPort}/${route}`;
45
+ const connData = await HttpClient.request({ url });
46
+
47
+ expect(connData)
48
+ .to.be.an("Object")
49
+ .that.has.all.keys(
50
+ "SystemLynxService",
51
+ "host",
52
+ "port",
53
+ "modules",
54
+ "route",
55
+ "namespace",
56
+ "serviceUrl"
57
+ )
58
+ .that.has.property("modules")
59
+ .that.is.an("array")
60
+ .to.has.a.lengthOf(1);
61
+ });
62
+ });
63
+ describe("LoadBalancer.clones (ServerModule)", () => {
64
+ const test_service1 = {
65
+ route: "test-service1",
66
+ port: 5393,
67
+ host: "localhost",
68
+ };
69
+
70
+ const test_service2 = {
71
+ route: "test-service2",
72
+ port1: 5391,
73
+ port2: 5392,
74
+ host: "localhost",
75
+ };
76
+ it("should be a Service object with additional methods for LoadBalancing", () => {
77
+ expect(LoadBalancer.clones)
78
+ .to.be.an("Object")
79
+ .that.has.all.keys("on", "emit", "register", "dispatch", "assignDispatch", "clones")
80
+ .that.respondsTo("on")
81
+ .that.respondsTo("emit")
82
+ .that.respondsTo("register")
83
+ .that.respondsTo("dispatch")
84
+ .that.respondsTo("assignDispatch")
85
+ .that.has.property("clones")
86
+ .that.is.an("array");
87
+ });
88
+
89
+ it("should be able to use clones.register(connData, callback) method to host connection", async () => {
90
+ const Service = ServiceFactory();
91
+ const { route, port, host } = test_service1;
92
+ await Service.startService({ route, port, host });
93
+ LoadBalancer.clones.register({ route, port, host }, () => {});
94
+ const url = `http://localhost:${lbPort}/${route}`;
95
+ const connData = await HttpClient.request({ url });
96
+
97
+ expect(connData)
98
+ .to.be.an("Object")
99
+ .that.has.all.keys(
100
+ "SystemLynxService",
101
+ "host",
102
+ "port",
103
+ "modules",
104
+ "route",
105
+ "namespace",
106
+ "serviceUrl"
107
+ )
108
+ .that.has.property("modules")
109
+ .that.is.an("array")
110
+ .to.has.a.lengthOf(0);
111
+ expect(connData.serviceUrl).to.equal(`http://localhost:${port}/${route}`);
112
+ });
113
+
114
+ it("should be able to manager the routing to multiple clones of the same Service", async () => {
115
+ const { route, port1, port2, host } = test_service2;
116
+ const Clone1 = ServiceFactory();
117
+ const Clone2 = ServiceFactory();
118
+ await Clone1.startService({ route, port: port1, host });
119
+ await Clone2.startService({ route, port: port2, host });
120
+ LoadBalancer.clones.register({ route, port: port1, host }, () => {});
121
+ LoadBalancer.clones.register({ route, port: port2, host }, () => {});
122
+
123
+ const url = `http://localhost:${lbPort}/${route}`;
124
+
125
+ const connData1 = await HttpClient.request({ url });
126
+ expect(connData1.serviceUrl).to.equal(`http://localhost:${port1}/${route}`);
127
+ const connData2 = await HttpClient.request({ url });
128
+ expect(connData2.serviceUrl).to.equal(`http://localhost:${port2}/${route}`);
129
+ });
130
+
131
+ it("should be able to manage the route of multiple clones of multiple Services. aka Service Discovery", async () => {
132
+ const route1 = test_service1.route;
133
+ const route2 = test_service2.route;
134
+ const url1 = `http://localhost:${lbPort}/${route1}`;
135
+ const url2 = `http://localhost:${lbPort}/${route2}`;
136
+
137
+ const connData1 = await HttpClient.request({ url: url1 });
138
+ expect(connData1.route).to.equal(`/${route1}`);
139
+ const connData2 = await HttpClient.request({ url: url2 });
140
+ expect(connData2.route).to.equal(`/${route2}`);
141
+ });
142
+ });
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ const SystemLynxServer = require("./components/Server");
3
+ const SystemLynxRouter = require("./components/Router");
4
+ const SocketEmitter = require("./components/SocketEmitter");
5
+ const SystemLynxWebSocket = require("./components/WebSocketServer");
6
+ const parseMethods = require("./components/parseMethods");
7
+ const shortId = require("shortid");
8
+
9
+ module.exports = function SystemLynxServerManager() {
10
+ let serverConfigurations = {
11
+ route: null,
12
+ port: null,
13
+ host: "localhost",
14
+ serviceUrl: null,
15
+ socketPort: null,
16
+ useREST: false,
17
+ useService: true,
18
+ staticRouting: false,
19
+ validateArgs: true,
20
+ middleware: [],
21
+ useCallbacks: true,
22
+ useReturnValues: false,
23
+ };
24
+ const server = SystemLynxServer();
25
+ const router = SystemLynxRouter(server, () => serverConfigurations);
26
+ const { SocketServer, WebSocket } = SystemLynxWebSocket();
27
+ const moduleQueue = [];
28
+ const modules = [];
29
+
30
+ const ServerManager = { Server: () => server, WebSocket: () => WebSocket };
31
+
32
+ ServerManager.startService = (options) => {
33
+ let { route, host = "localhost", port, socketPort, staticRouting } = options;
34
+
35
+ socketPort =
36
+ socketPort || parseInt(Math.random() * parseInt(Math.random() * 10000)) + 1023;
37
+ const namespace = staticRouting ? route : shortId();
38
+ SocketServer.listen(socketPort);
39
+ SocketEmitter.apply(ServerManager, [namespace, WebSocket]);
40
+
41
+ route = route.charAt(0) === "/" ? route.substr(1) : route;
42
+ route =
43
+ route.charAt(route.length - 1) === "/" ? route.substr(route.length - 1) : route;
44
+ const serviceUrl = `http://${host}:${port}/${route}`;
45
+ serverConfigurations = {
46
+ ...serverConfigurations,
47
+ ...options,
48
+ serviceUrl,
49
+ route,
50
+ socketPort,
51
+ };
52
+
53
+ server.get(`/${route}`, (req, res) => {
54
+ //The route will return connection data for the service including an array of
55
+ //modules (objects) which contain instructions on how to make request to each object
56
+ res.json({
57
+ modules,
58
+ port,
59
+ host,
60
+ route: `/${route}`,
61
+ serviceUrl,
62
+ namespace: `http://${host}:${socketPort}/${namespace}`,
63
+ SystemLynxService: true,
64
+ });
65
+ });
66
+
67
+ return new Promise((resolve) =>
68
+ server.listen(port, () => {
69
+ console.log(`(SystemLynxService): ${route} --> Listening on ${host}:${port}`);
70
+ moduleQueue.forEach(({ name, object, reserved_methods }) =>
71
+ ServerManager.addModule(name, object, reserved_methods)
72
+ );
73
+ moduleQueue.length = 0;
74
+ resolve(ServerManager);
75
+ })
76
+ );
77
+ };
78
+
79
+ ServerManager.addModule = (name, object, reserved_methods = []) => {
80
+ const { host, route, serviceUrl, staticRouting, useService, useREST, socketPort } =
81
+ serverConfigurations;
82
+
83
+ if (!serviceUrl) return moduleQueue.push({ name, object, reserved_methods });
84
+ const methods = parseMethods(object, ["on", "emit", ...reserved_methods], useREST);
85
+ const namespace = staticRouting ? name : shortId();
86
+
87
+ SocketEmitter.apply(object, [namespace, WebSocket]);
88
+
89
+ if (useService) {
90
+ const path = staticRouting ? `${route}/${name}` : `${shortId()}/${shortId()}`;
91
+
92
+ modules.push({
93
+ namespace: `http://${host}:${socketPort}/${namespace}`,
94
+ route: `/${path}`,
95
+ name,
96
+ methods,
97
+ });
98
+ methods.forEach((method) => router.addService(object, path, method, name));
99
+ }
100
+ if (useREST)
101
+ methods.forEach((method) => {
102
+ switch (method.fn) {
103
+ case "get":
104
+ case "put":
105
+ case "post":
106
+ case "delete":
107
+ router.addREST(object, `${route}/${name}`, method, name);
108
+ }
109
+ });
110
+ };
111
+
112
+ return ServerManager;
113
+ };
@@ -0,0 +1,89 @@
1
+ const isObject = (value) =>
2
+ typeof value === "object" ? (!value ? false : !Array.isArray(value)) : false;
3
+ const isEmpty = (obj) => Object.getOwnPropertyNames(obj).length === 0;
4
+ const isPromise = (p) => typeof p === "object" && typeof p.then === "function";
5
+
6
+ module.exports = function SystemLynxRouter(server, config) {
7
+ const addService = (ServerModule, route, { fn, method }, module_name) => {
8
+ server[method](
9
+ [`/${route}/${fn}`, `/sf/${route}/${fn}`, `/mf/${route}/${fn}`],
10
+ (req, res, next) => {
11
+ req.module_name = module_name;
12
+ req.fn = fn;
13
+ req.ServerModule = ServerModule;
14
+ next();
15
+ },
16
+ routeHandler
17
+ );
18
+ };
19
+
20
+ const addREST = (ServerModule, route, { method }, module_name) => {
21
+ server[method](
22
+ [`/${route}`],
23
+ (req, res, next) => {
24
+ req.module_name = module_name;
25
+ req.fn = method;
26
+ req.ServerModule = ServerModule;
27
+ next();
28
+ },
29
+ routeHandler
30
+ );
31
+ };
32
+
33
+ const routeHandler = (req, res) => {
34
+ const { query, file, files, body, fn, ServerModule, module_name, method } = req;
35
+ const { serviceUrl } = config();
36
+ const presets = { serviceUrl, module_name, fn };
37
+
38
+ const sendError = (error) => {
39
+ const status = error.status || 500;
40
+ const message = error.message || "Unexpected error";
41
+ const unhandledMessage = status === 500 ? "Unhandled error" : "Error";
42
+ res.status(status).json({
43
+ ...presets,
44
+ error,
45
+ status,
46
+ message: `[SystemLynx][error]: ${unhandledMessage} While calling ${module_name}.${fn}(...): ${message}`,
47
+ SystemLynxServiceError: true,
48
+ });
49
+ };
50
+
51
+ const sendResponse = (returnValue) => {
52
+ const status = returnValue.status || 200;
53
+ if (status < 400) {
54
+ res.status(status).json({
55
+ ...presets,
56
+ status,
57
+ message:
58
+ returnValue.message ||
59
+ `[SystemLynx][response]: ${module_name}.${fn}(...) returned successfully`,
60
+ returnValue,
61
+ });
62
+ } else sendError(returnValue);
63
+ };
64
+
65
+ if (typeof ServerModule[fn] !== "function")
66
+ return sendResponse({
67
+ message: `[SystemLynx][error]:${module_name}.${fn} method not found`,
68
+ status: 404,
69
+ });
70
+
71
+ try {
72
+ const args = body.__arguments || [];
73
+ if (!isEmpty(query) && !args.length) args.push(query);
74
+ if (isObject(args[0]) && method === "PUT") args[0] = { ...args[0], file, files };
75
+
76
+ const results = ServerModule[fn].apply(ServerModule, args);
77
+
78
+ if (isPromise(results)) {
79
+ results.then(sendResponse).catch(sendError);
80
+ } else {
81
+ sendResponse(results);
82
+ }
83
+ } catch (error) {
84
+ sendError(error);
85
+ }
86
+ };
87
+
88
+ return { addService, addREST };
89
+ };
@@ -0,0 +1,52 @@
1
+ //express server, socket.io server and middleware needed for SystemLynx basic functionality
2
+
3
+ module.exports = function SystemLynxServer() {
4
+ const cwd = process.cwd();
5
+ //express server
6
+ const express = require("express");
7
+ const server = express();
8
+ //express middleware
9
+ const bodyParser = require("body-parser");
10
+ const multer = require("multer");
11
+ //express file upload middleware setup
12
+ const TEMP_LOCATION = "./temp";
13
+ const mime = require("mime");
14
+ const shortId = require("shortid");
15
+ const storage = multer.diskStorage({
16
+ destination: (req, file, cb) => cb(null, TEMP_LOCATION),
17
+ filename: (req, file, cb) =>
18
+ cb(null, `${shortId()}.${mime.getExtension(file.mimetype)}`),
19
+ });
20
+ //multi-file and single-file upload middleware functions
21
+ const sf = multer({ storage: storage }).single("file");
22
+ const mf = multer({ storage: storage }).array("files");
23
+ //the sf and mf functions are used to a extract file from the req during a file upload
24
+ //a property named file and files will be added to the req object respectively
25
+ const singleFileUpload = (req, res, next) =>
26
+ sf(req, res, (err) => {
27
+ if (err) res.json(errorResponseBuilder(err));
28
+ else next();
29
+ });
30
+ const multiFileUpload = (req, res, next) =>
31
+ mf(req, res, (err) => {
32
+ if (err) res.json(errorResponseBuilder(err));
33
+ else next();
34
+ });
35
+
36
+ server.use("/sf", singleFileUpload);
37
+ server.use("/mf", multiFileUpload);
38
+ server.use(express.static(cwd + "/public"));
39
+ server.use(bodyParser.json({ limit: "5mb" }));
40
+
41
+ server.use((req, res, next) => {
42
+ res.setHeader("Access-Control-Allow-Origin", "*");
43
+ res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT ,DELETE");
44
+ res.setHeader(
45
+ "Access-Control-Allow-Headers",
46
+ "X-Requested-With,content-type, Authorization"
47
+ );
48
+ next();
49
+ });
50
+
51
+ return server;
52
+ };
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ const SystemLynxDispatcher = require("../../Dispatcher/Dispatcher");
3
+ const shortid = require("shortid");
4
+ module.exports = function SocketEmitter(namespace, WebSocket) {
5
+ const Emitter =
6
+ (this || {}).on && (this || {}).emit ? this : SystemLynxDispatcher.apply(this);
7
+
8
+ const socket = WebSocket.of(`/${namespace}`);
9
+ const emit = Emitter.emit;
10
+
11
+ Emitter.emit = (name, data) => {
12
+ const id = shortid();
13
+ const type = "WebSocket";
14
+ socket.emit("dispatch", { id, name, data, type });
15
+ //emit the same event locally
16
+ emit(name, data);
17
+ };
18
+ return Emitter;
19
+ };
@@ -0,0 +1,7 @@
1
+ module.exports = function SystemLynxWebWebSocket() {
2
+ const express = require("express");
3
+ const SocketServer = require("http").Server(express());
4
+ const WebSocket = require("socket.io")(SocketServer);
5
+
6
+ return { WebSocket, SocketServer };
7
+ };
@@ -0,0 +1,19 @@
1
+ const parseMethods = (obj, reserved_methods = [], useREST) => {
2
+ const methods = [];
3
+ const REST_methods = ["get", "put", "post", "delete"];
4
+ const props = Object.getOwnPropertyNames(obj);
5
+
6
+ props.forEach((fn) => {
7
+ if (typeof obj[fn] === "function" && reserved_methods.indexOf(fn) === -1) {
8
+ const method =
9
+ useREST && REST_methods.indexOf(fn.toLocaleLowerCase()) > -1
10
+ ? fn.toLocaleLowerCase()
11
+ : "put";
12
+ methods.push({ method, fn });
13
+ }
14
+ });
15
+
16
+ return methods;
17
+ };
18
+
19
+ module.exports = parseMethods;
@@ -0,0 +1,197 @@
1
+ const { expect } = require("chai");
2
+ const SystemLynxServerManager = require("../ServerManager");
3
+ const request = require("request");
4
+
5
+ describe("SystemLynxServerManager function", () => {
6
+ it("should return an ServerManager instance", () => {
7
+ const ServerManager = SystemLynxServerManager();
8
+
9
+ expect(ServerManager)
10
+ .to.be.an("Object")
11
+ .that.has.all.keys(["startService", "addModule", "Server", "WebSocket"])
12
+ .that.respondsTo("startService")
13
+ .that.respondsTo("addModule")
14
+ .that.respondsTo("Server")
15
+ .that.respondsTo("WebSocket");
16
+ });
17
+ });
18
+ describe("ServerManager", () => {
19
+ it("should be able use ServerManager.startService to start a server that will accept requests for ServerModule Connection Data on the given route", async () => {
20
+ const ServerManager = SystemLynxServerManager();
21
+ const route = "/testService";
22
+ const port = 4400;
23
+ const url = `http://localhost:${port}${route}`;
24
+
25
+ await ServerManager.startService({ route, port });
26
+ const results = await new Promise((resolve) => {
27
+ request({ url, json: true }, (err, res, body) => {
28
+ resolve(body);
29
+ });
30
+ });
31
+
32
+ expect(results)
33
+ .to.be.an("Object")
34
+ .that.has.all.keys(
35
+ "SystemLynxService",
36
+ "serviceUrl",
37
+ "route",
38
+ "host",
39
+ "port",
40
+ "modules",
41
+ "namespace"
42
+ )
43
+ .that.has.property("modules")
44
+ .that.is.an("array").that.is.empty;
45
+ });
46
+
47
+ it("should be able to use the ServerManager.addModule method to add data to the ServerManager instance that can be accessed via a GET request", async () => {
48
+ const ServerManager = SystemLynxServerManager();
49
+ const route = "/testService";
50
+ const port = 4634;
51
+ const url = `http://localhost:${port}${route}`;
52
+ const name = "TestModule";
53
+ await ServerManager.startService({ route, port });
54
+
55
+ ServerManager.addModule(name, {});
56
+ ServerManager.addModule(name + 1, {});
57
+ const results = await new Promise((resolve) => {
58
+ request({ url, json: true }, (err, res, body) => {
59
+ resolve(body);
60
+ });
61
+ });
62
+
63
+ expect(results)
64
+ .to.be.an("object")
65
+ .that.has.all.keys(
66
+ "SystemLynxService",
67
+ "serviceUrl",
68
+ "route",
69
+ "host",
70
+ "port",
71
+ "modules",
72
+ "namespace"
73
+ )
74
+ .that.has.property("modules")
75
+ .that.is.an("array")
76
+ .that.has.a.lengthOf(2);
77
+ expect(results.modules[0])
78
+ .to.be.an("object")
79
+ .that.has.all.keys("name", "methods", "route", "namespace");
80
+ });
81
+
82
+ it("should be able call ServerManager.addModule method before or after calling ServerManager.startService", async () => {
83
+ const ServerManager = SystemLynxServerManager();
84
+ const route = "/testService";
85
+ const port = 4500;
86
+ const url = `http://localhost:${port}${route}`;
87
+ const name = "TestModule";
88
+
89
+ ServerManager.addModule(name, {});
90
+ ServerManager.addModule(name + 1, {});
91
+
92
+ await ServerManager.startService({ route, port });
93
+
94
+ const results = await new Promise((resolve) => {
95
+ request({ url, json: true }, (err, res, body) => {
96
+ resolve(body);
97
+ });
98
+ });
99
+
100
+ expect(results)
101
+ .to.be.an("object")
102
+ .that.has.all.keys(
103
+ "SystemLynxService",
104
+ "serviceUrl",
105
+ "route",
106
+ "host",
107
+ "port",
108
+ "modules",
109
+ "namespace"
110
+ )
111
+ .that.has.property("modules")
112
+ .that.is.an("array")
113
+ .that.has.a.lengthOf(2);
114
+ expect(results.modules[0])
115
+ .to.be.an("object")
116
+ .that.has.all.keys("name", "methods", "route", "namespace");
117
+ });
118
+ });
119
+
120
+ describe("ServerManager.startService(ServerConfiguration)", () => {
121
+ it("should be able to use the useREST=true property to create a REST API route for any method with the name 'get', 'put', 'post' or 'delete'", async () => {
122
+ const ServerManager = SystemLynxServerManager();
123
+ const route = "/testAPI";
124
+ const port = 8372;
125
+ const url = `http://localhost:${port}${route}`;
126
+ const name = "testObject";
127
+ const object = {
128
+ get: () => (null, { REST_TEST_PASSED: true }),
129
+ put: () => {},
130
+ post: () => {},
131
+ delete: () => {},
132
+ };
133
+
134
+ ServerManager.addModule(name, object);
135
+
136
+ await ServerManager.startService({
137
+ route,
138
+ port,
139
+ useREST: true,
140
+ });
141
+
142
+ const results = await new Promise((resolve) => {
143
+ request({ url: `${url}/${name}`, json: true }, (err, res, body) => {
144
+ resolve(body);
145
+ });
146
+ });
147
+
148
+ expect(results).to.deep.equal({
149
+ fn: "get",
150
+ message: "[SystemLynx][response]: testObject.get(...) returned successfully",
151
+ module_name: "testObject",
152
+ returnValue: {
153
+ REST_TEST_PASSED: true,
154
+ },
155
+ serviceUrl: "http://localhost:8372/testAPI",
156
+ status: 200,
157
+ });
158
+ });
159
+
160
+ it("should be able to use the staticRouting=true property to create static routes to the ServerModules", async () => {
161
+ const ServerManager = SystemLynxServerManager();
162
+ const route = "/testAPI";
163
+ const port = 2233;
164
+ const url = `http://localhost:${port}${route}`;
165
+ const name = "testObject";
166
+ const object = {
167
+ get: () => (null, { SERVICE_TEST_PASSED: true }),
168
+ put: () => (null, { SERVICE_TEST_PASSED: true }),
169
+ post: () => {},
170
+ delete: () => {},
171
+ };
172
+
173
+ ServerManager.addModule(name, object);
174
+
175
+ await ServerManager.startService({
176
+ route,
177
+ port,
178
+ staticRouting: true,
179
+ useREST: true,
180
+ });
181
+
182
+ const results = await new Promise((resolve) => {
183
+ request({ url: `${url}/${name}/get`, json: true }, (err, res, body) => {
184
+ resolve(body);
185
+ });
186
+ });
187
+
188
+ expect(results).to.deep.equal({
189
+ returnValue: { SERVICE_TEST_PASSED: true },
190
+ fn: "get",
191
+ message: "[SystemLynx][response]: testObject.get(...) returned successfully",
192
+ module_name: "testObject",
193
+ serviceUrl: "http://localhost:2233/testAPI",
194
+ status: 200,
195
+ });
196
+ });
197
+ });
@@ -0,0 +1,29 @@
1
+ const { expect } = require("chai");
2
+ const SocketEmiiter = require("../components/SocketEmitter");
3
+ const { WebSocket, SocketServer } = require("../components/WebSocketServer")();
4
+ const io = require("socket.io-client");
5
+
6
+ describe("SocketEmiiter", () => {
7
+ it("should be able to use emmiter.emit(name, data) to dispatch events to a websockt client", done => {
8
+ const namespace = "test-namespace";
9
+ const port = 5556;
10
+ const eventName = "test-event";
11
+ SocketServer.listen(port);
12
+ const emmiter = SocketEmiiter(namespace, WebSocket);
13
+
14
+ setTimeout(() => {
15
+ emmiter.emit(eventName, { testPassed: true });
16
+ }, 500);
17
+ const socket = io.connect(`http://localhost:${port}/${namespace}`);
18
+ socket.on("dispatch", dispatch => {
19
+ expect(dispatch)
20
+ .to.be.an("object")
21
+ .that.has.all.keys("id", "name", "data", "type");
22
+ expect(dispatch.name).to.equal(eventName);
23
+ expect(dispatch.data).to.deep.equal({ testPassed: true });
24
+ done();
25
+ });
26
+ socket.on("disconnect", () => console.log("---------> disconnect"));
27
+ socket.on("connect", () => console.log(`socket connected to namespace: ${namespace}`));
28
+ });
29
+ });