orator 3.0.10 → 4.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/debug/Harness.js +4 -8
- package/dist/orator.compatible.js +4889 -0
- package/dist/orator.compatible.min.js +17 -0
- package/dist/orator.compatible.min.js.map +1 -0
- package/dist/orator.js +979 -1727
- package/dist/orator.min.js +3 -24
- package/dist/orator.min.js.map +1 -1
- package/package.json +58 -66
- package/source/Orator-Default-ServiceServer-Web.js +4 -0
- package/source/Orator-Default-ServiceServer.js +4 -0
- package/source/Orator-ServiceServer-Base.js +8 -6
- package/source/Orator-ServiceServer-IPC-SynthesizedResponse.js +18 -1
- package/source/Orator-ServiceServer-IPC.js +111 -83
- package/source/Orator.js +139 -32
- package/test/Orator_basic_tests.js +43 -18
- package/test_legacy/Orator_basic_tests.js +1 -1
- package/test_legacy/Orator_cluster_test.js.deferred +1 -1
- package/test_legacy/Orator_logging_tests.js +1 -1
- package/source/Orator-Default-ServiceServers-Node.js +0 -21
- package/source/Orator-Default-ServiceServers-Web.js +0 -21
- /package/{test → debug/site}/Test.css +0 -0
- /package/{test → debug/site}/Test.html +0 -0
package/source/Orator.js
CHANGED
|
@@ -7,19 +7,19 @@
|
|
|
7
7
|
* @module Orator Service
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
const libFableServiceProviderBase = require('fable-serviceproviderbase');
|
|
11
|
+
|
|
12
|
+
const libDefaultOratorServiceServer = require('./Orator-Default-ServiceServer.js');
|
|
13
|
+
|
|
10
14
|
const defaultOratorConfiguration = require('./Orator-Default-Configuration.js');
|
|
11
|
-
const defaultOratorServiceServers = require('./Orator-Default-ServiceServers-Node.js');
|
|
12
15
|
|
|
13
|
-
class Orator
|
|
16
|
+
class Orator extends libFableServiceProviderBase
|
|
14
17
|
{
|
|
15
|
-
constructor(pFable,
|
|
18
|
+
constructor(pFable, pOptions, pServiceHash)
|
|
16
19
|
{
|
|
17
|
-
|
|
18
|
-
this.fable = pFable;
|
|
20
|
+
super(pFable, pOptions, pServiceHash);
|
|
19
21
|
|
|
20
|
-
|
|
21
|
-
this.settings = this.fable.settings;
|
|
22
|
-
this.log = this.fable.log;
|
|
22
|
+
this.serviceType = 'Orator';
|
|
23
23
|
|
|
24
24
|
// Create the empty, important logic containers
|
|
25
25
|
this.serviceServer = false;
|
|
@@ -31,42 +31,55 @@ class Orator
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
// Now check to see that the ServicePort is set (this used to be APIServerPort)
|
|
34
|
-
if (!this.
|
|
34
|
+
if (!this.options.hasOwnProperty('ServicePort'))
|
|
35
35
|
{
|
|
36
|
-
if (this.settings.hasOwnProperty('APIServerPort'))
|
|
36
|
+
if (this.fable.settings.hasOwnProperty('APIServerPort'))
|
|
37
37
|
{
|
|
38
38
|
// Automatically migrate the legacy APIServerPort to ServicePort
|
|
39
|
-
this.
|
|
39
|
+
this.options.ServicePort = this.fable.settings.APIServerPort;
|
|
40
40
|
}
|
|
41
41
|
else
|
|
42
42
|
{
|
|
43
43
|
// Default to whatever the ... default is!
|
|
44
|
-
this.
|
|
44
|
+
this.options.ServicePort = defaultOratorConfiguration.ServicePort;
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
// Now check to see that the Product name is set
|
|
49
|
-
if (!this.
|
|
49
|
+
if (!this.options.hasOwnProperty('Product'))
|
|
50
50
|
{
|
|
51
|
-
this.
|
|
51
|
+
this.options.Product = defaultOratorConfiguration.Product;
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
onBeforeInitialize()
|
|
56
56
|
{
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
if (this.fable.settings.LogNoisiness > 3)
|
|
58
|
+
{
|
|
59
|
+
this.log.trace(`Orator [${this.UUID}]::[${this.Hash}] ${this.options.Product} onBeforeInitialize:`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
onBeforeInitializeAsync(fNext)
|
|
63
|
+
{
|
|
64
|
+
this.onBeforeInitialize();
|
|
65
|
+
// Check to see if there is a service server active; if not instantiate one (and use IPC if none is registered with Fable as the default provider)
|
|
59
66
|
if (!this.serviceServer)
|
|
60
67
|
{
|
|
61
68
|
// If the developer hasn't set this to a service provider class of their own choosing,
|
|
69
|
+
// TODO: Give the developer a chance to set a service provider instantiation address of their own choosing.
|
|
62
70
|
// use the built-in network-less one.
|
|
63
|
-
if (!this.
|
|
71
|
+
if (!this.fable.OratorServiceServer)
|
|
64
72
|
{
|
|
65
|
-
|
|
73
|
+
// If there isn't a default Service Server setup, create one.
|
|
74
|
+
let tmpServiceServerOptions = (typeof(this.options.ServiceServerOptions) == 'undefined') ? {} : this.options.ServiceServerOptions;
|
|
75
|
+
if (!this.fable.serviceManager.servicesMap.hasOwnProperty('OratorServiceServer'))
|
|
76
|
+
{
|
|
77
|
+
// Only register IPC if there isn't one yet.
|
|
78
|
+
this.fable.serviceManager.addServiceType('OratorServiceServer', libDefaultOratorServiceServer);
|
|
79
|
+
}
|
|
80
|
+
this.fable.serviceManager.instantiateServiceProvider('OratorServiceServer', tmpServiceServerOptions, 'OratorServiceServer-AutoInit');
|
|
66
81
|
}
|
|
67
|
-
|
|
68
|
-
this.serviceServer = new this.serviceServerProvider(this);
|
|
69
|
-
|
|
82
|
+
this.serviceServer = this.fable.OratorServiceServer;
|
|
70
83
|
// For legacy reasons, we also will provide this under the "webServer" variable.
|
|
71
84
|
this.webServer = this.serviceServer;
|
|
72
85
|
}
|
|
@@ -74,15 +87,82 @@ class Orator
|
|
|
74
87
|
{
|
|
75
88
|
this.log.warn(`Orator attempting to initialize a service server after initialization has already completed.`)
|
|
76
89
|
}
|
|
90
|
+
fNext();
|
|
91
|
+
}
|
|
77
92
|
|
|
78
|
-
|
|
93
|
+
onInitialize()
|
|
94
|
+
{
|
|
95
|
+
if (this.fable.settings.LogNoisiness > 3)
|
|
96
|
+
{
|
|
97
|
+
this.log.trace(`Orator [${this.UUID}]::[${this.Hash}] ${this.options.Product} onInitialize:`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
onInitializeAsync(fNext)
|
|
101
|
+
{
|
|
102
|
+
this.onInitialize();
|
|
103
|
+
return fNext();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
onAfterInitialize()
|
|
107
|
+
{
|
|
108
|
+
if (this.fable.settings.LogNoisiness > 3)
|
|
109
|
+
{
|
|
110
|
+
this.log.trace(`Orator [${this.UUID}]::[${this.Hash}] ${this.options.Product} onAfterInitialize:`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
onAfterInitializeAsync(fNext)
|
|
114
|
+
{
|
|
115
|
+
this.onAfterInitialize();
|
|
116
|
+
return fNext();
|
|
79
117
|
}
|
|
80
118
|
|
|
81
|
-
|
|
119
|
+
initialize(fCallback)
|
|
82
120
|
{
|
|
121
|
+
// I hate this -- is there a reason to not require a callback?
|
|
122
|
+
let tmpCallback = (typeof(fCallback) === 'function') ? fCallback : () => {};
|
|
123
|
+
|
|
124
|
+
if (!this.initializeTimestamp)
|
|
125
|
+
{
|
|
126
|
+
let tmpAnticipate = this.fable.serviceManager.instantiateServiceProviderWithoutRegistration('Anticipate');
|
|
127
|
+
|
|
128
|
+
if (this.fable.LogNoisiness > 3)
|
|
129
|
+
{
|
|
130
|
+
this.log.trace(`Orator [${this.UUID}]::[${this.Hash}] ${this.options.Product} beginning initialization steps...`);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
tmpAnticipate.anticipate(this.onBeforeInitializeAsync.bind(this));
|
|
134
|
+
tmpAnticipate.anticipate(this.onInitializeAsync.bind(this));
|
|
135
|
+
tmpAnticipate.anticipate(this.onAfterInitializeAsync.bind(this));
|
|
136
|
+
|
|
137
|
+
tmpAnticipate.wait(
|
|
138
|
+
(pError) =>
|
|
139
|
+
{
|
|
140
|
+
this.initializeTimestamp = this.fable.log.getTimeStamp();
|
|
141
|
+
if (this.fable.LogNoisiness > 2)
|
|
142
|
+
{
|
|
143
|
+
this.log.trace(`Orator [${this.UUID}]::[${this.Hash}] ${this.options.Product} initialization steps complete.`);
|
|
144
|
+
}
|
|
145
|
+
return tmpCallback(pError);
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
else
|
|
149
|
+
{
|
|
150
|
+
this.log.warn(`Orator [${this.UUID}]::[${this.Hash}] ${this.options.Product} async initialize called but initialization is already completed. Aborting.`);
|
|
151
|
+
// TODO: Should this be returning an error?
|
|
152
|
+
return tmpCallback();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
onBeforeStartService(fNext)
|
|
157
|
+
{
|
|
158
|
+
return fNext();
|
|
159
|
+
}
|
|
160
|
+
onStartService(fNext)
|
|
161
|
+
{
|
|
162
|
+
this.onAfterInitialize();
|
|
83
163
|
return this.serviceServer.listen
|
|
84
164
|
(
|
|
85
|
-
this.
|
|
165
|
+
this.options.ServicePort,
|
|
86
166
|
(pError) =>
|
|
87
167
|
{
|
|
88
168
|
this.log.info(`${this.serviceServer.Name} listening at ${this.serviceServer.URL} port ${this.serviceServer.Port}`);
|
|
@@ -90,42 +170,68 @@ class Orator
|
|
|
90
170
|
}
|
|
91
171
|
);
|
|
92
172
|
}
|
|
173
|
+
onAfterStartService(fNext)
|
|
174
|
+
{
|
|
175
|
+
return fNext();
|
|
176
|
+
}
|
|
93
177
|
|
|
94
178
|
startService(fNext)
|
|
95
179
|
{
|
|
96
180
|
var tmpNext = (typeof(fNext) === 'function') ? fNext : ()=>{};
|
|
97
181
|
|
|
182
|
+
let tmpAnticipate = this.fable.serviceManager.instantiateServiceProviderWithoutRegistration('Anticipate');
|
|
183
|
+
|
|
184
|
+
if (this.fable.LogNoisiness > 3)
|
|
185
|
+
{
|
|
186
|
+
this.log.trace(`Orator [${this.UUID}]::[${this.Hash}] ${this.options.Product} beginning startService steps...`);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Auto initialize if there is no serviceServer
|
|
98
190
|
if (!this.serviceServer)
|
|
99
191
|
{
|
|
100
|
-
this.
|
|
192
|
+
tmpAnticipate.anticipate(this.initialize.bind(this));
|
|
101
193
|
}
|
|
102
194
|
|
|
103
|
-
|
|
195
|
+
tmpAnticipate.anticipate(this.onBeforeStartService.bind(this));
|
|
196
|
+
tmpAnticipate.anticipate(this.onStartService.bind(this));
|
|
197
|
+
tmpAnticipate.anticipate(this.onAfterStartService.bind(this));
|
|
198
|
+
|
|
199
|
+
tmpAnticipate.wait(
|
|
200
|
+
(pError) =>
|
|
201
|
+
{
|
|
202
|
+
this.startServiceTimestamp = this.fable.log.getTimeStamp();
|
|
203
|
+
if (this.fable.LogNoisiness > 2)
|
|
204
|
+
{
|
|
205
|
+
this.log.trace(`Orator [${this.UUID}]::[${this.Hash}] ${this.options.Product} startService steps complete.`);
|
|
206
|
+
}
|
|
207
|
+
return tmpNext(pError);
|
|
208
|
+
});
|
|
104
209
|
}
|
|
105
210
|
|
|
106
|
-
stopService(
|
|
211
|
+
stopService(fCallback)
|
|
107
212
|
{
|
|
108
|
-
var
|
|
213
|
+
var tmpCallback = (typeof(fCallback) === 'function') ? fCallback : ()=>{};
|
|
109
214
|
|
|
110
215
|
if (!this.serviceServer)
|
|
111
216
|
{
|
|
112
217
|
let tmpMessage = `Orator attempting to stop a service server but the service server has not been intialized yet.`;
|
|
113
218
|
this.log.warn(tmpMessage);
|
|
114
|
-
return
|
|
219
|
+
return tmpCallback(tmpMessage);
|
|
115
220
|
}
|
|
116
221
|
|
|
117
222
|
if (!this.serviceServer.Active)
|
|
118
223
|
{
|
|
119
224
|
let tmpMessage = `Orator attempting to stop a service server but the service server is not actively running.`;
|
|
120
225
|
this.log.warn(tmpMessage);
|
|
121
|
-
return
|
|
226
|
+
return tmpCallback(tmpMessage);
|
|
122
227
|
}
|
|
123
228
|
|
|
124
|
-
return this.serviceServer.close(
|
|
229
|
+
return this.serviceServer.close(tmpCallback);
|
|
125
230
|
}
|
|
126
231
|
|
|
127
232
|
invoke(pMethod, pRoute, pData, fCallback)
|
|
128
233
|
{
|
|
234
|
+
//this.log.trace(`Orator [${this.UUID}]::[${this.Hash}] ${this.options.Product} invoking ${pMethod} ${pRoute}`);
|
|
129
235
|
return this.serviceServer.invoke(pMethod, pRoute, pData, fCallback);
|
|
130
236
|
}
|
|
131
237
|
|
|
@@ -163,3 +269,4 @@ class Orator
|
|
|
163
269
|
|
|
164
270
|
module.exports = Orator;
|
|
165
271
|
module.exports.ServiceServerBase = require('./Orator-ServiceServer-Base.js');
|
|
272
|
+
module.exports.ServiceServerIPC = require('./Orator-ServiceServer-IPC.js');
|
|
@@ -14,11 +14,12 @@ const Assert = Chai.assert;
|
|
|
14
14
|
|
|
15
15
|
//const libSuperTest = require('supertest');
|
|
16
16
|
const libFable = require('fable');
|
|
17
|
-
|
|
17
|
+
|
|
18
|
+
const defaultFableSettings = (
|
|
18
19
|
{
|
|
19
20
|
Product:'Orator-BasicTests-Backplane',
|
|
20
21
|
ProductVersion: '0.0.0',
|
|
21
|
-
APIServerPort:
|
|
22
|
+
APIServerPort: 0
|
|
22
23
|
});
|
|
23
24
|
|
|
24
25
|
suite
|
|
@@ -36,11 +37,13 @@ suite
|
|
|
36
37
|
'initialize should build a happy little object',
|
|
37
38
|
(fDone) =>
|
|
38
39
|
{
|
|
39
|
-
let
|
|
40
|
+
let tmpFable = new libFable(defaultFableSettings);
|
|
41
|
+
tmpFable.serviceManager.addServiceType('Orator', libOrator);
|
|
42
|
+
let tmpOrator = tmpFable.serviceManager.instantiateServiceProvider('Orator', {});
|
|
40
43
|
Expect(tmpOrator).to.be.an('object', 'Orator should initialize as an object directly from the require statement.');
|
|
41
44
|
Expect(tmpOrator.startService).to.be.an('function');
|
|
42
|
-
Expect(tmpOrator.
|
|
43
|
-
tmpOrator.
|
|
45
|
+
Expect(tmpOrator.options).to.be.an('object');
|
|
46
|
+
tmpOrator.initialize(
|
|
44
47
|
(pError)=>
|
|
45
48
|
{
|
|
46
49
|
Expect(tmpOrator.serviceServer.ServiceServerType).to.equal('IPC', 'The default service server provider should be IPC.');
|
|
@@ -51,14 +54,36 @@ suite
|
|
|
51
54
|
|
|
52
55
|
test
|
|
53
56
|
(
|
|
54
|
-
'orator should be able to initialize and start a service with
|
|
57
|
+
'orator should be able to initialize and start a service with discrete steps for init and start',
|
|
55
58
|
(fDone) =>
|
|
56
59
|
{
|
|
57
|
-
let
|
|
58
|
-
|
|
59
|
-
tmpOrator.
|
|
60
|
+
let tmpFable = new libFable(defaultFableSettings);
|
|
61
|
+
tmpFable.serviceManager.addServiceType('Orator', libOrator);
|
|
62
|
+
let tmpOrator = tmpFable.serviceManager.instantiateServiceProvider('Orator', {});
|
|
60
63
|
// Start the service
|
|
61
|
-
|
|
64
|
+
tmpOrator.initialize(
|
|
65
|
+
() =>
|
|
66
|
+
{
|
|
67
|
+
Expect(tmpOrator.serviceServer.Active).to.equal(false);
|
|
68
|
+
tmpOrator.startService(
|
|
69
|
+
()=>
|
|
70
|
+
{
|
|
71
|
+
Expect(tmpOrator.serviceServer.Active).to.equal(true);
|
|
72
|
+
fDone();
|
|
73
|
+
});
|
|
74
|
+
})
|
|
75
|
+
}
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
test
|
|
79
|
+
(
|
|
80
|
+
'orator should be able to initialize IPC and start a service with no effort',
|
|
81
|
+
(fDone) =>
|
|
82
|
+
{
|
|
83
|
+
let tmpFable = new libFable(defaultFableSettings);
|
|
84
|
+
tmpFable.serviceManager.addServiceType('Orator', libOrator);
|
|
85
|
+
let tmpOrator = tmpFable.serviceManager.instantiateServiceProvider('Orator', {});
|
|
86
|
+
// Start the service, which will implicitly call initialize
|
|
62
87
|
tmpOrator.startService(
|
|
63
88
|
()=>
|
|
64
89
|
{
|
|
@@ -73,12 +98,11 @@ suite
|
|
|
73
98
|
'ipc should be able to provide basic endpoint functionality',
|
|
74
99
|
(fDone) =>
|
|
75
100
|
{
|
|
76
|
-
let
|
|
77
|
-
|
|
78
|
-
tmpOrator.
|
|
101
|
+
let tmpFable = new libFable(defaultFableSettings);
|
|
102
|
+
tmpFable.serviceManager.addServiceType('Orator', libOrator);
|
|
103
|
+
let tmpOrator = tmpFable.serviceManager.instantiateServiceProvider('Orator', {});
|
|
79
104
|
// Start the service
|
|
80
105
|
tmpOrator.startService();
|
|
81
|
-
|
|
82
106
|
tmpOrator.serviceServer.get
|
|
83
107
|
(
|
|
84
108
|
'/test/:hash',
|
|
@@ -109,9 +133,10 @@ suite
|
|
|
109
133
|
'ipc should be able to process any number of handler additions with the use function',
|
|
110
134
|
(fDone) =>
|
|
111
135
|
{
|
|
112
|
-
let
|
|
113
|
-
|
|
114
|
-
tmpOrator.
|
|
136
|
+
let tmpFable = new libFable(defaultFableSettings);
|
|
137
|
+
tmpFable.serviceManager.addServiceType('Orator', libOrator);
|
|
138
|
+
let tmpOrator = tmpFable.serviceManager.instantiateServiceProvider('Orator', {});
|
|
139
|
+
|
|
115
140
|
// Start the service
|
|
116
141
|
tmpOrator.startService();
|
|
117
142
|
|
|
@@ -130,7 +155,7 @@ suite
|
|
|
130
155
|
}
|
|
131
156
|
);
|
|
132
157
|
|
|
133
|
-
|
|
158
|
+
tmpFable.Utility.waterfall([
|
|
134
159
|
(fStageComplete) =>
|
|
135
160
|
{
|
|
136
161
|
let tmpURI = `/MagicEndpoint/BippityBoppityBoo`;
|
|
@@ -1,21 +0,0 @@
|
|
|
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();
|
|
@@ -1,21 +0,0 @@
|
|
|
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();
|
|
File without changes
|
|
File without changes
|