nutella_framework 0.4.18 → 0.4.19

Sign up to get free protection for your applications and to get access to all the features.
@@ -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