orator 2.0.4 → 3.0.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.
- package/.config/code-server/config.yaml +4 -0
- package/.config/configstore/update-notifier-npm-check-updates.json +4 -0
- package/.config/configstore/update-notifier-npm.json +4 -0
- package/.vscode/launch.json +26 -6
- package/Dockerfile_LUXURYCode +69 -0
- package/debug/Harness.js +42 -0
- package/package.json +40 -27
- package/source/Orator-Default-Configuration.js +10 -0
- package/source/Orator-Default-ServiceServers-Node.js +21 -0
- package/source/Orator-ServiceServer-IPC-RouterConstrainer.js +35 -0
- package/source/Orator-ServiceServer-IPC-SynthesizedResponse.js +56 -0
- package/source/Orator-ServiceServer-IPC.js +214 -0
- package/source/Orator.js +122 -684
- package/test/Orator_basic_tests.js +44 -234
- package/{test → test_legacy}/Orator-proxy_tests.js +12 -3
- package/test_legacy/Orator_basic_tests.js +294 -0
- package/{test → test_legacy}/Orator_cluster_test.js.deferred +7 -7
- package/{test → test_legacy}/Orator_logging_tests.js +52 -6
- package/test_legacy/Test.css +4 -0
- package/test_legacy/Test.html +1 -0
- package/.travis.yml +0 -15
- package/Debug-Harness.js +0 -24
- package/test/Orator_chromecpu_notrace_tests.js +0 -90
- package/test/Orator_chromecpu_tests.js +0 -95
package/.vscode/launch.json
CHANGED
|
@@ -5,22 +5,42 @@
|
|
|
5
5
|
"version": "0.2.0",
|
|
6
6
|
"configurations": [
|
|
7
7
|
{
|
|
8
|
+
"name": "Launch Debug Harness",
|
|
8
9
|
"type": "node",
|
|
9
10
|
"request": "launch",
|
|
11
|
+
"outputCapture": "std",
|
|
12
|
+
"skipFiles": [
|
|
13
|
+
"<node_internals>/**"
|
|
14
|
+
],
|
|
15
|
+
"program": "${workspaceFolder}/debug/Harness.js",
|
|
16
|
+
"presentation": {
|
|
17
|
+
"hidden": false,
|
|
18
|
+
"group": "",
|
|
19
|
+
"order": 1
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
{
|
|
10
23
|
"name": "Mocha Tests",
|
|
11
|
-
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
|
|
12
24
|
"args": [
|
|
13
25
|
"-u",
|
|
14
26
|
"tdd",
|
|
15
|
-
"--bail",
|
|
16
27
|
"--timeout",
|
|
17
28
|
"999999",
|
|
18
29
|
"--colors",
|
|
19
|
-
"${workspaceFolder}/test
|
|
20
|
-
|
|
21
|
-
|
|
30
|
+
"${workspaceFolder}/test"
|
|
31
|
+
],
|
|
32
|
+
"internalConsoleOptions": "openOnSessionStart",
|
|
33
|
+
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
|
|
34
|
+
"request": "launch",
|
|
35
|
+
"skipFiles": [
|
|
36
|
+
"<node_internals>/**"
|
|
22
37
|
],
|
|
23
|
-
"
|
|
38
|
+
"type": "pwa-node",
|
|
39
|
+
"presentation": {
|
|
40
|
+
"hidden": false,
|
|
41
|
+
"group": "",
|
|
42
|
+
"order": 2
|
|
43
|
+
}
|
|
24
44
|
}
|
|
25
45
|
]
|
|
26
46
|
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Use the codercom/code-server image
|
|
2
|
+
FROM codercom/code-server:latest
|
|
3
|
+
MAINTAINER steven velozo
|
|
4
|
+
|
|
5
|
+
VOLUME /home/coder/.config
|
|
6
|
+
VOLUME /home/coder/.vscode
|
|
7
|
+
|
|
8
|
+
RUN echo "...installing debian dependencies..."
|
|
9
|
+
RUN sudo apt update
|
|
10
|
+
RUN sudo apt install vim curl tmux -y
|
|
11
|
+
|
|
12
|
+
RUN echo "Building development image..."
|
|
13
|
+
|
|
14
|
+
RUN echo "...installing vscode extensions..."
|
|
15
|
+
|
|
16
|
+
# Mocha unit testing in the sidebar
|
|
17
|
+
RUN code-server --install-extension hbenl.vscode-mocha-test-adapter
|
|
18
|
+
RUN code-server --install-extension hbenl.test-adapter-converter
|
|
19
|
+
RUN code-server --install-extension hbenl.vscode-test-explorer
|
|
20
|
+
|
|
21
|
+
# Magic indentation rainbow
|
|
22
|
+
RUN code-server --install-extension oderwat.indent-rainbow
|
|
23
|
+
RUN code-server --install-extension dbaeumer.vscode-eslint
|
|
24
|
+
|
|
25
|
+
# Contextual git
|
|
26
|
+
RUN code-server --install-extension eamodio.gitlens
|
|
27
|
+
|
|
28
|
+
# Other extensions (uncomment them to have them automagic, or run this from a terminal to install in the container):
|
|
29
|
+
|
|
30
|
+
# Microsoft's AI code completion
|
|
31
|
+
# RUN code-server --install-extension VisualStudioExptTeam.vscodeintellicode
|
|
32
|
+
|
|
33
|
+
# Live server -- make sure to open up the port on the docker image
|
|
34
|
+
# RUN code-server --install-extension ritwickdey.LiveServer
|
|
35
|
+
|
|
36
|
+
# Quick link to required modules' documentation
|
|
37
|
+
# RUN code-server --install-extension bengreenier.vscode-node-readme
|
|
38
|
+
|
|
39
|
+
# Switch up fonts
|
|
40
|
+
# RUN code-server --install-extension evan-buss.font-switcher
|
|
41
|
+
|
|
42
|
+
# Icons
|
|
43
|
+
# RUN code-server --install-extension vscode-icons-team.vscode-icons
|
|
44
|
+
# RUN code-server --install-extension PKief.material-icon-theme
|
|
45
|
+
|
|
46
|
+
# Hover over CSS colors to see them previewed
|
|
47
|
+
# RUN code-server --install-extension bierner.color-info
|
|
48
|
+
|
|
49
|
+
# An easy on the eyes color theme
|
|
50
|
+
# RUN code-server --install-extension daylerees.rainglow
|
|
51
|
+
|
|
52
|
+
RUN echo "...mapping library specific volumes..."
|
|
53
|
+
|
|
54
|
+
# Volume mapping for code
|
|
55
|
+
VOLUME /home/coder/orator
|
|
56
|
+
|
|
57
|
+
SHELL ["/bin/bash", "-c"]
|
|
58
|
+
USER coder
|
|
59
|
+
|
|
60
|
+
RUN echo "...installing node version manager..."
|
|
61
|
+
# Because there is a .bashrc chicken/egg problem, we will create one here to simulate logging in. This is not great.
|
|
62
|
+
RUN touch ~/.bashrc && chmod +x ~/.bashrc
|
|
63
|
+
RUN curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash
|
|
64
|
+
|
|
65
|
+
RUN echo "...installing node version 14 as the default..."
|
|
66
|
+
RUN . ~/.nvm/nvm.sh && source ~/.bashrc && nvm install 14
|
|
67
|
+
RUN . ~/.nvm/nvm.sh && source ~/.bashrc && nvm alias default 14
|
|
68
|
+
|
|
69
|
+
WORKDIR /home/coder/orator
|
package/debug/Harness.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// Load the orator module with a few simple routes
|
|
2
|
+
const libOrator = require(__dirname+'/../source/Orator.js');
|
|
3
|
+
// Uncomment the following line to test the restify server plug-in
|
|
4
|
+
// > make sure to run "npm i orator-serviceserver-restify" from the parent directory first so the package is available
|
|
5
|
+
// > please don't --save it!
|
|
6
|
+
const libOratorServiceServerRestify = require('orator-serviceserver-restify');
|
|
7
|
+
|
|
8
|
+
const tmpServiceServer = new libOrator(
|
|
9
|
+
{
|
|
10
|
+
"Product": "HarnessService",
|
|
11
|
+
"ProductVersion": "1.2.3",
|
|
12
|
+
|
|
13
|
+
"APIServerPort": 8080
|
|
14
|
+
}
|
|
15
|
+
// Uncomment the next line to enable restify!
|
|
16
|
+
,libOratorServiceServerRestify
|
|
17
|
+
);
|
|
18
|
+
// Initialize the service server
|
|
19
|
+
tmpServiceServer.initializeServiceServer();
|
|
20
|
+
// Start the service
|
|
21
|
+
tmpServiceServer.startService();
|
|
22
|
+
|
|
23
|
+
// Add a GET endpoint
|
|
24
|
+
tmpServiceServer.webServer.get
|
|
25
|
+
(
|
|
26
|
+
'/test/:hash',
|
|
27
|
+
(pRequest, pResponse, fNext) =>
|
|
28
|
+
{
|
|
29
|
+
// Send back whatever was sent as "name" in the URI
|
|
30
|
+
pResponse.send(pRequest.params);
|
|
31
|
+
tmpServiceServer.log.info(`Service has served the test echo route!`);
|
|
32
|
+
return fNext();
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
// If this is a web server, invoke is likely not implemented and will error.
|
|
37
|
+
let tmpURI = `/test/SomeHash`;
|
|
38
|
+
tmpServiceServer.invoke('GET', tmpURI, null,
|
|
39
|
+
(pError, pResponseData) =>
|
|
40
|
+
{
|
|
41
|
+
tmpServiceServer.log.info(`Response to [${tmpURI}] came back from IPC resulting in [${pResponseData}]!`)
|
|
42
|
+
});
|
package/package.json
CHANGED
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "orator",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
|
+
"description": "Unopinionated restful web API server container",
|
|
5
5
|
"main": "source/Orator.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"start": "node source/Orator.js",
|
|
8
|
-
"coverage": "
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"test-normal": "./node_modules/mocha/bin/_mocha --exit -u tdd -R spec",
|
|
14
|
-
"test-cluster": "./node_modules/mocha/bin/_mocha --exit -u tdd -R spec ./test/Orator_cluster_test.js.deferred"
|
|
8
|
+
"coverage": "./node_modules/.bin/nyc --reporter=lcov --reporter=text-lcov ./node_modules/mocha/bin/_mocha -- -u tdd -R spec",
|
|
9
|
+
"test": "./node_modules/mocha/bin/_mocha --exit -u tdd -R spec",
|
|
10
|
+
"build": "./node_modules/.bin/gulp build",
|
|
11
|
+
"docker-dev-build-image": "docker build ./ -f Dockerfile_LUXURYCode -t retold/orator:local",
|
|
12
|
+
"docker-dev-run": "docker run -it -d --name retold-orator-dev -p 40000:8080 -p 48086:8086 -p 48088:8088 -v \"$PWD/.config:/home/coder/.config\" -v \"$PWD:/home/coder/orator\" -u \"$(id -u):$(id -g)\" -e \"DOCKER_USER=$USER\" retold/orator:local"
|
|
15
13
|
},
|
|
16
14
|
"repository": {
|
|
17
15
|
"type": "git",
|
|
@@ -27,28 +25,43 @@
|
|
|
27
25
|
"bugs": {
|
|
28
26
|
"url": "https://github.com/stevenvelozo/orator/issues"
|
|
29
27
|
},
|
|
28
|
+
"mocha": {
|
|
29
|
+
"diff": true,
|
|
30
|
+
"extension": [
|
|
31
|
+
"js"
|
|
32
|
+
],
|
|
33
|
+
"package": "./package.json",
|
|
34
|
+
"reporter": "spec",
|
|
35
|
+
"slow": "75",
|
|
36
|
+
"timeout": "5000",
|
|
37
|
+
"ui": "tdd",
|
|
38
|
+
"watch-files": [
|
|
39
|
+
"source/**/*.js",
|
|
40
|
+
"test/**/*.js"
|
|
41
|
+
],
|
|
42
|
+
"watch-ignore": [
|
|
43
|
+
"lib/vendor"
|
|
44
|
+
]
|
|
45
|
+
},
|
|
30
46
|
"homepage": "https://github.com/stevenvelozo/orator",
|
|
31
47
|
"devDependencies": {
|
|
32
|
-
"
|
|
33
|
-
"chai": "4.
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
"
|
|
48
|
+
"browserify": "^17.0.0",
|
|
49
|
+
"chai": "4.3.7",
|
|
50
|
+
"gulp": "^4.0.2",
|
|
51
|
+
"gulp-babel": "^8.0.0",
|
|
52
|
+
"gulp-sourcemaps": "^3.0.0",
|
|
53
|
+
"gulp-terser": "^2.1.0",
|
|
54
|
+
"gulp-util": "^3.0.8",
|
|
55
|
+
"mocha": "10.2.0",
|
|
56
|
+
"nyc": "^15.1.0",
|
|
57
|
+
"vinyl-buffer": "^1.0.1",
|
|
58
|
+
"vinyl-source-stream": "^2.0.0"
|
|
42
59
|
},
|
|
43
60
|
"dependencies": {
|
|
61
|
+
"async": "^3.2.4",
|
|
44
62
|
"cachetrax": "^1.0.0",
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"http-forward": "^0.1.3",
|
|
49
|
-
"request": "^2.69.0",
|
|
50
|
-
"restify": "^6.4.0",
|
|
51
|
-
"restify-await-promise": "^1.0.0",
|
|
52
|
-
"restify-cors-middleware": "^1.1.1"
|
|
63
|
+
"fable": "~3.0.2",
|
|
64
|
+
"find-my-way": "^7.5.0",
|
|
65
|
+
"orator-serviceserver": "^1.0.1"
|
|
53
66
|
}
|
|
54
67
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default Service Server Function
|
|
3
|
+
*
|
|
4
|
+
* @license MIT
|
|
5
|
+
*
|
|
6
|
+
* @author Steven Velozo <steven@velozo.com>
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// Return the servers that are available without extensions loaded
|
|
10
|
+
getDefaultServiceServers = () =>
|
|
11
|
+
{
|
|
12
|
+
let tmpDefaultServiceServers = {};
|
|
13
|
+
|
|
14
|
+
tmpDefaultServiceServers.ipc = require('./Orator-ServiceServer-IPC.js');
|
|
15
|
+
|
|
16
|
+
tmpDefaultServiceServers.default = tmpDefaultServiceServers.ipc;
|
|
17
|
+
|
|
18
|
+
return tmpDefaultServiceServers;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
module.exports = getDefaultServiceServers();
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
// This is taken directly from the find-my-way documentation for custom constraints and only mildly edited
|
|
4
|
+
const ipcResponseTypeStrategy = (
|
|
5
|
+
{
|
|
6
|
+
// strategy name for referencing in the route handler `constraints` options
|
|
7
|
+
name: 'ipc',
|
|
8
|
+
isAsync: true,
|
|
9
|
+
|
|
10
|
+
// storage factory for storing routes in the find-my-way route tree
|
|
11
|
+
storage:
|
|
12
|
+
()=>
|
|
13
|
+
{
|
|
14
|
+
let handlers = {};
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
{
|
|
18
|
+
get: (type) => { return handlers[type] || null },
|
|
19
|
+
set: (type, store) => { handlers[type] = store }
|
|
20
|
+
});
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
// function to get the value of the constraint from each incoming request
|
|
24
|
+
deriveConstraint: (pRequest, pContext, fDone) =>
|
|
25
|
+
{
|
|
26
|
+
// If we wanted to deny the IPC request based on a constraint, we would do:
|
|
27
|
+
// fDone(new Error(`The request was denied because ____ in the Request object wasn't right...`));
|
|
28
|
+
return fDone(null, 'IPC');
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
// optional flag marking if handlers without constraints can match requests that have a value for this constraint
|
|
32
|
+
mustMatchWhenDerived: true
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
module.exports = ipcResponseTypeStrategy;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
class OratorServiceServerIPCSynthesizedResponse
|
|
2
|
+
{
|
|
3
|
+
constructor(pLog, pRequestGUID)
|
|
4
|
+
{
|
|
5
|
+
this.log = pLog;
|
|
6
|
+
|
|
7
|
+
this.requestGUID = pRequestGUID;
|
|
8
|
+
|
|
9
|
+
this.responseData = null;
|
|
10
|
+
this.responseStatus = -1;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
send(pData)
|
|
14
|
+
{
|
|
15
|
+
if (typeof(pData) == 'string')
|
|
16
|
+
{
|
|
17
|
+
// This is a string! Append it to the responsedata.
|
|
18
|
+
if (this.responseData === null)
|
|
19
|
+
{
|
|
20
|
+
this.responseData = pData;
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
else if (typeof(this.responseData) == 'string')
|
|
24
|
+
{
|
|
25
|
+
this.responseData = this.responseData+pData;
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
else
|
|
29
|
+
{
|
|
30
|
+
this.log(`Request ${this.requestGUID} has tried to send() a string value after send()ing data type ${typeof(this.responseData)}.`, pData)
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
else if (typeof(pData) == 'object')
|
|
35
|
+
{
|
|
36
|
+
if (this.responseData === null)
|
|
37
|
+
{
|
|
38
|
+
this.responseData = JSON.stringify(pData);
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
else if (typeof(this.responseData) == 'string')
|
|
42
|
+
{
|
|
43
|
+
// TODO: Discuss best way to handle this / if to handle this
|
|
44
|
+
this.responseData += this.responseData+JSON.stringify(pData);
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
else
|
|
48
|
+
{
|
|
49
|
+
this.log(`Request ${this.requestGUID} has tried to send() an object value to be auto stringified after send()ing data type ${typeof(this.responseData)}.`, pData)
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
module.exports = OratorServiceServerIPCSynthesizedResponse;
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
const libOratorServiceServerBase = require('orator-serviceserver');
|
|
2
|
+
|
|
3
|
+
// A synthesized response object, for simple IPC.
|
|
4
|
+
const libOratorServiceServerIPCSynthesizedResponse = require('./Orator-ServiceServer-IPC-SynthesizedResponse.js');
|
|
5
|
+
// A simple constrainer for the find-my-way router since we aren't using any kind of headers to pass version or host
|
|
6
|
+
const libOratorServiceServerIPCCustomConstrainer = require('./Orator-ServiceServer-IPC-RouterConstrainer.js');
|
|
7
|
+
|
|
8
|
+
// This library is the default router for our services
|
|
9
|
+
const libFindMyWay = require('find-my-way');
|
|
10
|
+
const libAsync = require('async');
|
|
11
|
+
|
|
12
|
+
class OratorServiceServerIPC extends libOratorServiceServerBase
|
|
13
|
+
{
|
|
14
|
+
constructor(pOrator)
|
|
15
|
+
{
|
|
16
|
+
super(pOrator);
|
|
17
|
+
|
|
18
|
+
this.routerOptions = (this.orator.settings.hasOwnProperty('router_options') && (typeof(this.orator.settings.router_options) == 'object')) ? this.orator.settings.router_options : {};
|
|
19
|
+
this.router = libFindMyWay(this.routerOptions);
|
|
20
|
+
this.router.addConstraintStrategy(libOratorServiceServerIPCCustomConstrainer);
|
|
21
|
+
|
|
22
|
+
this.URL = 'IPC';
|
|
23
|
+
|
|
24
|
+
this.preBehaviorFunctions = [];
|
|
25
|
+
this.behaviorMap = {};
|
|
26
|
+
this.postBehaviorFunctions = [];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
executePreBehaviorFunctions(pRequest, pResponse, fNext)
|
|
30
|
+
{
|
|
31
|
+
libAsync.eachOfSeries(this.preBehaviorFunctions,
|
|
32
|
+
(fBehaviorFunction, pFunctionIndex, fCallback) =>
|
|
33
|
+
{
|
|
34
|
+
return fBehaviorFunction(pRequest, pResponse, fCallback);
|
|
35
|
+
},
|
|
36
|
+
(pError) =>
|
|
37
|
+
{
|
|
38
|
+
if (pError)
|
|
39
|
+
{
|
|
40
|
+
this.log.error(`IPC Provider preBehaviorFunction ${pFunctionIndex} failed with error: ${pError}`, pError);
|
|
41
|
+
}
|
|
42
|
+
return fNext(pError);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
executePostBehaviorFunctions(pRequest, pResponse, fNext)
|
|
47
|
+
{
|
|
48
|
+
libAsync.eachOfSeries(this.postBehaviorFunctions,
|
|
49
|
+
(fBehaviorFunction, pFunctionIndex, fCallback) =>
|
|
50
|
+
{
|
|
51
|
+
return fBehaviorFunction(pRequest, pResponse, fCallback);
|
|
52
|
+
},
|
|
53
|
+
(pError) =>
|
|
54
|
+
{
|
|
55
|
+
if (pError)
|
|
56
|
+
{
|
|
57
|
+
this.log.error(`IPC Provider postBehaviorFunction ${pFunctionIndex} failed with error: ${pError}`, pError);
|
|
58
|
+
}
|
|
59
|
+
return fNext(pError);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/*
|
|
64
|
+
* Service Route Creation Functions
|
|
65
|
+
*
|
|
66
|
+
* These base functions provide basic validation for the routes, but don't actually
|
|
67
|
+
* do anything with them. The design intent here is to allow derived classes to call
|
|
68
|
+
* these functions to validate that they conform to expected standards.
|
|
69
|
+
*
|
|
70
|
+
* Something like:
|
|
71
|
+
|
|
72
|
+
get (pRoute, ...fRouteProcessingFunctions)
|
|
73
|
+
{
|
|
74
|
+
//...now we can do our actual get mapping function!....
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
* This pattern and calling super is totally optional, obviously.
|
|
78
|
+
*************************************************************************/
|
|
79
|
+
addRouteProcessor(pMethod, pRoute, pRouteFunctionArray)
|
|
80
|
+
{
|
|
81
|
+
// We have a constrainer on IPC so we can control channels eventually, if we like.
|
|
82
|
+
// For now it just makes sure it was added with an IPC service server.
|
|
83
|
+
this.router.on(pMethod, pRoute, { constraints: { "ipc": "IPC" } },
|
|
84
|
+
(pRequest, pResponse, pParameters) =>
|
|
85
|
+
{
|
|
86
|
+
libAsync.waterfall(
|
|
87
|
+
[
|
|
88
|
+
(fStageComplete)=>
|
|
89
|
+
{
|
|
90
|
+
// Added to make this mimic what we saw with route parsing in the old restify
|
|
91
|
+
pRequest.params = pParameters;
|
|
92
|
+
return fStageComplete();
|
|
93
|
+
},
|
|
94
|
+
(fStageComplete)=>
|
|
95
|
+
{
|
|
96
|
+
return this.executePreBehaviorFunctions(pRequest, pResponse, fStageComplete);
|
|
97
|
+
},
|
|
98
|
+
(fStageComplete)=>
|
|
99
|
+
{
|
|
100
|
+
libAsync.eachOfSeries(pRouteFunctionArray,
|
|
101
|
+
(fBehaviorFunction, pFunctionIndex, fCallback) =>
|
|
102
|
+
{
|
|
103
|
+
return fBehaviorFunction(pRequest, pResponse, fCallback);
|
|
104
|
+
},
|
|
105
|
+
(pBehaviorFunctionError) =>
|
|
106
|
+
{
|
|
107
|
+
if (pBehaviorFunctionError)
|
|
108
|
+
{
|
|
109
|
+
this.log.error(`IPC Provider behavior function ${pFunctionIndex} failed with error: ${pBehaviorFunctionError}`, pBehaviorFunctionError);
|
|
110
|
+
return fNext(pError);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
},
|
|
114
|
+
(fStageComplete)=>
|
|
115
|
+
{
|
|
116
|
+
return this.executePostBehaviorFunctions(pRequest, pResponse, fStageComplete);
|
|
117
|
+
}
|
|
118
|
+
],
|
|
119
|
+
(pRequestError)=>
|
|
120
|
+
{
|
|
121
|
+
if (pRequestError)
|
|
122
|
+
{
|
|
123
|
+
this.log.error(`IPC Provider behavior function ${pFunctionIndex} failed with error: ${pBehaviorFunctionError}`, pBehaviorFunctionError);
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
get(pRoute, ...fRouteProcessingFunctions)
|
|
132
|
+
{
|
|
133
|
+
if (!super.get(pRoute, ...fRouteProcessingFunctions))
|
|
134
|
+
{
|
|
135
|
+
this.log.error(`IPC provider failed to map GET route [${pRoute}]!`);
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return this.addRouteProcessor('GET', pRoute, Array.from(fRouteProcessingFunctions));
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
put(pRoute, ...fRouteProcessingFunctions)
|
|
143
|
+
{
|
|
144
|
+
if (!super.get(pRoute, ...fRouteProcessingFunctions))
|
|
145
|
+
{
|
|
146
|
+
this.log.error(`IPC provider failed to map PUT route [${pRoute}]!`);
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
post(pRoute, ...fRouteProcessingFunctions)
|
|
154
|
+
{
|
|
155
|
+
if (!super.get(pRoute, ...fRouteProcessingFunctions))
|
|
156
|
+
{
|
|
157
|
+
this.log.error(`IPC provider failed to map POST route [${pRoute}]!`);
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
del(pRoute, ...fRouteProcessingFunctions)
|
|
165
|
+
{
|
|
166
|
+
if (!super.get(pRoute, ...fRouteProcessingFunctions))
|
|
167
|
+
{
|
|
168
|
+
this.log.error(`IPC provider failed to map DEL route [${pRoute}]!`);
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
/*************************************************************************
|
|
175
|
+
* End of Service Route Creation Functions
|
|
176
|
+
*/
|
|
177
|
+
|
|
178
|
+
// Programmatically invoke a route
|
|
179
|
+
invoke(pMethod, pRoute, pData, fCallback)
|
|
180
|
+
{
|
|
181
|
+
// If the data is skipped and a callback is parameter 3, do the right thing
|
|
182
|
+
let tmpCallback = (typeof(fCallback) == 'function') ? fCallback :
|
|
183
|
+
(typeof(pData) == 'function') ? pData :
|
|
184
|
+
// This is here in case the developer passed no callback and just wants to fire and forget the IPC call which might not be async safe
|
|
185
|
+
()=>{};
|
|
186
|
+
|
|
187
|
+
// Create a bare minimum request object for IPC to pass to our router
|
|
188
|
+
let tmpRequest = (
|
|
189
|
+
{
|
|
190
|
+
method: pMethod,
|
|
191
|
+
url: pRoute,
|
|
192
|
+
guid: this.orator.fable.getUUID()
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
// Create a container for the IPC response data to be aggregated to from send() methodds
|
|
196
|
+
let tmpSynthesizedResponseData = new libOratorServiceServerIPCSynthesizedResponse(this.log, tmpRequest.guid);
|
|
197
|
+
|
|
198
|
+
return this.router.lookup(
|
|
199
|
+
tmpRequest,
|
|
200
|
+
tmpSynthesizedResponseData,
|
|
201
|
+
(pError, pResults)=>
|
|
202
|
+
{
|
|
203
|
+
if (pError)
|
|
204
|
+
{
|
|
205
|
+
this.log.error(`IPC Request Error Request GUID [${tmpRequest.guid}] handling route [${pRoute}]: ${pError}`, {Error: pError, Route: pRoute, Data: pData});
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// by default, send data back through
|
|
209
|
+
return tmpCallback(pError, tmpSynthesizedResponseData.responseData, tmpSynthesizedResponseData, pResults);
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
module.exports = OratorServiceServerIPC;
|