nutella_framework 0.4.18 → 0.4.19

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.
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "monitoring-bot",
3
+ "version": "0.0.1",
4
+ "type": "bot",
5
+ "description": "Monitoring bot"
6
+ }
@@ -0,0 +1,6 @@
1
+ #!/bin/sh
2
+
3
+ BASEDIR=$(dirname $0)
4
+
5
+ ruby $BASEDIR/monitoring-bot.rb # > /dev/null 2>&1 &
6
+ echo $! > $BASEDIR/.pid
@@ -45,7 +45,7 @@ module Nutella
45
45
  File.chmod( 0755, 'startup' )
46
46
 
47
47
  # Write configuration into config.json
48
- Nutella.config['broker'] = 'localhost'
48
+ Nutella.config['broker'] = '127.0.0.1'
49
49
  out1 && out2
50
50
  end
51
51
 
@@ -69,8 +69,14 @@ module Nutella
69
69
  out.slice!(0,5)
70
70
  Semantic::Version.new "#{out[0..2]}.0"
71
71
  end
72
+ # Mongo version lambda
73
+ mongo_semver = lambda do
74
+ out = `mongod --version`
75
+ out.slice!(0,12)
76
+ Semantic::Version.new out[0..4]
77
+ end
72
78
  # Check versions
73
- return true if check_version?('node', '0.10.0', node_semver) && check_version?('git', '1.8.0', git_semver) && check_version?('tmux', '1.8.0', tmux_semver)
79
+ return true if check_version?('node', '0.10.0', node_semver) && check_version?('git', '1.8.0', git_semver) && check_version?('tmux', '1.8.0', tmux_semver) && check_version?('mongodb', '2.6.9', mongo_semver)
74
80
  # If even one of the checks fails, return false
75
81
  false
76
82
  end
@@ -94,6 +94,8 @@ module Nutella
94
94
  def start_all_components( app_id, app_path, run_id, params )
95
95
  # Start the internal broker
96
96
  return false unless ComponentsStarter.start_internal_broker
97
+ # Start mongo db
98
+ return false unless ComponentsStarter.start_mongo_db
97
99
  # Start all framework-level components (if needed)
98
100
  return false unless ComponentsStarter.start_framework_components
99
101
  # Start all app-level bots (if any, if needed)
data/lib/commands/stop.rb CHANGED
@@ -34,6 +34,7 @@ module Nutella
34
34
  # If running on the internal broker, stop it if needed
35
35
  if Nutella.runlist.empty?
36
36
  stop_internal_broker
37
+ stop_mongo
37
38
  end
38
39
 
39
40
  # Output success message
@@ -80,6 +81,12 @@ module Nutella
80
81
  end
81
82
 
82
83
 
84
+ def stop_mongo
85
+ pid_file_path = "#{Nutella.config['config_dir']}.mongo_pid"
86
+ kill_process_with_pid pid_file_path
87
+ end
88
+
89
+
83
90
  # Does the process pid file exist?
84
91
  # If it does we send a SIGKILL to the process with that pid
85
92
  # to stop the process and delete the pid file
@@ -24,6 +24,27 @@ class ComponentsStarter
24
24
  end
25
25
 
26
26
 
27
+ # Starts mongodb if it's not started already.
28
+ # This operation is only necessary on mac because Ubuntu automatically
29
+ # installs mongo as a service and runs it.
30
+ # @return [boolean] true if mongo has been correctly started, false otherwise
31
+ def self.start_mongo_db
32
+ pid_file_path = "#{Nutella.config['config_dir']}.mongo_pid"
33
+ # Check if the process with pid indicated in the pidfile is alive
34
+ return true if sanitize_pid_file pid_file_path
35
+ # Check that mongo is not running 'unsupervised' (i.e. check port 27017), if it is, return
36
+ return true unless mongo_port_free?
37
+ # Mongo is not running and there is no pid file so we try to start it and create a new pid file.
38
+ # Note that the pid file is created by the `startup` script, not here.
39
+ pid = fork
40
+ exec("mongod --config /usr/local/etc/mongod.conf > /dev/null 2>&1 & \necho $! > #{pid_file_path}") if pid.nil?
41
+ # Wait a bit to give the chance to mongo to actually start up
42
+ sleep 1
43
+ # All went well so we return true
44
+ true
45
+ end
46
+
47
+
27
48
  # Starts all framework components. If order.json is present, components are started
28
49
  # in that order.
29
50
  # @return [boolean] true if all components are started correctly, false otherwise
@@ -128,6 +149,21 @@ class ComponentsStarter
128
149
  private_class_method :broker_port_free?
129
150
 
130
151
 
152
+ # Checks if port 27017 (MongoDB standard port) is free
153
+ # or some other service is already listening on it
154
+ # @return [boolean] true if there is no mongo listening on port 27017, false otherwise
155
+ def self.mongo_port_free?
156
+ begin
157
+ s = TCPServer.new('0.0.0.0', 27017)
158
+ s.close
159
+ rescue
160
+ return false
161
+ end
162
+ true
163
+ end
164
+ private_class_method :mongo_port_free?
165
+
166
+
131
167
  # Starts a single framework component
