retold-data-service 1.0.3 → 1.0.4

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.
@@ -1,4 +1,10 @@
1
1
  {
2
2
  "optOut": false,
3
- "lastUpdateCheck": 1684950851047
3
+ "lastUpdateCheck": 1686012350867,
4
+ "update": {
5
+ "latest": "9.6.7",
6
+ "current": "6.14.18",
7
+ "type": "major",
8
+ "name": "npm"
9
+ }
4
10
  }
@@ -9,7 +9,7 @@
9
9
  "type": "node",
10
10
  "request": "launch",
11
11
  "outputCapture": "std",
12
- "cwd": "/home/coder/retold-data-service/debug/",
12
+ "cwd": "${workspaceFolder}/debug/",
13
13
  "skipFiles": [
14
14
  "<node_internals>/**"
15
15
  ],
@@ -56,8 +56,8 @@ RUN code-server --install-extension mtxr.sqltools-driver-mysql
56
56
  RUN echo "...configuring mariadb (mysql) server..."
57
57
  RUN sudo apt install default-mysql-server default-mysql-client -y
58
58
  RUN sudo sed -i "s|bind-address|#bind-address|g" /etc/mysql/mariadb.conf.d/50-server.cnf
59
- ADD ./debug/MySQL-Security.sql /home/coder/MySQL-Configure-Security.sql
60
- ADD ./debug/MySQL-Laden-Entry.sh /usr/bin/MySQL-Laden-Entry.sh
59
+ COPY ./debug/model/manual_scripts/MySQL-Security.sql /home/coder/MySQL-Configure-Security.sql
60
+ COPY ./debug/model/manual_scripts/MySQL-Laden-Entry.sh /usr/bin/MySQL-Laden-Entry.sh
61
61
  RUN ( sudo mysqld_safe --skip-grant-tables --skip-networking & ) && sleep 5 && mysql -u root < /home/coder/MySQL-Configure-Security.sql
62
62
 
63
63
  # Import the initial database
package/README.md CHANGED
@@ -1,27 +1,37 @@
1
1
  # Retold Data Service
2
2
 
3
- Provide a consistent back or mid-tier data service.
3
+ Provide a consistent back or mid-tier data service with boilerplate tooling
4
+ abstracted behind configuration. Leaving a simple mechanism to add complexity
5
+ where desired.
4
6
 
5
7
  ## Basic Usage
6
8
 
7
- This library can run in any of three types of configurations:
9
+ This library is meant to be run in any of three types of configurations:
8
10
 
9
11
  * Configuration Driven
10
12
  * Managed via Backplane Endpoints
11
13
  * Hybrid (configuration plus endpoint)
12
14
 
15
+ Currently only configuration driven mode is implemented.
16
+
13
17
  ## Configuration-Driven Mode
14
18
 
15
- The service looks for a `Retold` stanza in the configuration. For instance:
19
+ By default this service looks in a relative `model/Model-Extended.json` from the CWD
20
+ for the schemas.
16
21
 
