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/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, pServiceProvider)
18
+ constructor(pFable, pOptions, pServiceHash)
16
19
  {
17
- // We were passed a fully operational fable -- use this
18
- this.fable = pFable;
20
+ super(pFable, pOptions, pServiceHash);
19
21
 
20
- // Carry core application requirements into the orator object for simplicity
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.settings.hasOwnProperty('ServicePort'))
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.settings.ServicePort = this.fable.settings.APIServerPort;
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.settings.ServicePort = defaultOratorConfiguration.ServicePort;
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.settings.hasOwnProperty('Product'))
49
+ if (!this.options.hasOwnProperty('Product'))
50
50
  {
51
- this.settings.Product = defaultOratorConfiguration.Product;
51
+ this.options.Product = defaultOratorConfiguration.Product;
52
52
  }
53
53
  }
54
54
 
55
- initializeServiceServer(fNext)
55
+ onBeforeInitialize()
56
56
  {
57
- var tmpNext = (typeof(fNext) === 'function') ? fNext : ()=>{};
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.serviceServerProvider)
71
+ if (!this.fable.OratorServiceServer)
64
72
  {
65
- this.serviceServerProvider = defaultOratorServiceServers.default;
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
- return tmpNext()
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
- _startServiceListener(fNext)
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.settings.ServicePort,
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.initializeServiceServer();
192
+ tmpAnticipate.anticipate(this.initialize.bind(this));
101
193
  }
102
194
 
103
- return this._startServiceListener(tmpNext);
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(fNext)
211
+ stopService(fCallback)
107
212
  {
108
- var tmpNext = (typeof(fNext) === 'function') ? fNext : ()=>{};
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 tmpNext(tmpMessage);
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 tmpNext(tmpMessage);
226
+ return tmpCallback(tmpMessage);
122
227
  }
123
228
 
124
- return this.serviceServer.close(tmpNext);
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
- const _Fable = new libFable(
17
+
18
+ const defaultFableSettings = (
18
19
  {
19
20
  Product:'Orator-BasicTests-Backplane',
20
21
  ProductVersion: '0.0.0',
21
- APIServerPort: 8099
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 tmpOrator = new libOrator(_Fable);
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.settings).to.be.an('object');
43
- tmpOrator.initializeServiceServer(
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 no effort',
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 tmpOrator = new libOrator(_Fable);
58
- // Start the service server
59
- tmpOrator.initializeServiceServer();
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
- Expect(tmpOrator.serviceServer.Active).to.equal(false);
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 tmpOrator = new libOrator(_Fable);
77
- // Initialize the service server
78
- tmpOrator.initializeServiceServer();
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 tmpOrator = new libOrator(_Fable);
113
- // Initialize the service server
114
- tmpOrator.initializeServiceServer();
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
- _Fable.Utility.waterfall([
158
+ tmpFable.Utility.waterfall([
134
159
  (fStageComplete) =>
135
160
  {
136
161
  let tmpURI = `/MagicEndpoint/BippityBoppityBoo`;
@@ -150,7 +150,7 @@ suite
150
150
  .end(
151
151
  function (pError, pResponse)
152
152
  {
153
- _Orator.settings.Profiling.TraceLog = true;
153
+ _Orator.options.Profiling.TraceLog = true;
154
154
  Expect(pResponse.text)
155
155
  .to.contain('50000px');
156
156
  libSuperTest('http://localhost:8099/')
@@ -152,7 +152,7 @@ suite
152
152
  .end(
153
153
  function (pError, pResponse)
154
154
  {
155
- _Orator.settings.Profiling.TraceLog = true;
155
+ _Orator.options.Profiling.TraceLog = true;
156
156
  Expect(pResponse.text)
157
157
  .to.contain('50000px');
158
158
  libSuperTest('http://localhost:8099/')
@@ -116,7 +116,7 @@ suite
116
116
  .to.contain('dire');
117
117
  }
118
118
  // Next uncaught exception should be passed through without logging the stack trace
119
- _Orator.settings.LogStackTraces = false;
119
+ _Orator.options.LogStackTraces = false;
120
120
  fDone();
121
121
  }
122
122
  );
@@ -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