fiftyone.pipeline.cloudrequestengine 4.4.54 → 4.4.56

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/cloudEngine.js CHANGED
@@ -1,23 +1,23 @@
1
- /* *********************************************************************
2
- * This Original Work is copyright of 51 Degrees Mobile Experts Limited.
3
- * Copyright 2023 51 Degrees Mobile Experts Limited, Davidson House,
4
- * Forbury Square, Reading, Berkshire, United Kingdom RG1 3EU.
5
- *
6
- * This Original Work is licensed under the European Union Public Licence
7
- * (EUPL) v.1.2 and is subject to its terms as set out below.
8
- *
9
- * If a copy of the EUPL was not distributed with this file, You can obtain
10
- * one at https://opensource.org/licenses/EUPL-1.2.
11
- *
12
- * The 'Compatible Licences' set out in the Appendix to the EUPL (as may be
13
- * amended by the European Commission) shall be deemed incompatible for
14
- * the purposes of the Work and the provisions of the compatibility
15
- * clause in Article 5 of the EUPL shall not apply.
16
- *
17
- * If using the Work as, or as part of, a network application, by
18
- * including the attribution notice(s) required under Article 5 of the EUPL
19
- * in the end user terms of the application under an appropriate heading,
20
- * such notice(s) shall fulfill the requirements of that article.
1
+ /* *********************************************************************
2
+ * This Original Work is copyright of 51 Degrees Mobile Experts Limited.
3
+ * Copyright 2023 51 Degrees Mobile Experts Limited, Davidson House,
4
+ * Forbury Square, Reading, Berkshire, United Kingdom RG1 3EU.
5
+ *
6
+ * This Original Work is licensed under the European Union Public Licence
7
+ * (EUPL) v.1.2 and is subject to its terms as set out below.
8
+ *
9
+ * If a copy of the EUPL was not distributed with this file, You can obtain
10
+ * one at https://opensource.org/licenses/EUPL-1.2.
11
+ *
12
+ * The 'Compatible Licences' set out in the Appendix to the EUPL (as may be
13
+ * amended by the European Commission) shall be deemed incompatible for
14
+ * the purposes of the Work and the provisions of the compatibility
15
+ * clause in Article 5 of the EUPL shall not apply.
16
+ *
17
+ * If using the Work as, or as part of, a network application, by
18
+ * including the attribution notice(s) required under Article 5 of the EUPL
19
+ * in the end user terms of the application under an appropriate heading,
20
+ * such notice(s) shall fulfill the requirements of that article.
21
21
  * ********************************************************************* */
22
22
 
23
23
  const engines = require('fiftyone.pipeline.engines');