17
- ```
18
- {
19
- ...
20
- "Retold": {
21
- "MeadowModel": "./meadow-schema-extended.json"
22
- },
23
- ...
24
- }
22
+ Default configuration:
23
+
24
+ ```js
25
+ {
26
+ FullMeadowSchemaPath: `${process.cwd()}/model/`,
27
+ FullMeadowSchemaFilename: `Model-Extended.json`,
28
+
29
+ DALMeadowSchemaPath: `${process.cwd()}/model/meadow/`,
30
+ DALMeadowSchemaPrefix: `Model-MeadowSchema-`,
31
+ DALMeadowSchemaPostfix: ``,
32
+
33
+ AutoStartOrator: true
34
+ })
25
35
  ```
26
36
 
27
37
  The three auto-configured parameters are:
package/debug/Harness.js CHANGED
@@ -3,33 +3,51 @@ const _Settings = require('./bookstore-configuration.json');
3
3
  const libFable = require('fable');
4
4
 
5
5
  _Fable = new libFable(_Settings);
6
- _Fable.serviceManager.addAndInstantiateServiceType('RetoldDataService', require('../source/Retold-Data-Service.js'));
6
+ let libRetoldDataService = _Fable.serviceManager.addAndInstantiateServiceType('RetoldDataService', require('../source/Retold-Data-Service.js'));
7
7
 
8
- _Fable.MeadowEndpoints.Book.controller.BehaviorInjection.setBehavior('Read-PostOperation',
9
- (pRequest, pRequestState, fComplete) =>
8
+ libRetoldDataService.onAfterInitializeAsync =
9
+ (fAfterInitializeComplete) =>
10
10
  {
11
- // Get the join records
12
- _Fable.DAL.BookAuthorJoin.doReads(_Fable.DAL.BookAuthorJoin.query.addFilter('IDBook', pRequestState.Record.IDBook),
13
- (pJoinReadError, pJoinReadQuery, pJoinRecords)=>
11
+ // Create a post operation behavior for the book Read singular record endpoint only
12
+ _Fable.MeadowEndpoints.Book.controller.BehaviorInjection.setBehavior('Read-PostOperation',
13
+ (pRequest, pRequestState, fRequestComplete) =>
14
14
  {
15
- let tmpAuthorList = [];
16
- for (let j = 0; j < pJoinRecords.length; j++)
17
- {
18
- tmpAuthorList.push(pJoinRecords[j].IDAuthor);
19
- }
20
- if (tmpAuthorList.length < 1)
21
- {
22
- pRequestState.Record.Authors = [];
23
- return fComplete();
24
- }
25
- else
26
- {
27
- _Fable.DAL.Author.doReads(_Fable.DAL.Author.query.addFilter('IDAuthor', tmpAuthorList, 'IN'),
28
- (pReadsError, pReadsQuery, pAuthors)=>
15
+ // Get the join records
16
+ _Fable.DAL.BookAuthorJoin.doReads(_Fable.DAL.BookAuthorJoin.query.addFilter('IDBook', pRequestState.Record.IDBook),
17
+ (pJoinReadError, pJoinReadQuery, pJoinRecords)=>
18
+ {
19
+ let tmpAuthorList = [];
20
+ for (let j = 0; j < pJoinRecords.length; j++)
29
21
  {
30
- pRequestState.Record.Authors = pAuthors;
31
- return fComplete();
32
- });
33
- }
22
+ tmpAuthorList.push(pJoinRecords[j].IDAuthor);
23
+ }
24
+ if (tmpAuthorList.length < 1)
25
+ {
26
+ _Fable.log.trace(`Found no authors for IDBook ${pRequestState.Record.IDBook} (${pRequestState.Record.Title}). What even is a book without authors?`)
27
+ pRequestState.Record.Authors = [];
28
+ return fRequestComplete();
29
+ }
30
+ else
31
+ {
32
+ _Fable.DAL.Author.doReads(_Fable.DAL.Author.query.addFilter('IDAuthor', tmpAuthorList, 'IN'),
33
+ (pReadsError, pReadsQuery, pAuthors)=>
34
+ {
35
+ pRequestState.Record.Authors = pAuthors;
36
+ _Fable.log.info(`Found ${pAuthors.length} authors for IDBook ${pRequestState.Record.IDBook} (${pRequestState.Record.Title}).`)
37
+ return fRequestComplete();
38
+ });
39
+ }
40
+ });
34
41
  });
42
+
43
+ return fAfterInitializeComplete();
44
+ };
45
+
46
+ libRetoldDataService.initializeAsync(
47
+ (pError) =>
48
+ {
49
+ if (pError)
50
+ {
51
+ _Fable.log.error(`Error initializing `)
52
+ }
35
53
  });
@@ -14,7 +14,7 @@
14
14
  }
15
15
  ],
16
16
 
17
- "APIServerPort": 8086,
17
+ "APIServerPort": 7765,
18
18
 
19
19
  "MySQL":
20
20
  {
package/package.json CHANGED
@@ -1,73 +1,60 @@
1
1
  {
2
- "name": "retold-data-service",
3
- "version": "1.0.3",
4
- "description": "Serve up a whole model!",
5
- "main": "source/Retold-Data-Service.js",
6
- "scripts": {
7
- "start": "node source/Retold-Data-Service.js",
8
- "coverage": "./node_modules/.bin/nyc --reporter=lcov --reporter=text-lcov ./node_modules/mocha/bin/_mocha -- -u tdd -R spec",
9
- "test": "./node_modules/.bin/mocha -u tdd -R spec",
10
- "build": "./node_modules/.bin/gulp build",
11
- "build-compatible": "GULP_CUSTOM_BUILD_TARGET=compatible ./node_modules/.bin/gulp build",
12
- "docker-dev-build": "docker build ./ -f Dockerfile_LUXURYCode -t retold/retold-data-service:local",
13
- "docker-dev-run": "docker run -it -d --name retold-retold-data-service-dev -p 44444:8080 -p 48086:8086 -v \"$PWD/.config:/home/coder/.config\" -v \"$PWD:/home/coder/retold-data-service\" -u \"$(id -u):$(id -g)\" -e \"DOCKER_USER=$USER\" retold/retold-data-service:local",
14
- "docker-dev-shell": "docker exec -it retold-retold-data-service-dev /bin/bash"
15
- },
16
- "mocha": {
17
- "diff": true,
18
- "extension": [
19
- "js"
2
+ "name": "retold-data-service",
3
+ "version": "1.0.4",
4
+ "description": "Serve up a whole model!",
5
+ "main": "source/Retold-Data-Service.js",
6
+ "scripts": {
7
+ "start": "node source/Retold-Data-Service.js",
8
+ "coverage": "./node_modules/.bin/nyc --reporter=lcov --reporter=text-lcov ./node_modules/mocha/bin/_mocha -- -u tdd -R spec",
9
+ "test": "./node_modules/.bin/mocha -u tdd -R spec",
10
+ "build": "npx quack build",
11
+ "docker-dev-build": "docker build ./ -f Dockerfile_LUXURYCode -t retold-data-service-image:local",
12
+ "docker-dev-run": "docker run -it -d --name retold-data-service-dev -p 44444:8080 -p 43306:3306 -p 8086:8086 -v \"$PWD/.config:/home/coder/.config\" -v \"$PWD:/home/coder/retold-data-service\" -u \"$(id -u):$(id -g)\" -e \"DOCKER_USER=$USER\" retold-data-service-image:local",
13
+ "docker-dev-shell": "docker exec -it retold-data-service-dev /bin/bash"
14
+ },
15
+ "mocha": {
16
+ "diff": true,
17
+ "extension": [
18
+ "js"
19
+ ],
20
+ "package": "./package.json",
21
+ "reporter": "spec",
22
+ "slow": "75",
23
+ "timeout": "5000",
24
+ "ui": "tdd",
25
+ "watch-files": [
26
+ "source/**/*.js",
27
+ "test/**/*.js"
28
+ ],
29
+ "watch-ignore": [
30
+ "lib/vendor"
31
+ ]
32
+ },
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "https://github.com/stevenvelozo/retold-data-service.git"
36
+ },
37
+ "keywords": [
38
+ "entity",
39
+ "behavior",
40
+ "api"
20
41
  ],
21
- "package": "./package.json",
22
- "reporter": "spec",
23
- "slow": "75",
24
- "timeout": "5000",
25
- "ui": "tdd",
26
- "watch-files": [
27
- "source/**/*.js",
28
- "test/**/*.js"
29
- ],
30
- "watch-ignore": [
31
- "lib/vendor"
32
- ]
33
- },
34
- "repository": {
35
- "type": "git",
36
- "url": "https://github.com/stevenvelozo/retold-data-service.git"
37
- },
38
- "keywords": [
39
- "entity",
40
- "behavior"
41
- ],
42
- "author": "Steven Velozo <steven@velozo.com> (http://velozo.com/)",
43
- "license": "MIT",
44
- "bugs": {
45
- "url": "https://github.com/stevenvelozo/retold-data-service/issues"
46
- },
47
- "homepage": "https://github.com/stevenvelozo/retold-data-service",
48
- "devDependencies": {
49
- "@babel/core": "^7.21.8",
50
- "@babel/preset-env": "^7.21.5",
51
- "browserify": "^17.0.0",
52
- "chai": "4.3.7",
53
- "gulp": "^4.0.2",
54
- "gulp-babel": "^8.0.0",
55
- "gulp-env": "^0.4.0",
56
- "gulp-sourcemaps": "^3.0.0",
57
- "gulp-terser": "^2.1.0",
58
- "gulp-util": "^3.0.8",
59
- "mocha": "10.2.0",
60
- "nyc": "^15.1.0",
61
- "vinyl-buffer": "^1.0.1",
62
- "vinyl-source-stream": "^2.0.0"
63
- },
64
- "dependencies": {
65
- "fable": "^3.0.46",
66
- "fable-serviceproviderbase": "^3.0.4",
67
- "meadow": "^2.0.5",
68
- "meadow-connection-mysql": "^1.0.2",
69
- "meadow-endpoints": "^4.0.2",
70
- "orator": "^3.0.11",
71
- "orator-serviceserver-restify": "^1.0.4"
72
- }
42
+ "author": "Steven Velozo <steven@velozo.com> (http://velozo.com/)",
43
+ "license": "MIT",
44
+ "bugs": {
45
+ "url": "https://github.com/stevenvelozo/retold-data-service/issues"
46
+ },
47
+ "homepage": "https://github.com/stevenvelozo/retold-data-service",
48
+ "devDependencies": {
49
+ "quackage": "^1.0.24"
50
+ },
51
+ "dependencies": {
52
+ "fable": "^3.0.96",
53
+ "fable-serviceproviderbase": "^3.0.12",
54
+ "meadow": "^2.0.15",
55
+ "meadow-connection-mysql": "^1.0.4",
56
+ "meadow-endpoints": "^4.0.2",
57
+ "orator": "^4.0.2",
58
+ "orator-serviceserver-restify": "^2.0.2"
59
+ }
73
60
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Retold Data Service
3
- *
3
+ *
4
4
  * All-in-one add-ins for fable to provide endpoints.
5
5
  *
6
6
  * @author Steven Velozo <steven@velozo.com>
@@ -8,6 +8,7 @@
8
8
  const libFableServiceProviderBase = require('fable-serviceproviderbase');
9
9
 
10
10
  const libOrator = require('orator');
11
+ const libOratorServiceServerRestify = require('orator-serviceserver-restify');
11
12
  const libMeadow = require('meadow');
12
13
  const libMeadowEndpoints = require('meadow-endpoints');
13
14
 
@@ -15,12 +16,11 @@ const defaultDataServiceSettings = (
15
16
  {
16
17
  FullMeadowSchemaPath: `${process.cwd()}/model/`,
17
18
  FullMeadowSchemaFilename: `Model-Extended.json`,
18
-
19
+
19
20
  DALMeadowSchemaPath: `${process.cwd()}/model/meadow/`,
20
21
  DALMeadowSchemaPrefix: `Model-MeadowSchema-`,
21
22
  DALMeadowSchemaPostfix: ``,
22
23
 
23
- AutoInitializeDataService: true,
24
24
  AutoStartOrator: true
25
25
  });
26
26
 
@@ -33,57 +33,19 @@ class RetoldDataService extends libFableServiceProviderBase
33
33
  this.serviceType = 'RetoldDataService';
34
34
 
35
35
  this.options = this.fable.Utility.extend(defaultDataServiceSettings, this.options);
36
+ }
36
37
 
37
- // TODO: Check if Fable already has an Orator service provider, otherwise add one.
38
- // TODO: First switch the new Orator to the new service provider pattern
39
- // TODO: Make the restify/http stuff optional, so IPC works.
40
- // Orator is the (usually web) server
41
- this.fable.Orator = new libOrator(this.fable, require('orator-serviceserver-restify'));
42
-
43
- // Because this requires the callback, we will have to add better plumbing for these services to initialie
44
- this.fable.Orator.initializeServiceServer(() =>
45
- {
46
- // TODO: This code will be much cleaner with these as services
47
- this._Meadow = libMeadow.new(_Fable);
48
-
49
- // Create DAL objects for each table in the schema
50
- // These will be unnecessary when meadow and meadow-endpoints are full fledged fable services
51
- this._DAL = {};
52
- this.fable.DAL = this._DAL;
53
- this._MeadowEndpoints = {};
54
- this.fable.MeadowEndpoints = this._MeadowEndpoints;
55
-
56
- // TODO: Change this to an option (e.g. we might want to do ALASQL)
57
- // Load the mysql connection for meadow if it doesn't exist yet
58
- _Fable.serviceManager.addAndInstantiateServiceType('MeadowMySQLProvider', require('meadow-connection-mysql'));
59
-
60
- this.fullModel = false;
61
- this.entityList = false;
62
-
63
- this.serviceInitialized = false;
64
-
65
- if (this.options.AutoInitializeDataService)
66
- {
67
- this.fable.log.info(`The Retold Data Service is Auto Initializing itself`);
68
- this.initializeService();
69
- }
70
-
71
- if (this.options.AutoStartOrator)
72
- {
73
- this.fable.log.info(`The Retold Data Service is Auto Starting Orator`);
74
- this.fable.Orator.startWebServer(
75
- (pError) =>
76
- {
77
- if (pError)
78
- {
79
- console.log(`Error auto-starting Orator: ${pError}`, pError);
80
- }
81
- });
82
- }
83
- });
38
+ onBeforeInitializeAsync(fCallback)
39
+ {
40
+ this.onBeforeInitialize();
41
+ return fCallback();
42
+ }
43
+ onBeforeInitialize()
44
+ {
45
+ this.log.info("Retold Data Service Application is beginning initialization...");
84
46
  }
85
47
 
86
- initializeService()
48
+ initializeAsync(fCallback)
87
49
  {
88
50
  if (this.serviceInitialized)
89
51
  {
@@ -91,42 +53,149 @@ class RetoldDataService extends libFableServiceProviderBase
91
53
  }
92
54
  else
93
55
  {
94
- this.fable.log.info("Retold Data Service Application is starting up...");
95
-
96
- // Create DAL objects for each table in the schema
97
-
98
- // 1. Load full compiled schema of the model from stricture
99
- _Fable.log.info(`...loading full model stricture schema...`);
100
- this.fullModel = require (`${this.options.FullMeadowSchemaPath}${this.options.FullMeadowSchemaFilename}`);
101
- _Fable.log.info(`...full model stricture schema loaded.`);
102
-
103
- // 2. Extract an array of each table in the schema
104
- _Fable.log.info(`...getting entity list...`);
105
- this.entityList = Object.keys(this.fullModel.Tables);
106
-
107
- // 3. Enumerate each entry in the compiled model and load a DAL for that table
108
- _Fable.log.info(`...initializing ${this.entityList.length} DAL objects and corresponding Meadow Endpoints...`);
109
- for (let i = 0; i < this.entityList.length; i++)
110
- {
111
- // 4. Create the DAL for each entry (e.g. it would be at _DAL.Movie for the Movie entity)
112
- let tmpDALEntityName = this.entityList[i];
113
- let tmpDALPackageFile = `${this.options.DALMeadowSchemaPath}${this.options.DALMeadowSchemaPrefix}${tmpDALEntityName}${this.options.DALMeadowSchemaPostfix}.json`
114
- _Fable.log.info(`Initializing the ${tmpDALEntityName} DAL from [${tmpDALPackageFile}]...`);
115
- this._DAL[tmpDALEntityName] = this._Meadow.loadFromPackage(tmpDALPackageFile);
116
- // 5. Tell this DAL object to use MySQL
117
- _Fable.log.info(`...defaulting the ${tmpDALEntityName} DAL to use MySQL`);
118
- this._DAL[tmpDALEntityName].setProvider('MySQL');
119
- // 6. Create a Meadow Endpoints class for this DAL
120
- _Fable.log.info(`...initializing the ${tmpDALEntityName} Meadow Endpoints to use MySQL`);
121
- this._MeadowEndpoints[tmpDALEntityName] = libMeadowEndpoints.new(this._DAL[tmpDALEntityName]);
122
- // 8. Expose the meadow endpoints on Orator
123
- _Fable.log.info(`...mapping the ${tmpDALEntityName} Meadow Endpoints to Orator`);
124
- this._MeadowEndpoints[tmpDALEntityName].connectRoutes(this.fable.Orator.webServer);
125
- }
126
-
127
- this.serviceInitialized = true;
56
+ let tmpAnticipate = this.fable.instantiateServiceProviderWithoutRegistration('Anticipate');
57
+ // Phase I: Allow the API host to inject behavior before anything magic happens.
58
+ tmpAnticipate.anticipate(this.onBeforeInitializeAsync.bind(this));
59
+ // Phase II: Make sure there is an Orator server available so we can put the behaviors somewhere
60
+ tmpAnticipate.anticipate(
61
+ function (fCallback)
62
+ {
63
+ // Check if Fable already has an Orator service provider, otherwise add one.
64
+ if (!this.fable.serviceClasses.hasOwnProperty('OratorServiceServer'))
65
+ {
66
+ this.fable.serviceManager.addAndInstantiateServiceType('OratorServiceServer', libOratorServiceServerRestify, this.fable.settings);
67
+ }
68
+ else if (!this.fable.OratorServiceServer)
69
+ {
70
+ this.fable.serviceManager.instantiateServiceProvider('OratorServiceServer', this.fable.settings);
71
+ }
72
+ return fCallback();
73
+ }.bind(this));
74
+ tmpAnticipate.anticipate(
75
+ function (fCallback)
76
+ {
77
+ // Check if Fable already has an Orator service provider, otherwise add one.
78
+ if (!this.fable.serviceClasses.hasOwnProperty('Orator'))
79
+ {
80
+ this.fable.serviceManager.addAndInstantiateServiceType('Orator', libOrator, this.fable.settings);
81
+ }
82
+ else if (!this.fable.Orator)
83
+ {
84
+ this.fable.serviceManager.instantiateServiceProvider('Orator', this.fable.settings);
85
+ }
86
+ return fCallback();
87
+ }.bind(this));
88
+ // Phase III: Initialize orator
89
+ tmpAnticipate.anticipate(this.fable.Orator.initialize.bind(this.fable.Orator));
90
+ // Phase IV: Initialize Meadow (this will simplify greatly when meadow and meadow-endpoints are service-ized)
91
+ tmpAnticipate.anticipate(
92
+ function (fCallback)
93
+ {
94
+ // TODO: This code will be much cleaner with meadow and meadow-endpoints as a service. They are the only toolchain that is left!
95
+ this._Meadow = libMeadow.new(_Fable);
96
+
97
+ // Create DAL objects for each table in the schema
98
+ // These will be unnecessary when meadow and meadow-endpoints are full fledged fable services and then
99
+ // refactored to auto-initialize on a schema provider.
100
+ // For now, this is a mock of how we expect that service to provide interfaces to DAL objects.
101
+ this._DAL = {};
102
+ this.fable.DAL = this._DAL;
103
+ // And a mock of how the endpoints will be expressed.
104
+ this._MeadowEndpoints = {};
105
+ this.fable.MeadowEndpoints = this._MeadowEndpoints;
106
+
107
+ // TODO: This goes away when the above use services in a sane fashion.
108
+ // Load the mysql connection for meadow if it doesn't exist yet
109
+ _Fable.serviceManager.addAndInstantiateServiceType('MeadowMySQLProvider', require('meadow-connection-mysql'));
110
+
111
+ this.fullModel = false;
112
+ this.entityList = false;
113
+
114
+ this.serviceInitialized = false;
115
+
116
+ return fCallback();
117
+ }.bind(this));
118
+ // Phase V: Initialize the meat of the matter (the retold data service)
119
+ tmpAnticipate.anticipate(
120
+ function(fCallback)
121
+ {
122
+ this.fable.log.info("Retold Data Service DAL methods initializing...");
123
+
124
+ // Create DAL objects for each table in the schema
125
+ // 1. Load full compiled schema of the model from stricture
126
+ _Fable.log.info(`...loading full model stricture schema...`);
127
+ this.fullModel = require (`${this.options.FullMeadowSchemaPath}${this.options.FullMeadowSchemaFilename}`);
128
+ _Fable.log.info(`...full model stricture schema loaded.`);
129
+
130
+ // 2. Extract an array of each table in the schema
131
+ _Fable.log.info(`...getting entity list...`);
132
+ this.entityList = Object.keys(this.fullModel.Tables);
133
+
134
+ // 3. Enumerate each entry in the compiled model and load a DAL for that table
135
+ _Fable.log.info(`...initializing ${this.entityList.length} DAL objects and corresponding Meadow Endpoints...`);
136
+ for (let i = 0; i < this.entityList.length; i++)
137
+ {
138
+ // 4. Create the DAL for each entry (e.g. it would be at _DAL.Movie for the Movie entity)
139
+ let tmpDALEntityName = this.entityList[i];
140
+ let tmpDALPackageFile = `${this.options.DALMeadowSchemaPath}${this.options.DALMeadowSchemaPrefix}${tmpDALEntityName}${this.options.DALMeadowSchemaPostfix}.json`
141
+ _Fable.log.info(`Initializing the ${tmpDALEntityName} DAL from [${tmpDALPackageFile}]...`);
142
+ this._DAL[tmpDALEntityName] = this._Meadow.loadFromPackage(tmpDALPackageFile);
143
+ // 5. Tell this DAL object to use MySQL
144
+ _Fable.log.info(`...defaulting the ${tmpDALEntityName} DAL to use MySQL`);
145
+ this._DAL[tmpDALEntityName].setProvider('MySQL');
146
+ // 6. Create a Meadow Endpoints class for this DAL
147
+ _Fable.log.info(`...initializing the ${tmpDALEntityName} Meadow Endpoints to use MySQL`);
148
+ this._MeadowEndpoints[tmpDALEntityName] = libMeadowEndpoints.new(this._DAL[tmpDALEntityName]);
149
+ // 8. Expose the meadow endpoints on Orator
150
+ _Fable.log.info(`...mapping the ${tmpDALEntityName} Meadow Endpoints to Orator`);
151
+ this._MeadowEndpoints[tmpDALEntityName].connectRoutes(this.fable.Orator.webServer);
152
+ }
153
+
154
+ this.serviceInitialized = true;
155
+
156
+ return fCallback();
157
+ }.bind(this));
158
+ // Phase VI: Optionally auto start the orator server.
159
+ tmpAnticipate.anticipate(
160
+ function (fCallback)
161
+ {
162
+ if (this.options.AutoStartOrator)
163
+ {
164
+ this.fable.log.info(`The Retold Data Service is Auto Starting Orator...`);
165
+ this.fable.Orator.startWebServer(fCallback);
166
+ }
167
+ else
168
+ {
169
+ return fCallback();
170
+ }
171
+ }.bind(this));
172
+ tmpAnticipate.anticipate(this.onAfterInitializeAsync.bind(this));
173
+
174
+ // Now anticipate (wait for) initialization to complete.
175
+ tmpAnticipate.wait(
176
+ function (pError)
177
+ {
178
+ if (pError)
179
+ {
180
+ let tmpErrorMessage = `Error initializing Retold Data Service: ${pError}`;
181
+ this.log.error(tmpErrorMessage);
182
+ // TODO: Should this bubble up? I think not.
183
+ throw new Error(tmpErrorMessage);
184
+ }
185
+ return fCallback();
186
+ }.bind(this));
128
187
  }
129
188
  }
189
+
190
+ onAfterInitializeAsync(fCallback)
191
+ {
192
+ this.onAfterInitialize();
193
+ return fCallback();
194
+ }
195
+ onAfterInitialize()
196
+ {
197
+ this.log.info("Retold Data Service Application has completed an initialization attempt.");
198
+ }
130
199
  }
131
200
 
132
201
  module.exports = RetoldDataService;
@@ -8,7 +8,6 @@
8
8
 
9
9
  var Chai = require("chai");
10
10
  var Expect = Chai.expect;
11
- var Assert = Chai.assert;
12
11
 
13
12
  const libFable = require('fable');
14
13
 
@@ -42,9 +41,13 @@ suite
42
41
  AutoStartOrator: true
43
42
  });
44
43
 
45
- tmpRetoldDataService.initializeService();
44
+ Expect(tmpRetoldDataService).to.be.an('object', 'Retold Data Service should initialize as an object.');
46
45
 
47
- return fDone();
46
+ tmpRetoldDataService.initializeAsync(
47
+ function(pError)
48
+ {
49
+ return fDone();
50
+ });
48
51
  }
49
52
  );
50
53
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "Product": "MeadowEndpointsTest",
3
3
 
4
- "APIServerPort": 8088,
4
+ "APIServerPort": 7764,
5
5
 
6
6
  "MySQL":
7
7
  {
@@ -1,41 +0,0 @@
1
- /*
2
- An example of Meadow Endpoints, Fable and Orator
3
- */
4
-
5
- /**
6
- * @license MIT
7
- * @author <steven@velozo.com>
8
- */
9
-
10
- // Server Settings
11
- let fStartServiceServer = (fInitializeCallback) =>
12
- {
13
- _Orator.initializeServiceServer(() =>
14
- {
15
-
16
-
17
- // 100. Add a post processing hook to the Book DAL on single reads
18
- /*
19
- This post processing step will look for all book author joins then
20
- load all appropriate authors and stuff them in the book record before
21
- returning it.
22
- */
23
-
24
-
25
- // Static site mapping
26
- _Orator.log.info("...Mapping static route for web site...");
27
-
28
- //_Orator.addStaticRoute(__dirname+'/../web/');
29
-
30
- // Start the web server (ctrl+c to end it)
31
- _Orator.startWebServer(
32
- (pError) =>
33
- {
34
- fInitializeCallback(pError);
35
- }
36
- );
37
- });
38
- return _Orator;
39
- }
40
-
41
- module.exports = fStartServiceServer;