132
168
  # @return [boolean] true if the component has been started successfully, false otherwise
133
169
  def self.start_framework_component( component_dir )
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: nutella_framework 0.4.18 ruby lib
5
+ # stub: nutella_framework 0.4.19 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "nutella_framework"
9
- s.version = "0.4.18"
9
+ s.version = "0.4.19"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Alessandro Gnoli"]
14
- s.date = "2015-05-05"
14
+ s.date = "2015-05-12"
15
15
  s.description = "utella is a framework to create and run RoomApps"
16
16
  s.email = "tebemis@gmail.com"
17
17
  s.executables = ["nutella"]
@@ -103,6 +103,11 @@ Gem::Specification.new do |s|
103
103
  "framework_components/main_interface/startup",
104
104
  "framework_components/main_interface/views/index.erb",
105
105
  "framework_components/main_interface/views/not_found_404.erb",
106
+ "framework_components/monitoring-bot/.gitignore",
107
+ "framework_components/monitoring-bot/README.md",
108
+ "framework_components/monitoring-bot/monitoring-bot.rb",
109
+ "framework_components/monitoring-bot/nutella.json",
110
+ "framework_components/monitoring-bot/startup",
106
111
  "framework_components/order.json",
107
112
  "framework_components/roomcast-bot/data/default/channels-data.json",
108
113
  "framework_components/roomcast-bot/data/default/channels.json",
@@ -334,6 +339,8 @@ Gem::Specification.new do |s|
334
339
  s.add_runtime_dependency(%q<nokogiri>, ["~> 1.6"])
335
340
  s.add_runtime_dependency(%q<slop>, ["~> 4.0"])
336
341
  s.add_runtime_dependency(%q<nutella_lib>, [">= 0.4.12", "~> 0.4"])
342
+ s.add_runtime_dependency(%q<activesupport>, ["~> 4.2"])
343
+ s.add_runtime_dependency(%q<mandrill-api>, [">= 1.0.53", "~> 1.0"])
337
344
  s.add_development_dependency(%q<shoulda>, ["~> 3.0"])
338
345
  s.add_development_dependency(%q<yard>, ["~> 0.8"])
339
346
  s.add_development_dependency(%q<rdoc>, ["~> 4.0"])
@@ -350,6 +357,8 @@ Gem::Specification.new do |s|
350
357
  s.add_dependency(%q<nokogiri>, ["~> 1.6"])
351
358
  s.add_dependency(%q<slop>, ["~> 4.0"])
352
359
  s.add_dependency(%q<nutella_lib>, [">= 0.4.12", "~> 0.4"])
360
+ s.add_dependency(%q<activesupport>, ["~> 4.2"])
361
+ s.add_dependency(%q<mandrill-api>, [">= 1.0.53", "~> 1.0"])
353
362
  s.add_dependency(%q<shoulda>, ["~> 3.0"])
354
363
  s.add_dependency(%q<yard>, ["~> 0.8"])
355
364
  s.add_dependency(%q<rdoc>, ["~> 4.0"])
@@ -367,6 +376,8 @@ Gem::Specification.new do |s|
367
376
  s.add_dependency(%q<nokogiri>, ["~> 1.6"])
368
377
  s.add_dependency(%q<slop>, ["~> 4.0"])
369
378
  s.add_dependency(%q<nutella_lib>, [">= 0.4.12", "~> 0.4"])
379
+ s.add_dependency(%q<activesupport>, ["~> 4.2"])
380
+ s.add_dependency(%q<mandrill-api>, [">= 1.0.53", "~> 1.0"])
370
381
  s.add_dependency(%q<shoulda>, ["~> 3.0"])
371
382
  s.add_dependency(%q<yard>, ["~> 0.8"])
372
383
  s.add_dependency(%q<rdoc>, ["~> 4.0"])
@@ -169,14 +169,19 @@ module Nutella
169
169
  # - [Hash] from: the sender's identifiers (run_id, app_id, component_id and optionally resource_id)
170
170
  def self.subscribe_to_all_runs( channel, callback )
171
171
  # Check the passed callback has the right number of arguments
172
- raise 'You need to pass a callback with 4 parameters (payload, app_id, run_id, from) when subscribing to all runs!' if callback.parameters.length!=4
172
+ raise 'You need to pass a callback with 4 parameters (payload, app_id, run_id, from) when subscribing to all runs!' if callback.parameters.length!=4 && callback.parameters.length!=5
173
173
  # Pad channel
174
174
  padded_channel = Nutella::Net.pad_channel(channel, '+', '+')
175
175
  mqtt_cb = lambda do |mqtt_message, mqtt_channel|
176
176
  begin
177
177
  type, from, payload, _ = Nutella::Net.extract_fields_from_message mqtt_message
