nutella_framework 0.4.5 → 0.4.8
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.
- checksums.yaml +4 -4
- data/Gemfile +14 -15
- data/VERSION +1 -1
- data/framework_components/beacon-cloud-bot/README.md +27 -0
- data/framework_components/beacon-cloud-bot/beacon_cloud_bot.rb +154 -0
- data/framework_components/beacon-cloud-bot/nutella.json +6 -0
- data/framework_components/beacon-cloud-bot/startup +4 -0
- data/framework_components/beacon-cloud-interface/LICENSE +21 -0
- data/framework_components/beacon-cloud-interface/Readme.md +0 -0
- data/framework_components/beacon-cloud-interface/bower.json +29 -0
- data/framework_components/beacon-cloud-interface/bower_components/bower-mqttws/.bower.json +23 -0
- data/framework_components/beacon-cloud-interface/bower_components/bower-mqttws/bower.json +14 -0
- data/framework_components/beacon-cloud-interface/bower_components/bower-mqttws/mqttws31.js +2081 -0
- data/framework_components/beacon-cloud-interface/bower_components/bower-mqttws/readme.md +4 -0
- data/framework_components/beacon-cloud-interface/bower_components/nutella_lib/.bower.json +37 -0
- data/framework_components/beacon-cloud-interface/bower_components/nutella_lib/LICENSE +21 -0
- data/framework_components/beacon-cloud-interface/bower_components/nutella_lib/README.md +15 -0
- data/framework_components/beacon-cloud-interface/bower_components/nutella_lib/bower.json +28 -0
- data/framework_components/beacon-cloud-interface/bower_components/nutella_lib/examples/browser/mqtt_client_hello_world.html +23 -0
- data/framework_components/beacon-cloud-interface/bower_components/nutella_lib/examples/browser/nutella_hello_world.html +52 -0
- data/framework_components/beacon-cloud-interface/bower_components/nutella_lib/examples/node/mqtt_client_hello_world.js +14 -0
- data/framework_components/beacon-cloud-interface/bower_components/nutella_lib/examples/node/nutella_hello_world.js +38 -0
- data/framework_components/beacon-cloud-interface/bower_components/nutella_lib/nutella_lib.js +789 -0
- data/framework_components/beacon-cloud-interface/bower_components/nutella_lib/package.json +30 -0
- data/framework_components/beacon-cloud-interface/bower_components/nutella_lib/simple-js-mqtt-client.js +428 -0
- data/framework_components/beacon-cloud-interface/css/animation.css +17 -0
- data/framework_components/beacon-cloud-interface/css/cursor.css +16 -0
- data/framework_components/beacon-cloud-interface/css/page_layout.css +73 -0
- data/framework_components/beacon-cloud-interface/index.html +157 -0
- data/framework_components/beacon-cloud-interface/js/lib/nutella_lib.js +4039 -0
- data/framework_components/beacon-cloud-interface/js/react/beacon-add.js +102 -0
- data/framework_components/beacon-cloud-interface/js/react/beacon-table.js +73 -0
- data/framework_components/beacon-cloud-interface/js/react/beacon.js +97 -0
- data/framework_components/beacon-cloud-interface/nutella.json +6 -0
- data/framework_components/example_framework_web_interface/index.html +11 -2
- data/framework_components/example_framework_web_interface/node_modules/nutella_lib/.npmignore +10 -0
- data/framework_components/example_framework_web_interface/node_modules/nutella_lib/.travis.yml +5 -0
- data/framework_components/example_framework_web_interface/node_modules/nutella_lib/LICENSE +21 -0
- data/framework_components/example_framework_web_interface/node_modules/nutella_lib/README.md +27 -0
- data/framework_components/example_framework_web_interface/node_modules/nutella_lib/dist/nutella_lib.js +4039 -0
- data/framework_components/example_framework_web_interface/node_modules/nutella_lib/dist/nutella_lib.js.map +1 -0
- data/framework_components/example_framework_web_interface/node_modules/nutella_lib/examples/browser_hello_world.html +67 -0
- data/framework_components/example_framework_web_interface/node_modules/nutella_lib/examples/node_hello_world.js +51 -0
- data/framework_components/example_framework_web_interface/node_modules/nutella_lib/gulpfile.js +31 -0
- data/framework_components/example_framework_web_interface/node_modules/nutella_lib/package.json +41 -0
- data/framework_components/example_framework_web_interface/node_modules/nutella_lib/src/app_core.js +19 -0
- data/framework_components/example_framework_web_interface/node_modules/nutella_lib/src/app_core_browser.js +17 -0
- data/framework_components/example_framework_web_interface/node_modules/nutella_lib/src/app_log.js +50 -0
- data/framework_components/example_framework_web_interface/node_modules/nutella_lib/src/app_net.js +279 -0
- data/framework_components/example_framework_web_interface/node_modules/nutella_lib/src/app_persist.js +20 -0
- data/framework_components/example_framework_web_interface/node_modules/nutella_lib/src/fr_core_browser.js +17 -0
- data/framework_components/example_framework_web_interface/node_modules/nutella_lib/src/fr_log.js +50 -0
- data/framework_components/example_framework_web_interface/node_modules/nutella_lib/src/fr_net.js +499 -0
- data/framework_components/example_framework_web_interface/node_modules/nutella_lib/src/nutella_i.js +74 -0
- data/framework_components/example_framework_web_interface/node_modules/nutella_lib/src/nutella_i_browser.js +130 -0
- data/framework_components/example_framework_web_interface/node_modules/nutella_lib/src/nutella_lib.js +91 -0
- data/framework_components/example_framework_web_interface/node_modules/nutella_lib/src/nutella_lib_browser.js +90 -0
- data/framework_components/example_framework_web_interface/node_modules/nutella_lib/src/run_log.js +51 -0
- data/framework_components/example_framework_web_interface/node_modules/nutella_lib/src/run_net.js +84 -0
- data/framework_components/example_framework_web_interface/node_modules/nutella_lib/src/run_persist.js +20 -0
- data/framework_components/example_framework_web_interface/node_modules/nutella_lib/src/util/net.js +327 -0
- data/framework_components/example_framework_web_interface/node_modules/nutella_lib/test/nutella.test.js +16 -0
- data/framework_components/example_framework_web_interface/node_modules/nutella_lib/test/runner.html +22 -0
- data/framework_components/example_framework_web_interface/package.json +15 -0
- data/framework_components/{order.json.example → order.json} +0 -0
- data/framework_components/runs_list_bot/{app_runs_list_bot.rb → runs_list_bot.rb} +9 -3
- data/framework_components/runs_list_bot/startup +1 -1
- data/lib/commands/meta/run_command.rb +21 -36
- data/lib/commands/start.rb +9 -199
- data/lib/commands/util/components_list.rb +68 -0
- data/lib/commands/util/components_starter.rb +169 -0
- data/nutella_framework.gemspec +109 -47
- data/nutella_lib/framework_net.rb +17 -13
- metadata +84 -106
data/framework_components/example_framework_web_interface/node_modules/nutella_lib/src/fr_net.js
ADDED
|
@@ -0,0 +1,499 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework-level Networking APIs for nutella
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
var AbstractNet = require('./util/net');
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Framework-level network APIs for nutella
|
|
11
|
+
* @param main_nutella
|
|
12
|
+
* @constructor
|
|
13
|
+
*/
|
|
14
|
+
var FRNetSubModule = function(main_nutella) {
|
|
15
|
+
this.net = new AbstractNet(main_nutella);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Subscribes to a channel or filter.
|
|
22
|
+
*
|
|
23
|
+
* @param channel
|
|
24
|
+
* @param callback
|
|
25
|
+
* @param done_callback
|
|
26
|
+
*/
|
|
27
|
+
FRNetSubModule.prototype.subscribe = function(channel, callback, done_callback) {
|
|
28
|
+
this.net.subscribe_to(channel, callback, undefined, undefined, done_callback);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Unsubscribes from a channel
|
|
34
|
+
*
|
|
35
|
+
* @param channel
|
|
36
|
+
* @param done_callback
|
|
37
|
+
*/
|
|
38
|
+
FRNetSubModule.prototype.unsubscribe = function(channel, done_callback) {
|
|
39
|
+
this.net.unsubscribe_from(channel, undefined, undefined, done_callback);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Publishes a message to a channel
|
|
45
|
+
*
|
|
46
|
+
* @param channel
|
|
47
|
+
* @param message
|
|
48
|
+
*/
|
|
49
|
+
FRNetSubModule.prototype.publish = function(channel, message) {
|
|
50
|
+
this.net.publish_to(channel, message, undefined, undefined);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Sends a request.
|
|
56
|
+
*
|
|
57
|
+
* @param channel
|
|
58
|
+
* @param message
|
|
59
|
+
* @param callback
|
|
60
|
+
*/
|
|
61
|
+
FRNetSubModule.prototype.request = function(channel, message, callback) {
|
|
62
|
+
this.net.request_to(channel, message, callback, undefined, undefined);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Handles requests.
|
|
68
|
+
*
|
|
69
|
+
* @param channel
|
|
70
|
+
* @param callback
|
|
71
|
+
* @param done_callback
|
|
72
|
+
*/
|
|
73
|
+
FRNetSubModule.prototype.handle_requests = function(channel, callback, done_callback) {
|
|
74
|
+
this.net.handle_requests_on(channel, callback, undefined, undefined, done_callback);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
//----------------------------------------------------------------------------------------------------------------
|
|
80
|
+
// Framework-level APIs to communicate at the run-level to a specific run
|
|
81
|
+
//----------------------------------------------------------------------------------------------------------------
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Allows framework-level APIs to subscribe to a run-level channel within a specific run
|
|
85
|
+
*
|
|
86
|
+
* @param app_id
|
|
87
|
+
* @param run_id
|
|
88
|
+
* @param channel
|
|
89
|
+
* @param callback
|
|
90
|
+
* @param done_callback
|
|
91
|
+
*/
|
|
92
|
+
FRNetSubModule.prototype.subscribe_to_run = function(app_id, run_id, channel, callback,done_callback) {
|
|
93
|
+
this.net.subscribe_to(channel,callback,app_id,run_id,done_callback)
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Allows framework-level APIs to unsubscribe from a run-level channel within a specific run
|
|
99
|
+
*
|
|
100
|
+
* @param app_id
|
|
101
|
+
* @param run_id
|
|
102
|
+
* @param channel
|
|
103
|
+
* @param done_callback
|
|
104
|
+
*/
|
|
105
|
+
FRNetSubModule.prototype.unsubscribe_to_run = function( app_id, run_id, channel, done_callback ) {
|
|
106
|
+
this.net.unsubscribe_from(channel, app_id, run_id, done_callback);
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Allows framework-level APIs to publish to a run-level channel within a specific run
|
|
112
|
+
*
|
|
113
|
+
* @param app_id
|
|
114
|
+
* @param run_id
|
|
115
|
+
* @param channel
|
|
116
|
+
* @param message
|
|
117
|
+
*/
|
|
118
|
+
FRNetSubModule.prototype.publish_to_run = function( app_id, run_id, channel, message ) {
|
|
119
|
+
this.net.publish_to(channel, message, app_id, run_id);
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Allows framework-level APIs to make an asynchronous request to a run-level channel within a specific run
|
|
125
|
+
*
|
|
126
|
+
* @param app_id
|
|
127
|
+
* @param run_id
|
|
128
|
+
* @param channel
|
|
129
|
+
* @param request
|
|
130
|
+
* @param callback
|
|
131
|
+
*/
|
|
132
|
+
FRNetSubModule.prototype.request_to_run = function( app_id, run_id, channel, request, callback) {
|
|
133
|
+
this.net.request_to(channel, request, callback, app_id, run_id);
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Allows framework-level APIs to handle requests on a run-level channel within a specific run
|
|
139
|
+
*
|
|
140
|
+
* @param app_id
|
|
141
|
+
* @param run_id
|
|
142
|
+
* @param channel
|
|
143
|
+
* @param callback
|
|
144
|
+
*/
|
|
145
|
+
FRNetSubModule.prototype.handle_requests_on_run = function( app_id, run_id, channel, callback, done_callback) {
|
|
146
|
+
this.net.handle_requests_on(channel, callback, app_id, run_id, done_callback)
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
//----------------------------------------------------------------------------------------------------------------
|
|
152
|
+
// Framework-level APIs to communicate at the run-level (broadcast)
|
|
153
|
+
//----------------------------------------------------------------------------------------------------------------
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Callback for subscribing to all runs
|
|
158
|
+
* @callback allRunsCb
|
|
159
|
+
# @param {string} message - the received message. Messages that are not JSON are discarded
|
|
160
|
+
# @param {String} app_id - the app_id of the channel the message was sent on
|
|
161
|
+
# @param {String} run_id - the run_id of the channel the message was sent on
|
|
162
|
+
# @param {Object} from - the sender's identifiers (run_id, app_id, component_id and optionally resource_id)
|
|
163
|
+
*/
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Allows framework-level APIs to subscribe to a run-level channel *for ALL runs*
|
|
167
|
+
*
|
|
168
|
+
* @param channel
|
|
169
|
+
* @param {allRunsCb} callback
|
|
170
|
+
* @param done_callback
|
|
171
|
+
*/
|
|
172
|
+
FRNetSubModule.prototype.subscribe_to_all_runs = function( channel, callback, done_callback ) {
|
|
173
|
+
//Pad channel
|
|
174
|
+
var padded_channel = this.net.pad_channel(channel, '+', '+');
|
|
175
|
+
var mqtt_cb = function(mqtt_message, mqtt_channel) {
|
|
176
|
+
try {
|
|
177
|
+
var f = JSON.parse(mqtt_message);
|
|
178
|
+
var f1 = extractRunIdAndAppId(mqtt_channel);
|
|
179
|
+
if(f.type==='publish')
|
|
180
|
+
callback(f.payload, f1.appId, f1.runId, f.from);
|
|
181
|
+
} catch(e) {
|
|
182
|
+
if (e instanceof SyntaxError) {
|
|
183
|
+
// Message is not JSON, drop it
|
|
184
|
+
} else {
|
|
185
|
+
// Bubble up whatever exception is thrown
|
|
186
|
+
throw e;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
// Add to subscriptions, save mqtt callback and subscribe
|
|
191
|
+
this.net.subscriptions.push(padded_channel);
|
|
192
|
+
this.net.callbacks.push(mqtt_cb);
|
|
193
|
+
this.net.nutella.mqtt_client.subscribe(padded_channel, mqtt_cb, done_callback);
|
|
194
|
+
// Notify subscription
|
|
195
|
+
this.net.publish_to('subscriptions', {type: 'subscribe', channel: padded_channel}, undefined, undefined);
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Allows framework-level APIs to unsubscribe from a run-level channel *for ALL runs*
|
|
201
|
+
*
|
|
202
|
+
* @param channel
|
|
203
|
+
* @param done_callback
|
|
204
|
+
*/
|
|
205
|
+
FRNetSubModule.prototype.unsubscribe_from_all_runs = function(channel, done_callback) {
|
|
206
|
+
this.net.unsubscribe_from(channel, '+', '+', done_callback);
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Allows framework-level APIs to publish a message to a run-level channel *for ALL runs*
|
|
212
|
+
*
|
|
213
|
+
* @param channel
|
|
214
|
+
* @param message
|
|
215
|
+
*/
|
|
216
|
+
FRNetSubModule.prototype.publish_to_all_runs = function( channel, message ) {
|
|
217
|
+
Object.keys(this.net.nutella.runs_list).forEach(function(app_id) {
|
|
218
|
+
this.net.nutella.runs_list[app_id].runs.forEach(function(run_id){
|
|
219
|
+
this.net.publish_to(channel, message, app_id, run_id);
|
|
220
|
+
}.bind(this));
|
|
221
|
+
}.bind(this));
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Allows framework-level APIs to send a request to a run-level channel *for ALL runs*
|
|
227
|
+
*
|
|
228
|
+
* @param channel
|
|
229
|
+
* @param request
|
|
230
|
+
* @param callback
|
|
231
|
+
*/
|
|
232
|
+
FRNetSubModule.prototype.request_to_all_runs = function(channel, request, callback) {
|
|
233
|
+
Object.keys(this.net.nutella.runs_list).forEach(function(app_id) {
|
|
234
|
+
this.net.nutella.runs_list[app_id].runs.forEach(function(run_id){
|
|
235
|
+
this.net.publish_to(channel, message, app_id, run_id);
|
|
236
|
+
this.net.request_to(channel, request, callback, app_id, run_id);
|
|
237
|
+
}.bind(this));
|
|
238
|
+
}.bind(this));
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Callback that is used to handle messages from all runs
|
|
243
|
+
* @callback handle_all_runs_cb
|
|
244
|
+
* @param {string} payload - the received message (request). Messages that are not JSON are discarded
|
|
245
|
+
* @param {string} app_id - the app_id of the channel the request was sent on
|
|
246
|
+
* @param {string} run_id - the run_id of the channel the request was sent on
|
|
247
|
+
* @param {Object} from - the sender's identifiers (from containing, run_id, app_id, component_id and optionally resource_id)
|
|
248
|
+
* @return {Object} the response sent back to the client that performed the request. Whatever is returned by the callback is marshaled into a JSON string and sent via MQTT.
|
|
249
|
+
*/
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Allows framework-level APIs to handle requests to a run-level channel *for ALL runs*
|
|
253
|
+
*
|
|
254
|
+
* @param channel
|
|
255
|
+
* @param {handle_all_runs_cb} callback
|
|
256
|
+
* @param done_callback
|
|
257
|
+
*/
|
|
258
|
+
FRNetSubModule.prototype.handle_requests_on_all_runs = function(channel, callback, done_callback) {
|
|
259
|
+
// Pad channel
|
|
260
|
+
var padded_channel = this.net.pad_channel(channel, '+', '+');
|
|
261
|
+
var ln = this.net;
|
|
262
|
+
var mqtt_cb = function(mqtt_message, mqtt_channel) {
|
|
263
|
+
try {
|
|
264
|
+
var f = JSON.parse(mqtt_message);
|
|
265
|
+
var f1 = extractRunIdAndAppId(mqtt_channel);
|
|
266
|
+
// Only handle requests that have proper id set
|
|
267
|
+
if(f.type!=='request' || f.id===undefined) return;
|
|
268
|
+
// Execute callback and send response
|
|
269
|
+
var m = ln.prepare_message_for_response(callback(f.payload, f1.appId, f1.runId, f.from), f.id);
|
|
270
|
+
ln.nutella.mqtt_client.publish( padded_channel, m );
|
|
271
|
+
} catch(e) {
|
|
272
|
+
if (e instanceof SyntaxError) {
|
|
273
|
+
// Message is not JSON, drop it
|
|
274
|
+
} else {
|
|
275
|
+
// Bubble up whatever exception is thrown
|
|
276
|
+
throw e;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
};
|
|
280
|
+
this.net.nutella.mqtt_client.subscribe( padded_channel, mqtt_cb, done_callback);
|
|
281
|
+
// Notify subscription
|
|
282
|
+
this.net.publish_to('subscriptions', {type: 'handle_requests', channel: padded_channel}, undefined, undefined);
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
//----------------------------------------------------------------------------------------------------------------
|
|
288
|
+
// Framework-level APIs to communicate at the application-level
|
|
289
|
+
//----------------------------------------------------------------------------------------------------------------
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Allows framework-level APIs to subscribe to an app-level channel
|
|
294
|
+
*
|
|
295
|
+
* @param app_id
|
|
296
|
+
* @param channel
|
|
297
|
+
* @param callback
|
|
298
|
+
* @param done_callback
|
|
299
|
+
*/
|
|
300
|
+
FRNetSubModule.prototype.subscribe_to_app = function(app_id, channel, callback, done_callback) {
|
|
301
|
+
this.net.subscribe_to(channel,callback,app_id, undefined, done_callback)
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Allows framework-level APIs to unsubscribe from an app-level channel within a specific run
|
|
307
|
+
*
|
|
308
|
+
* @param app_id
|
|
309
|
+
* @param channel
|
|
310
|
+
* @param done_callback
|
|
311
|
+
*/
|
|
312
|
+
FRNetSubModule.prototype.unsubscribe_to_app = function( app_id, channel, done_callback) {
|
|
313
|
+
this.net.unsubscribe_from(channel,app_id,undefined, done_callback);
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Allows framework-level APIs to publish to an app-level channel
|
|
319
|
+
*
|
|
320
|
+
* @param app_id
|
|
321
|
+
* @param channel
|
|
322
|
+
* @param message
|
|
323
|
+
*/
|
|
324
|
+
FRNetSubModule.prototype.publish_to_app = function(app_id, channel, message) {
|
|
325
|
+
this.net.publish_to(channel,message,app_id,undefined);
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Allows framework-level APIs to make an asynchronous request to a run-level channel within a specific run
|
|
331
|
+
*
|
|
332
|
+
* @param app_id
|
|
333
|
+
* @param channel
|
|
334
|
+
* @param request
|
|
335
|
+
* @param callback
|
|
336
|
+
*/
|
|
337
|
+
FRNetSubModule.prototype.request_to_app = function( app_id, channel, request, callback) {
|
|
338
|
+
this.net.request_to(channel, request, callback, app_id, undefined);
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Allows framework-level APIs to handle requests on a run-level channel within a specific run
|
|
344
|
+
*
|
|
345
|
+
* @param app_id
|
|
346
|
+
* @param channel
|
|
347
|
+
* @param callback
|
|
348
|
+
* @param done_callback
|
|
349
|
+
*/
|
|
350
|
+
FRNetSubModule.prototype.handle_requests_on_app = function(app_id, channel, callback, done_callback) {
|
|
351
|
+
this.net.handle_requests_on(channel, callback, app_id, undefined, done_callback);
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
//----------------------------------------------------------------------------------------------------------------
|
|
356
|
+
// Framework-level APIs to communicate at the application-level (broadcast)
|
|
357
|
+
//----------------------------------------------------------------------------------------------------------------
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Callback used to handle all messages received when subscribing to all applications
|
|
361
|
+
* @callback subscribeToAllAppsCb
|
|
362
|
+
* @param {string} message - the received message. Messages that are not JSON are discarded
|
|
363
|
+
* @param {string} app_id - the app_id of the channel the message was sent on
|
|
364
|
+
* @param {Object} from - the sender's identifiers (run_id, app_id, component_id and optionally resource_id)
|
|
365
|
+
*/
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Allows framework-level APIs to subscribe to an app-level channel *for ALL apps*
|
|
369
|
+
*
|
|
370
|
+
* @param channel
|
|
371
|
+
* @param {subscribeToAllAppsCb} callback
|
|
372
|
+
* @param done_callback
|
|
373
|
+
*/
|
|
374
|
+
FRNetSubModule.prototype.subscribe_to_all_apps = function(channel, callback, done_callback) {
|
|
375
|
+
//Pad channel
|
|
376
|
+
var padded_channel = this.net.pad_channel(channel, '+', undefined);
|
|
377
|
+
var mqtt_cb = function(mqtt_message, mqtt_channel) {
|
|
378
|
+
try {
|
|
379
|
+
var f = JSON.parse(mqtt_message);
|
|
380
|
+
var app_id = extractAppId(mqtt_channel);
|
|
381
|
+
if(f.type==='publish')
|
|
382
|
+
callback(f.payload, app_id, f.from);
|
|
383
|
+
} catch(e) {
|
|
384
|
+
if (e instanceof SyntaxError) {
|
|
385
|
+
// Message is not JSON, drop it
|
|
386
|
+
} else {
|
|
387
|
+
// Bubble up whatever exception is thrown
|
|
388
|
+
throw e;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
};
|
|
392
|
+
// Add to subscriptions, save mqtt callback and subscribe
|
|
393
|
+
this.net.subscriptions.push(padded_channel);
|
|
394
|
+
this.net.callbacks.push(mqtt_cb);
|
|
395
|
+
this.net.nutella.mqtt_client.subscribe(padded_channel, mqtt_cb, done_callback);
|
|
396
|
+
// Notify subscription
|
|
397
|
+
this.net.publish_to('subscriptions', {type: 'subscribe', channel: padded_channel}, undefined, undefined);
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Allows framework-level APIs to unsubscribe from an app-level channel *for ALL apps*
|
|
403
|
+
*
|
|
404
|
+
* @param channel
|
|
405
|
+
* @param done_callback
|
|
406
|
+
*/
|
|
407
|
+
FRNetSubModule.prototype.unsubscribe_from_all_apps = function(channel, done_callback) {
|
|
408
|
+
this.net.unsubscribe_from(channel, '+', undefined, done_callback);
|
|
409
|
+
};
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Allows framework-level APIs to publish a message to an app-level channel *for ALL apps*
|
|
414
|
+
*
|
|
415
|
+
* @param channel
|
|
416
|
+
* @param message
|
|
417
|
+
*/
|
|
418
|
+
FRNetSubModule.prototype.publish_to_all_apps = function(channel, message) {
|
|
419
|
+
Object.keys(this.net.nutella.runs_list).forEach(function(app_id) {
|
|
420
|
+
this.net.publish_to(channel, message, app_id, undefined);
|
|
421
|
+
}.bind(this));
|
|
422
|
+
};
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* Allows framework-level APIs to send a request to an app-level channel *for ALL apps*
|
|
427
|
+
*
|
|
428
|
+
* @param channel
|
|
429
|
+
* @param request
|
|
430
|
+
* @param callback
|
|
431
|
+
*/
|
|
432
|
+
FRNetSubModule.prototype.request_to_all_apps = function(channel, request, callback) {
|
|
433
|
+
Object.keys(this.net.nutella.runs_list).forEach(function(app_id) {
|
|
434
|
+
this.net.request_to(channel, request, callback, app_id, undefined);
|
|
435
|
+
}.bind(this));
|
|
436
|
+
};
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* This callback is used to handle messages coming from all applications
|
|
441
|
+
* @callback handleAllAppsCb
|
|
442
|
+
* @param {string} request - the received message (request). Messages that are not JSON are discarded.
|
|
443
|
+
* @param {string} app_id - the app_id of the channel the request was sent on
|
|
444
|
+
* @param {Object} from - the sender's identifiers (from containing, run_id, app_id, component_id and optionally resource_id)
|
|
445
|
+
* @return {Object} The response sent back to the client that performed the request. Whatever is returned by the callback is marshaled into a JSON string and sent via MQTT.
|
|
446
|
+
*/
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* Allows framework-level APIs to handle requests to app-level channel *for ALL runs*
|
|
450
|
+
*
|
|
451
|
+
* @param channel
|
|
452
|
+
* @param {handleAllAppsCb} callback
|
|
453
|
+
* @param done_callback
|
|
454
|
+
*/
|
|
455
|
+
FRNetSubModule.prototype.handle_requests_on_all_apps = function(channel, callback, done_callback) {
|
|
456
|
+
// Pad channel
|
|
457
|
+
var padded_channel = this.net.pad_channel(channel, '+', undefined);
|
|
458
|
+
var ln = this.net;
|
|
459
|
+
var mqtt_cb = function(mqtt_message, mqtt_channel) {
|
|
460
|
+
try {
|
|
461
|
+
var f = JSON.parse(mqtt_message);
|
|
462
|
+
var f1 = extractRunIdAndAppId(mqtt_channel);
|
|
463
|
+
// Only handle requests that have proper id set
|
|
464
|
+
if(f.type!=='request' || f.id===undefined) return;
|
|
465
|
+
// Execute callback and send response
|
|
466
|
+
var m = ln.prepare_message_for_response(callback(f.payload, f1.appId, f1.runId, f.from), f.id);
|
|
467
|
+
ln.nutella.mqtt_client.publish( padded_channel, m );
|
|
468
|
+
} catch(e) {
|
|
469
|
+
if (e instanceof SyntaxError) {
|
|
470
|
+
// Message is not JSON, drop it
|
|
471
|
+
} else {
|
|
472
|
+
// Bubble up whatever exception is thrown
|
|
473
|
+
throw e;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
};
|
|
477
|
+
this.net.nutella.mqtt_client.subscribe( padded_channel, mqtt_cb, done_callback);
|
|
478
|
+
// Notify subscription
|
|
479
|
+
this.net.publish_to('subscriptions', {type: 'handle_requests', channel: padded_channel}, undefined, undefined);
|
|
480
|
+
};
|
|
481
|
+
|
|
482
|
+
|
|
483
|
+
// Utility functions
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
function extractRunIdAndAppId(mqtt_channel) {
|
|
487
|
+
var sp = mqtt_channel.replace('/nutella/apps/', '').split('/');
|
|
488
|
+
return {appId: sp[0], runId: sp[2]};
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
function extractAppId(mqtt_channel) {
|
|
492
|
+
var sp = mqtt_channel.replace('/nutella/apps/', '').split('/');
|
|
493
|
+
return sp[0];
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
|
|
499
|
+
module.exports = FRNetSubModule;
|
data/framework_components/example_framework_web_interface/node_modules/nutella_lib/src/nutella_i.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run-level and App-level Nutella instances for node
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
var SimpleMQTTClient = require('simple-mqtt-client');
|
|
6
|
+
|
|
7
|
+
// Require various sub-modules
|
|
8
|
+
var AppSubModule = require('./app_core');
|
|
9
|
+
var NetSubModule = require('./run_net');
|
|
10
|
+
var LogSubModule = require('./run_log');
|
|
11
|
+
var PersistSubModule = require('./run_persist');
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Defines the RunNutellaInstance class.
|
|
16
|
+
*
|
|
17
|
+
* @param {String } app_id - the app_id this component belongs to
|
|
18
|
+
* @param {string} run_id - the run_id this component is launched in
|
|
19
|
+
* @param {string} broker_hostname - the hostname of the broker.
|
|
20
|
+
* @param {string} component_id - the name of this component
|
|
21
|
+
*/
|
|
22
|
+
var RunNutellaInstance = function (broker_hostname, app_id, run_id, component_id) {
|
|
23
|
+
//Initialize parameters
|
|
24
|
+
this.mqtt_client = new SimpleMQTTClient(broker_hostname);
|
|
25
|
+
this.appId = app_id;
|
|
26
|
+
this.runId = run_id;
|
|
27
|
+
this.componentId = component_id;
|
|
28
|
+
// Initialized the various sub-modules
|
|
29
|
+
this.net = new NetSubModule(this);
|
|
30
|
+
this.log = new LogSubModule(this);
|
|
31
|
+
this.persist = new PersistSubModule(this);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Sets the resource id for this instance of nutella
|
|
36
|
+
*
|
|
37
|
+
* @param {string} resource_id - the resource_id associated to this instance of nutella
|
|
38
|
+
*/
|
|
39
|
+
RunNutellaInstance.prototype.setResourceId = function(resource_id){
|
|
40
|
+
this.resourceId = resource_id;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Defines the AppNutellaInstance class.
|
|
47
|
+
*
|
|
48
|
+
* @param {String } app_id - the app_id this component belongs to
|
|
49
|
+
* @param {string} broker_hostname - the hostname of the broker.
|
|
50
|
+
* @param {string} component_id - the name of this component
|
|
51
|
+
*/
|
|
52
|
+
var AppNutellaInstance = function (broker_hostname, app_id, component_id) {
|
|
53
|
+
//Initialize parameters
|
|
54
|
+
this.mqtt_client = new SimpleMQTTClient(broker_hostname);
|
|
55
|
+
this.appId = app_id;
|
|
56
|
+
this.componentId = component_id;
|
|
57
|
+
// Initialized the various sub-modules
|
|
58
|
+
this.app = new AppSubModule(this);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Sets the resource id for this instance of nutella
|
|
63
|
+
*
|
|
64
|
+
* @param {string} resource_id - the resource_id associated to this instance of nutella
|
|
65
|
+
*/
|
|
66
|
+
AppNutellaInstance.prototype.setResourceId = function(resource_id){
|
|
67
|
+
this.resourceId = resource_id;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
module.exports = {
|
|
72
|
+
RunNutellaInstance : RunNutellaInstance,
|
|
73
|
+
AppNutellaInstance : AppNutellaInstance
|
|
74
|
+
};
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run-level and App-level Nutella instances for the browser
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
var SimpleMQTTClient = require('simple-mqtt-client');
|
|
6
|
+
|
|
7
|
+
// Require various sub-modules
|
|
8
|
+
var AppSubModule = require('./app_core_browser');
|
|
9
|
+
var FrSubModule = require('./fr_core_browser');
|
|
10
|
+
var NetSubModule = require('./run_net');
|
|
11
|
+
var LogSubModule = require('./run_log');
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Defines the RunNutellaInstance class.
|
|
16
|
+
*
|
|
17
|
+
* @param {String } app_id - the app_id this component belongs to
|
|
18
|
+
* @param {string} run_id - the run_id this component is launched in
|
|
19
|
+
* @param {string} broker_hostname - the hostname of the broker.
|
|
20
|
+
* @param {string} component_id - the name of this component
|
|
21
|
+
*/
|
|
22
|
+
var RunNutellaInstance = function (broker_hostname, app_id, run_id, component_id) {
|
|
23
|
+
//Initialize parameters
|
|
24
|
+
this.mqtt_client = new SimpleMQTTClient(broker_hostname);
|
|
25
|
+
this.appId = app_id;
|
|
26
|
+
this.runId = run_id;
|
|
27
|
+
this.componentId = component_id;
|
|
28
|
+
// Initialized the various sub-modules
|
|
29
|
+
this.net = new NetSubModule(this);
|
|
30
|
+
this.log = new LogSubModule(this);
|
|
31
|
+
// Start pinging
|
|
32
|
+
setInterval(function(){
|
|
33
|
+
this.net.publish('pings', 'ping');
|
|
34
|
+
}.bind(this),5000);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Sets the resource id for this instance of nutella
|
|
39
|
+
*
|
|
40
|
+
* @param {string} resource_id - the resource_id associated to this instance of nutella
|
|
41
|
+
*/
|
|
42
|
+
RunNutellaInstance.prototype.setResourceId = function(resource_id){
|
|
43
|
+
this.resourceId = resource_id;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Defines the AppNutellaInstance class.
|
|
49
|
+
*
|
|
50
|
+
* @param {String } app_id - the app_id this component belongs to
|
|
51
|
+
* @param {string} broker_hostname - the hostname of the broker.
|
|
52
|
+
* @param {string} component_id - the name of this component
|
|
53
|
+
*/
|
|
54
|
+
var AppNutellaInstance = function (broker_hostname, app_id, component_id) {
|
|
55
|
+
//Initialize parameters
|
|
56
|
+
this.mqtt_client = new SimpleMQTTClient(broker_hostname);
|
|
57
|
+
this.appId = app_id;
|
|
58
|
+
this.componentId = component_id;
|
|
59
|
+
// Initialized the various sub-modules
|
|
60
|
+
this.app = new AppSubModule(this);
|
|
61
|
+
//Initialize the runs list
|
|
62
|
+
this.runs_list = [];
|
|
63
|
+
// Fetch the runs list
|
|
64
|
+
this.app.net.request('app_runs_list', undefined, function(response) {
|
|
65
|
+
this.runs_list = response;
|
|
66
|
+
}.bind(this));
|
|
67
|
+
// Subscribe to runs list updates
|
|
68
|
+
this.app.net.subscribe('app_runs_list', function(message, from) {
|
|
69
|
+
this.runs_list = message;
|
|
70
|
+
}.bind(this));
|
|
71
|
+
// Start pinging
|
|
72
|
+
setInterval(function(){
|
|
73
|
+
this.app.net.publish('pings', 'ping');
|
|
74
|
+
}.bind(this),5000);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Sets the resource id for this instance of nutella
|
|
79
|
+
*
|
|
80
|
+
* @param {string} resource_id - the resource_id associated to this instance of nutella
|
|
81
|
+
*/
|
|
82
|
+
AppNutellaInstance.prototype.setResourceId = function(resource_id){
|
|
83
|
+
this.resourceId = resource_id;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Defines the FRNutellaInstance class.
|
|
89
|
+
*
|
|
90
|
+
* @param {string} broker_hostname - the hostname of the broker.
|
|
91
|
+
* @param {string} component_id - the name of this component
|
|
92
|
+
*/
|
|
93
|
+
var FrNutellaInstance = function (broker_hostname, component_id) {
|
|
94
|
+
//Initialize parameters
|
|
95
|
+
this.mqtt_client = new SimpleMQTTClient(broker_hostname);
|
|
96
|
+
this.componentId = component_id;
|
|
97
|
+
// Initialize the various sub-modules
|
|
98
|
+
this.f = new FrSubModule(this);
|
|
99
|
+
//Initialize the runs list
|
|
100
|
+
this.runs_list = {};
|
|
101
|
+
// Fetch the runs list
|
|
102
|
+
this.f.net.request('runs_list', undefined, function(response) {
|
|
103
|
+
this.runs_list = response;
|
|
104
|
+
}.bind(this));
|
|
105
|
+
// Subscribe to runs list updates
|
|
106
|
+
this.f.net.subscribe('runs_list', function(message, from) {
|
|
107
|
+
this.runs_list = message;
|
|
108
|
+
}.bind(this));
|
|
109
|
+
// Start pinging
|
|
110
|
+
setInterval(function(){
|
|
111
|
+
this.f.net.publish('pings', 'ping');
|
|
112
|
+
}.bind(this),5000);
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Sets the resource id for this instance of nutella
|
|
117
|
+
*
|
|
118
|
+
* @param {string} resource_id - the resource_id associated to this instance of nutella
|
|
119
|
+
*/
|
|
120
|
+
FrNutellaInstance.prototype.setResourceId = function(resource_id){
|
|
121
|
+
this.resourceId = resource_id;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
module.exports = {
|
|
127
|
+
RunNutellaInstance : RunNutellaInstance,
|
|
128
|
+
AppNutellaInstance : AppNutellaInstance,
|
|
129
|
+
FrNutellaInstance : FrNutellaInstance
|
|
130
|
+
};
|