@@ -38,55 +38,61 @@ class CloudEngine extends Engine {
38
38
  constructor () {
39
39
  super(...arguments);
40
40
 
41
- this.dataKey = 'CloudEngineBase'; // This should be overriden
41
+ this.dataKey = 'CloudEngineBase'; // This should be overridden
42
42
 
43
- const engine = this;
44
-
45
- this.registrationCallbacks.push(function (pipeline, flowElement) {
46
- const cloudRequestEngine = pipeline.flowElements.cloud;
47
-
48
- if (!cloudRequestEngine) {
49
- pipeline.log('error', 'No CloudRequestEngine in Pipeline');
50
- }
43
+ this.registrationCallbacks.push((pipeline, flowElement) => {
44
+ this.handlePipelineRegistration(pipeline, flowElement);
45
+ });
46
+ }
51
47
 
52
- cloudRequestEngine.ready().then(function () {
53
- flowElement.properties = cloudRequestEngine.flowElementProperties[flowElement.dataKey];
54
- engine.updateProperties();
55
- flowElement.evidenceKeyFilter = new BasicListEvidenceKeyFilter(cloudRequestEngine.evidenceKeys);
56
- engine.initialised = true;
57
- }).catch(function (error) {
58
- // throw error;
48
+ /**
49
+ * Handles the registration of the Cloud Engine in a pipeline.
50
+ * This method is called when a pipeline is registered,
51
+ * and it ensures that the CloudRequestEngine is present in the pipeline.
52
+ *
53
+ * @param {Pipeline} pipeline - The pipeline being registered.
54
+ * @param {FlowElement} flowElement - The flow element associated with the Cloud Engine.
55
+ */
56
+ handlePipelineRegistration (pipeline, flowElement) {
57
+ if (!pipeline.flowElements.cloud) {
58
+ pipeline.log('error', 'No CloudRequestEngine in Pipeline');
59
+ }
59
60
 
60
- engine.errors = error;
61
+ this._cloudRequestEngine = pipeline.flowElements.cloud;
62
+ this._flowElement = flowElement;
63
+ }
61
64
 
62
- engine.initialised = false;
65
+ /**
66
+ * Updates the Cloud Engine when the CloudRequestEngine is ready.
67
+ * This method fetches properties and evidence keys from the CloudRequestEngine,
68
+ * updating the Cloud Engine accordingly.
69
+ *
70
+ * @param {Function} resolve - Callback to be called on successful completion.
71
+ * @param {Function} reject - Callback to be called if there is an error.
72
+ */
73
+ updateEngineWhenCloudRequestEngineReady (resolve, reject) {
74
+ this._cloudRequestEngine.ready()
75
+ .then(() => {
76
+ this._flowElement.properties = this._cloudRequestEngine.flowElementProperties[this._flowElement.dataKey];
77
+ this.updateProperties();
78
+ this._flowElement.evidenceKeyFilter = new BasicListEvidenceKeyFilter(this._cloudRequestEngine.evidenceKeys);
79
+ resolve(this);
80
+ })
81
+ .catch((error) => {
82
+ this.errors = error;
83
+ reject(this.errors);
63
84
  });
64
- });
65
85
  }
66
86
 
67
87
  /**
68
- * Function for testing if the cloud engine is ready
69
- * Checks to see if properties and evidence keys have been fetched
88
+ * Checks if the Cloud Engine is ready.
89
+ * This method returns a Promise that resolves if the CloudRequestEngine is ready,
90
+ * indicating that properties and evidence keys have been successfully fetched.
70
91
  *
71
- * @returns {Promise} whether ready
92
+ * @returns {Promise} A Promise that resolves if the CloudRequestEngine is ready and rejects if there is an error.
72
93
  */
73
94
  ready () {
74
- const self = this;
75
- return new Promise(function (resolve, reject) {
76
- if (self.initialised === true) {
77
- resolve(self);
78
- } else {
79
- const readyCheck = setInterval(function () {
80
- if (self.initialised === true) {
81
- clearInterval(readyCheck);
82
- resolve(self);
83
- } else if (self.initialised === false) {
84
- clearInterval(readyCheck);
85
- reject(self.errors);
86
- }
87
- });
88
- }
89
- });
95
+ return new Promise((resolve, reject) => this.updateEngineWhenCloudRequestEngineReady(resolve, reject));
90
96
  }
91
97
 
92
98
  /**
@@ -1,23 +1,23 @@
1
- /* *********************************************************************
2
- * This Original Work is copyright of 51 Degrees Mobile Experts Limited.
3
- * Copyright 2023 51 Degrees Mobile Experts Limited, Davidson House,
4
- * Forbury Square, Reading, Berkshire, United Kingdom RG1 3EU.
5
- *
6
- * This Original Work is licensed under the European Union Public Licence
7
- * (EUPL) v.1.2 and is subject to its terms as set out below.
8
- *
9
- * If a copy of the EUPL was not distributed with this file, You can obtain
10
- * one at https://opensource.org/licenses/EUPL-1.2.
11
- *
12
- * The 'Compatible Licences' set out in the Appendix to the EUPL (as may be
13
- * amended by the European Commission) shall be deemed incompatible for
14
- * the purposes of the Work and the provisions of the compatibility
15
- * clause in Article 5 of the EUPL shall not apply.
16
- *
17
- * If using the Work as, or as part of, a network application, by
18
- * including the attribution notice(s) required under Article 5 of the EUPL
19
- * in the end user terms of the application under an appropriate heading,
20
- * such notice(s) shall fulfill the requirements of that article.
1
+ /* *********************************************************************
2
+ * This Original Work is copyright of 51 Degrees Mobile Experts Limited.
3
+ * Copyright 2023 51 Degrees Mobile Experts Limited, Davidson House,
4
+ * Forbury Square, Reading, Berkshire, United Kingdom RG1 3EU.
5
+ *
6
+ * This Original Work is licensed under the European Union Public Licence
7
+ * (EUPL) v.1.2 and is subject to its terms as set out below.
8
+ *
9
+ * If a copy of the EUPL was not distributed with this file, You can obtain
10
+ * one at https://opensource.org/licenses/EUPL-1.2.
11
+ *
12
+ * The 'Compatible Licences' set out in the Appendix to the EUPL (as may be
13
+ * amended by the European Commission) shall be deemed incompatible for
14
+ * the purposes of the Work and the provisions of the compatibility
15
+ * clause in Article 5 of the EUPL shall not apply.
16
+ *
17
+ * If using the Work as, or as part of, a network application, by
18
+ * including the attribution notice(s) required under Article 5 of the EUPL
19
+ * in the end user terms of the application under an appropriate heading,
20
+ * such notice(s) shall fulfill the requirements of that article.
21
21
  * ********************************************************************* */
22
22
 
23
23
  const util = require('util');
@@ -97,25 +97,47 @@ class CloudRequestEngine extends Engine {
97
97
 
98
98
  // Properties of connected FlowElements
99
99
  this.flowElementProperties = {};
100
+ }
100
101
 
101
- const self = this;
102
+ /**
103
+ * Check if the keys and properties have been fetched.
104
+ *
105
+ * This computed property determines whether the keys of a 'flowElementProperties' object and the 'evidenceKeyFilter'
106
+ * array both have elements, indicating that the necessary data has been fetched and is ready for use.
107
+ *
108
+ * @returns {boolean} True if the keys and properties are fetched and ready; otherwise, false.
109
+ */
110
+ get keysAndPropertiesFetched () {
111
+ return Object.keys(this.flowElementProperties).length > 0 && this.evidenceKeyFilter.length > 0;
112
+ }
102
113
 
114
+ /**
115
+ * Fetches evidence keys and properties data.
116
+ *
117
+ * This method asynchronously fetches evidence keys and properties required for the operation.
118
+ * It uses Promises to handle data retrieval and provides callback functions for success and failure scenarios.
119
+ *
120
+ * @param {Function} resolveCallback - A callback function to be called when the data is successfully fetched.
121
+ * It will receive the current instance as a parameter.
122
+ *
123
+ * @param {Function} rejectCallback - A callback function to be called when an error occurs during data retrieval.
124
+ * It will receive the error information as a parameter.
125
+ */
126
+ fetchEvidenceKeysAndProperties (resolveCallback, rejectCallback) {
127
+ const self = this;
103
128
  Promise.all([this.getEvidenceKeys(), this.fetchProperties()]).then(function () {
104
- self.initialised = true;
129
+ resolveCallback(self);
105
130
  }).catch(function (errors) {
106
- self.initialised = false;
107
-
108
131
  self.errors = errors;
109
-
110
132
  if (self.pipelines) {
111
133
  // Log error on all pipelines engine is attached to
112
-
113
134
  self.pipelines.map(function (pipeline) {
114
135
  pipeline.log('error', {
115
136
  source: 'CloudRequestEngine',
116
137
  message: self.errors
117
138
  });
118
139
  });
140
+ rejectCallback(self.errors);
119
141
  }
120
142
  });
121
143
  }
@@ -129,20 +151,10 @@ class CloudRequestEngine extends Engine {
129
151
  ready () {
130
152
  const self = this;
131
153
  return new Promise(function (resolve, reject) {
132
- if (self.initialised === true) {
154
+ if (self.keysAndPropertiesFetched) {
133
155
  resolve(self);
134
- } else if (self.initialised === false) {
135
- reject(self.errors);
136
156
  } else {
137
- const readyCheck = setInterval(function () {
138
- if (self.initialised === true) {
139
- clearInterval(readyCheck);
140
- resolve(self);
141
- } else if (self.initialised === false) {
142
- reject(self.errors);
143
- clearInterval(readyCheck);
144
- }
145
- });
157
+ self.fetchEvidenceKeysAndProperties(resolve, reject);
146
158
  }
147
159
  });
148
160
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fiftyone.pipeline.cloudrequestengine",
3
- "version": "4.4.54",
3
+ "version": "4.4.56",
4
4
  "description": "Cloud request engine for the 51Degrees Pipeline API",
5
5
  "main": "index.js",
6
6
  "directories": {
@@ -21,6 +21,7 @@
21
21
  * ********************************************************************* */
22
22
 
23
23
  const path = require('path');
24
+ const http = require('http');
24
25
  const MockRequestClient = require('./classes/mockRequestClient');
25
26
  const CloudRequestEngine = require('../cloudRequestEngine');
26
27
  const CloudRequestError = require('../cloudRequestError');
@@ -41,7 +42,7 @@ const testResourceKey = 'AAAAAAAAAAAA';
41
42
  * Test cloud request engine adds correct information to post request
42
43
  * and returns the response in the ElementData
43
44
  */
44
- test('process', done => {
45
+ test('process', done => {
45
46
  const jsonResponse = { device: { value: 51 } };
46
47
  const client = new MockRequestClient({ json: jsonResponse });
47
48
  const engine = new CloudRequestEngine({
@@ -130,7 +131,7 @@ test('sub properties', () => {
130
131
  expect(Object.entries(devicesProperties).length).toBe(1);
131
132
  propertiesContainName(devicesProperties.devices.itemproperties, 'IsMobile');
132
133
  propertiesContainName(devicesProperties.devices.itemproperties, 'IsTablet');
133
- });
134
+ });
134
135
  });
135
136
 
136
137
  /**
@@ -155,11 +156,69 @@ test('validate error handling JSON errors', async () => {
155
156
  await expect(e()).rejects.toEqual([new CloudRequestError(errorMessage)]);
156
157
  });
157
158
 
158
- /**
159
- *
160
- * @param properties
161
- * @param name
162
- */
159
+ /**
160
+ * Test cloud request engine handles unavailability of cloud service
161
+ * as expected.
162
+ * An exception should be thrown by the cloud request engine
163
+ * containing the errors from the cloud service in the JSON object.
164
+ */
165
+
166
+ test('validate case when cloud unavailable', (done) => {
167
+ const SERVER_PORT = 3000;
168
+ const errorMessage = 'Cloud server internal error';
169
+
170
+ const server = http.createServer((req, res) => {
171
+ const client = new MockRequestClient({
172
+ resourceKey: 'resourceKey',
173
+ error: '{ "status":"500", "errors": ["' + errorMessage + '"] }'
174
+ });
175
+
176
+ const requestEngine = new CloudRequestEngine({
177
+ resourceKey: testResourceKey,
178
+ requestClient: client
179
+ });
180
+
181
+ requestEngine.ready().then(engine => {
182
+ res.statusCode = 200;
183
+ res.setHeader('Content-Type', 'application/json');
184
+ res.end(JSON.stringify(engine.device));
185
+ }).catch(error => {
186
+ res.statusCode = 200;
187
+ res.setHeader('Content-Type', 'application/json');
188
+ res.end(JSON.stringify(error));
189
+ });
190
+ }).listen(SERVER_PORT, () => {
191
+ const options = {
192
+ hostname: 'localhost',
193
+ port: SERVER_PORT,
194
+ path: '/',
195
+ method: 'GET'
196
+ };
197
+
198
+ const req = http.request(options, (res) => {
199
+ let response = '';
200
+
201
+ res.on('data', (chunk) => {
202
+ response += chunk;
203
+ });
204
+
205
+ res.on('end', () => {
206
+ const error = JSON.parse(response)[0];
207
+ expect(error.errorMessage).toBe(errorMessage);
208
+ expect(error.name).toBe('CloudRequestError');
209
+ server.close(); // Close the server after the request is complete.
210
+ done();
211
+ });
212
+ });
213
+ req.end();
214
+ });
215
+ });
216
+
217
+ /**
218
+ *
219
+ * @param properties
220
+ * @param name
221
+ */
163
222
  function propertiesContainName (properties, name) {
164
223
  expect(properties[name.toLowerCase()]).not.toBeUndefined();
165
224
  expect(properties[name.toLowerCase()]).not.toBeNull();