178
178
  app_id, run_id = self.extract_run_id_and_app_id mqtt_channel
179
- callback.call(payload, app_id, run_id, from) if type=='publish'
179
+ if channel.include?('#')
180
+ unpadded_channel = un_pad_wildcard_channel(mqtt_channel)
181
+ callback.call(unpadded_channel, payload, app_id, run_id, from) if type=='publish'
182
+ else
183
+ callback.call(payload, app_id, run_id, from) if type=='publish'
184
+ end
180
185
  rescue JSON::ParserError
181
186
  # Make sure the message is JSON, if not drop the message
182
187
  return
@@ -193,6 +198,11 @@ module Nutella
193
198
  Nutella::Net.publish_to('subscriptions', {'type' => 'subscribe', 'channel' => padded_channel}, nil, nil)
194
199
  end
195
200
 
201
+ def self.un_pad_wildcard_channel(channel)
202
+ regex = Regexp.new '/nutella/apps/[^"\/"]+/runs/[^"\/"]+/'
203
+ channel.gsub(regex, '')
204
+ end
205
+
196
206
 
197
207
  # Allows framework-level APIs to unsubscribe from a run-level channel *for ALL runs*
198
208
  #
@@ -270,6 +280,32 @@ module Nutella
270
280
  Nutella::Net.publish_to('subscriptions', {'type' => 'handle_requests', 'channel' => padded_channel}, nil, nil)
271
281
  end
272
282
 
283
+ def self.catch_requests_on_all_runs_wildcard(callback)
284
+ # Pad channel
285
+ padded_channel = Nutella::Net.pad_channel("#", '+', '+')
286
+ mqtt_cb = lambda do |request, mqtt_channel|
287
+ begin
288
+ # Extract nutella fields
289
+ type, from, payload, id = Nutella::Net.extract_fields_from_message request
290
+ app_id, run_id = self.extract_run_id_and_app_id mqtt_channel
291
+ # Only handle requests that have proper id set
292
+ return if type!='request' || id.nil?
293
+ # Execute callback and send response
294
+ regex = Regexp.new '/nutella/apps/[^"\/"]+/runs/[^"\/"]+/'
295
+ unpadded_channel = mqtt_channel.gsub(regex, '')
296
+ callback.call( unpadded_channel, payload, app_id, run_id, from)
297
+ rescue JSON::ParserError
298
+ # Make sure that request contains JSON, if not drop the message
299
+ return
300
+ rescue ArgumentError
301
+ # Check the passed callback has the right number of arguments
302
+ STDERR.puts "The callback you passed to subscribe has the #{$!}: it needs 'request', 'app_id', 'run_id' and 'from'"
303
+ end
304
+ end
305
+ # Subscribe to the channel
306
+ Nutella.mqtt.subscribe( padded_channel, mqtt_cb )
307
+ end
308
+
273
309
  # @!endgroup
274
310
 
275
311
  # ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nutella_framework
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.18
4
+ version: 0.4.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alessandro Gnoli
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-05 00:00:00.000000000 Z
11
+ date: 2015-05-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: semantic
@@ -142,6 +142,40 @@ dependencies:
142
142
  - - "~>"
143
143
  - !ruby/object:Gem::Version
144
144
  version: '0.4'
145
+ - !ruby/object:Gem::Dependency
146
+ name: activesupport
147
+ requirement: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - "~>"
150
+ - !ruby/object:Gem::Version
151
+ version: '4.2'
152
+ type: :runtime
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - "~>"
157
+ - !ruby/object:Gem::Version
158
+ version: '4.2'
159
+ - !ruby/object:Gem::Dependency
160
+ name: mandrill-api
161
+ requirement: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: 1.0.53
166
+ - - "~>"
167
+ - !ruby/object:Gem::Version
168
+ version: '1.0'
169
+ type: :runtime
170
+ prerelease: false
171
+ version_requirements: !ruby/object:Gem::Requirement
172
+ requirements:
173
+ - - ">="
174
+ - !ruby/object:Gem::Version
175
+ version: 1.0.53
176
+ - - "~>"
177
+ - !ruby/object:Gem::Version
178
+ version: '1.0'
145
179
  - !ruby/object:Gem::Dependency
146
180
  name: shoulda
147
181
  requirement: !ruby/object:Gem::Requirement
@@ -318,6 +352,11 @@ files:
318
352
  - framework_components/main_interface/startup
319
353
  - framework_components/main_interface/views/index.erb
320
354
  - framework_components/main_interface/views/not_found_404.erb
355
+ - framework_components/monitoring-bot/.gitignore
356
+ - framework_components/monitoring-bot/README.md
357
+ - framework_components/monitoring-bot/monitoring-bot.rb
358
+ - framework_components/monitoring-bot/nutella.json
359
+ - framework_components/monitoring-bot/startup
321
360
  - framework_components/order.json
322
361
  - framework_components/roomcast-bot/data/default/channels-data.json
323
362
  - framework_components/roomcast-bot/data/default/channels.json