sfpagent 0.1.6 → 0.1.9

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.

Potentially problematic release.


This version of sfpagent might be problematic. Click here for more details.

@@ -7,45 +7,42 @@ require 'uri'
7
7
  require 'net/http'
8
8
  require 'logger'
9
9
  require 'json'
10
+ require 'digest/md5'
10
11
 
11
12
  module Sfp
12
13
  module Agent
13
14
  NetHelper = Object.new.extend(Nuri::Net::Helper)
14
15
 
15
- if Process.euid == 0
16
- CachedDir = '/var/sfpagent'
17
- else
18
- CachedDir = File.expand_path('~/.sfpagent')
19
- end
16
+ CachedDir = (Process.euid == 0 ? '/var/sfpagent' : File.expand_path('~/.sfpagent'))
20
17
  Dir.mkdir(CachedDir, 0700) if not File.exist?(CachedDir)
21
18
 
22
19
  DefaultPort = 1314
20
+
23
21
  PIDFile = "#{CachedDir}/sfpagent.pid"
24
22
  LogFile = "#{CachedDir}/sfpagent.log"
25
23
  ModelFile = "#{CachedDir}/sfpagent.model"
26
24
  AgentsDataFile = "#{CachedDir}/sfpagent.agents"
27
25
 
26
+ BSigFile = "#{CachedDir}/bsig.model"
27
+ BSigPIDFile = "#{CachedDir}/bsig.pid"
28
+
28
29
  @@logger = WEBrick::Log.new(LogFile, WEBrick::BasicLog::INFO ||
29
30
  WEBrick::BasicLog::ERROR ||
30
31
  WEBrick::BasicLog::FATAL ||
31
32
  WEBrick::BasicLog::WARN)
32
33
 
33
- @@model_lock = Mutex.new
34
+ @@current_model_hash = nil
35
+
36
+ @@bsig = nil
37
+ @@bsig_modified_time = nil
38
+ @@bsig_engine = Sfp::BSig.new # create BSig engine instance
39
+
34
40
  @@runtime_lock = Mutex.new
35
41
 
36
42
  def self.logger
37
43
  @@logger
38
44
  end
39
45
 
40
- def self.check_config(p={})
41
- # check modules directory, and create it if it's not exist
42
- p[:modules_dir] = "#{CachedDir}/modules" if p[:modules_dir].to_s.strip == ''
43
- p[:modules_dir] = File.expand_path(p[:modules_dir].to_s)
44
- p[:modules_dir].chop! if p[:modules_dir][-1,1] == '/'
45
- Dir.mkdir(p[:modules_dir], 0700) if not File.exists?(p[:modules_dir])
46
- p
47
- end
48
-
49
46
  # Start the agent.
50
47
  #
51
48
  # options:
@@ -56,14 +53,29 @@ module Sfp
56
53
  # :keyfile
57
54
  #
58
55
  def self.start(p={})
56
+ Process.daemon
57
+
59
58
  begin
60
- @@config = p = check_config(p)
61
-
59
+ # check modules directory, and create it if it's not exist
60
+ p[:modules_dir] = File.expand_path(p[:modules_dir].to_s.strip != '' ? p[:modules_dir].to_s : "#{CachedDir}/modules")
61
+ Dir.mkdir(p[:modules_dir], 0700) if not File.exist?(p[:modules_dir])
62
+ @@config = p
63
+ Sfp::Agent.logger.info "modules dir: " + p[:modules_dir]
64
+
65
+ # load modules from cached directory
66
+ load_modules(p)
67
+
68
+ # reload model
69
+ build_model({:complete => true})
70
+
71
+ # create web server
62
72
  server_type = (p[:daemon] ? WEBrick::Daemon : WEBrick::SimpleServer)
63
73
  port = (p[:port] ? p[:port] : DefaultPort)
64
-
65
- config = {:Host => '0.0.0.0', :Port => port, :ServerType => server_type,
66
- :Logger => @@logger}
74
+ config = { :Host => '0.0.0.0',
75
+ :Port => port,
76
+ :ServerType => server_type,
77
+ :pid => '/tmp/webrick.pid',
78
+ :Logger => Sfp::Agent.logger }
67
79
  if p[:ssl]
68
80
  config[:SSLEnable] = true
69
81
  config[:SSLVerifyClient] = OpenSSL::SSL::VERIFY_NONE
@@ -71,36 +83,44 @@ module Sfp
71
83
  config[:SSLPrivateKey] = OpenSSL::PKey::RSA.new(File.open(p[:keyfile]).read)
72
84
  config[:SSLCertName] = [["CN", WEBrick::Utils::getservername]]
73
85
  end
74
-
75
- load_modules(p)
76
- reload_model
77
-
78
86
  server = WEBrick::HTTPServer.new(config)
79
- server.mount("/", Sfp::Agent::Handler, @@logger)
87
+ server.mount("/", Sfp::Agent::Handler, Sfp::Agent.logger)
88
+
89
+ # trap signal
90
+ ['INT', 'KILL', 'HUP'].each { |signal|
91
+ trap(signal) {
92
+ Sfp::Agent.logger.info "Shutting down web server"
93
+ server.shutdown
94
+ }
95
+ }
80
96
 
97
+ # send request to local web server to save its PID
81
98
  fork {
82
- begin
83
- # send request to save PID
84
- sleep 2
85
- url = URI.parse("http://127.0.0.1:#{config[:Port]}/pid")
86
- http = Net::HTTP.new(url.host, url.port)
87
- if p[:ssl]
88
- http.use_ssl = p[:ssl]
89
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
99
+ sleep 0.5
100
+ 1.upto(5) do |i|
101
+ begin
102
+ NetHelper.get_data('127.0.0.1', config[:Port], '/pid')
103
+ break if File.exist?(PIDFile)
104
+ rescue
105
+ sleep (i*i)
90
106
  end
91
- req = Net::HTTP::Get.new(url.path)
92
- http.request(req)
93
- puts "\nSFP Agent is running with PID #{File.read(PIDFile)}" if File.exist?(PIDFile)
94
- rescue Exception => e
95
- Sfp::Agent.logger.warn "Cannot request /pid #{e}"
96
107
  end
108
+ puts "SFP Agent is running with PID #{File.read(PIDFile)}" if File.exist?(PIDFile)
97
109
  }
98
110
 
99
- trap('INT') { server.shutdown }
111
+ # start BSig's main thread in a separate process
112
+ fork {
113
+ bsig_engine.enable({:mode => :main})
114
+ }
115
+
116
+ # enable BSig's satisfier
117
+ bsig_engine.enable({:mode => :satisfier})
100
118
 
119
+ # start web server
101
120
  server.start
121
+
102
122
  rescue Exception => e
103
- @@logger.error "Starting the agent [Failed] #{e}"
123
+ Sfp::Agent.logger.error "Starting the agent [Failed] #{e}\n#{e.backtrace.join("\n")}"
104
124
  raise e
105
125
  end
106
126
  end
@@ -108,25 +128,36 @@ module Sfp
108
128
  # Stop the agent's daemon.
109
129
  #
110
130
  def self.stop
131
+ # stopping web server (main thread)
111
132
  pid = (File.exist?(PIDFile) ? File.read(PIDFile).to_i : nil)
112
133
  if not pid.nil? and `ps h #{pid}`.strip =~ /.*sfpagent.*/
113
- print "Stopping SFP Agent with PID #{pid} "
114
- Process.kill('KILL', pid)
115
- puts "[OK]"
116
- @@logger.info "SFP Agent daemon has been stopped."
134
+ Process.kill('HUP', pid)
135
+ puts "Stopping SFP Agent with PID #{pid}"
136
+ File.delete(PIDFile) if File.exist?(PIDFile)
117
137
  else
118
138
  puts "SFP Agent is not running."
119
139
  end
120
- File.delete(PIDFile) if File.exist?(PIDFile)
140
+
141
+ # stopping BSig engine
142
+ pid_bsig = (File.exist?(BSigPIDFile) ? File.read(BSigPIDFile).to_i : nil)
143
+ if not pid_bsig.nil? and `ps h #{pid_bsig}`.strip =~ /.*sfpagent.*/
144
+ Process.kill('HUP', pid_bsig)
145
+ puts "Stopping BSig engine with PID #{pid_bsig}"
146
+ File.delete(BSigPIDFile) if File.exist?(BSigPIDFile)
147
+ else
148
+ puts "BSig engine is not running."
149
+ end
150
+
151
+ Sfp::Agent.logger.info "SFP Agent daemon has been stopped."
121
152
  end
122
153
 
123
154
  # Print the status of the agent.
124
155
  #
125
156
  def self.status
126
- pid = (File.exist?(PIDFile) ? File.read(PIDFile).to_i : nil)
127
- if pid.nil?
157
+ if not File.exist?(PIDFile)
128
158
  puts "SFP Agent is not running."
129
159
  else
160
+ pid = File.read(PIDFile).to_i
130
161
  if `ps hf #{pid}`.strip =~ /.*sfpagent.*/
131
162
  puts "SFP Agent is running with PID #{pid}"
132
163
  else
@@ -134,56 +165,118 @@ module Sfp
134
165
  puts "SFP Agent is not running."
135
166
  end
136
167
  end
168
+
169
+ if not File.exist?(BSigPIDFile)
170
+ puts "BSig engine is not running."
171
+ else
172
+ pid = File.read(BSigPIDFile).to_i
173
+ if `ps hf #{pid}`.strip =~ /.*sfpagent.*/
174
+ puts "BSig engine is running with PID #{pid}"
175
+ else
176
+ File.delete(BSigPIDFile)
177
+ puts "BSig engine is not running."
178
+ end
179
+ end
137
180
  end
138
181
 
139
182
  # Save given model to cached file, and then reload the model.
140
183
  #
141
184
  def self.set_model(model)
142
185
  begin
143
- @@model_lock.synchronize {
144
- @@logger.info "Setting the model [Wait]"
145
- File.open(ModelFile, 'w', 0600) { |f|
146
- f.write(JSON.generate(model))
186
+ # generate MD5 hash for the new model
187
+ data = JSON.generate(model)
188
+ new_model_hash = Digest::MD5.hexdigest(data)
189
+
190
+ # save the new model if it's not same with the existing one
191
+ if Digest::MD5.hexdigest(data) != @@current_model_hash
192
+ Sfp::Agent.logger.info "Setting new model [Wait]"
193
+ File.open(ModelFile, File::RDWR|File::CREAT, 0600) { |f|
194
+ f.flock(File::LOCK_EX)
195
+ f.rewind
196
+ f.write(data)
147
197
  f.flush
198
+ f.truncate(f.pos)
148
199
  }
149
- }
150
- reload_model
151
- @@logger.info "Setting the model [OK]"
200
+ build_model
201
+ Sfp::Agent.logger.info "Setting the model [OK]"
202
+ else
203
+ #Sfp::Agent.logger.info "The model is not changed."
204
+ end
152
205
  return true
153
206
  rescue Exception => e
154
- @@logger.error "Setting the model [Failed] #{e}"
207
+ Sfp::Agent.logger.error "Setting the model [Failed] #{e}\n#{e.backtrace.join("\n")}"
155
208
  end
156
209
  false
157
210
  end
158
211
 
159
- # Return the model which is read from cached file.
212
+ # Reload the model from cached file.
213
+ #
214
+ def self.build_model(p={})
215
+ if not File.exist?(ModelFile)
216
+ Sfp::Agent.logger.info "There is no model in cache."
217
+ else
218
+ begin
219
+ @@runtime_lock.synchronize {
220
+ data = File.read(ModelFile)
221
+ @@current_model_hash = Digest::MD5.hexdigest(data)
222
+ if !defined?(@@runtime) or @@runtime.nil? or p[:complete]
223
+ @@runtime = Sfp::Runtime.new(JSON[data])
224
+ else
225
+ @@runtime.set_model(JSON[data])
226
+ end
227
+ }
228
+ Sfp::Agent.logger.info "Reloading the model in cache [OK]"
229
+ rescue Exception => e
230
+ Sfp::Agent.logger.error "Reloading the model in cache [Failed] #{e}\n#{e.backtrace.join("\n")}"
231
+ end
232
+ end
233
+ end
234
+
235
+ # Setting a new BSig model: set @@bsig variable, and save in cached file
160
236
  #
161
- def self.get_model
162
- return nil if not File.exist?(ModelFile)
237
+ def self.set_bsig(bsig)
163
238
  begin
164
- @@model_lock.synchronize {
165
- return JSON[File.read(ModelFile)]
239
+ File.open(BSigFile, File::RDWR|File::CREAT, 0600) { |f|
240
+ f.flock(File::LOCK_EX)
241
+ Sfp::Agent.logger.info "Setting the BSig model [Wait]"
242
+ f.rewind
243
+ data = (bsig.nil? ? '' : JSON.generate(bsig))
244
+ f.write(data)
245
+ f.flush
246
+ f.truncate(f.pos)
166
247
  }
248
+ Sfp::Agent.logger.info "Setting the BSig model [OK]"
249
+ return true
167
250
  rescue Exception => e
168
- @@logger.error "Get the model [Failed] #{e}\n#{e.backtrace}"
251
+ Sfp::Agent.logger.error "Setting the BSig model [Failed] #{e}\n#{e.backtrace.join("\n")}"
169
252
  end
170
253
  false
171
254
  end
172
255
 
173
- # Reload the model from cached file.
256
+ # Return a BSig model from cached file
174
257
  #
175
- def self.reload_model
176
- model = get_model
177
- if model.nil?
178
- @@logger.info "There is no model in cache."
179
- else
180
- begin
181
- @@runtime_lock.synchronize { @@runtime = Sfp::Runtime.new(model) }
182
- @@logger.info "Reloading the model in cache [OK]"
183
- rescue Exception => e
184
- @@logger.error "Reloading the model in cache [Failed] #{e}"
185
- end
258
+ def self.get_bsig
259
+ return nil if not File.exist?(BSigFile)
260
+ return @@bsig if File.mtime(BSigFile) == @@bsig_modified_time
261
+
262
+ begin
263
+ data = File.read(BSigFile)
264
+ @@bsig = (data.length > 0 ? JSON[data] : nil)
265
+ @@bsig_modified_time = File.mtime(BSigFile)
266
+ return @@bsig
267
+ rescue Exception => e
268
+ Sfp::Agent.logger.error "Get the BSig model [Failed] #{e}\n#{e.backtrace.join("\n")}"
186
269
  end
270
+ false
271
+ end
272
+
273
+ def self.bsig_engine
274
+ @@bsig_engine
275
+ end
276
+
277
+ def self.whoami?
278
+ return nil if !defined?(@@runtime) or @@runtime.nil?
279
+ @@runtime.whoami?
187
280
  end
188
281
 
189
282
  # Return the current state of the model.
@@ -192,33 +285,31 @@ module Sfp
192
285
  @@runtime_lock.synchronize {
193
286
  return nil if !defined?(@@runtime) or @@runtime.nil?
194
287
  begin
195
- @@runtime.get_state if @@runtime.modules.nil?
196
288
  return @@runtime.get_state(as_sfp)
197
289
  rescue Exception => e
198
- @@logger.error "Get state [Failed] #{e}\n#{e.backtrace.join("\n")}"
290
+ Sfp::Agent.logger.error "Get state [Failed] #{e}\n#{e.backtrace.join("\n")}"
199
291
  end
200
292
  }
201
293
  false
202
294
  end
203
295
 
204
296
  def self.resolve(path, as_sfp=true)
297
+ return Sfp::Undefined.new if !defined?(@@runtime) or @@runtime.nil? or @@runtime.root.nil?
205
298
  begin
206
- #@@runtime_lock.synchronize {
207
- return Sfp::Undefined.new if !defined?(@@runtime) or @@runtime.nil? or @@runtime.modules.nil?
208
- path = path.simplify
209
- _, node, _ = path.split('.', 3)
210
- if @@runtime.modules.has_key?(node)
211
- # local resolve
212
- parent, attribute = path.pop_ref
213
- mod = @@runtime.modules.at?(parent)
214
- if mod.is_a?(Hash)
215
- mod[:_self].update_state
216
- state = mod[:_self].state
217
- return state[attribute] if state.has_key?(attribute)
218
- end
219
- return Sfp::Undefined.new
299
+ path = path.simplify
300
+ _, node, _ = path.split('.', 3)
301
+ if @@runtime.root.has_key?(node)
302
+ # local resolve
303
+ parent, attribute = path.pop_ref
304
+ mod = @@runtime.root.at?(parent)
305
+ if mod.is_a?(Hash)
306
+ mod[:_self].update_state
307
+ state = mod[:_self].state
308
+ return state[attribute] if state.has_key?(attribute)
220
309
  end
221
- #}
310
+ return Sfp::Undefined.new
311
+ end
312
+
222
313
  agents = get_agents
223
314
  if agents[node].is_a?(Hash)
224
315
  # remote resolve
@@ -232,7 +323,7 @@ module Sfp
232
323
  end
233
324
  end
234
325
  rescue Exception => e
235
- @@logger.error "Resolve #{path} [Failed] #{e}\n#{e.backtrace.join("\n")}"
326
+ Sfp::Agent.logger.error "Resolve #{path} [Failed] #{e}\n#{e.backtrace.join("\n")}"
236
327
  end
237
328
  Sfp::Undefined.new
238
329
  end
@@ -242,15 +333,14 @@ module Sfp
242
333
  # @param action contains the action's schema.
243
334
  #
244
335
  def self.execute_action(action)
245
- logger = (@@config[:daemon] ? @@logger : Logger.new(STDOUT))
336
+ logger = (@@config[:daemon] ? Sfp::Agent.logger : Logger.new(STDOUT))
246
337
  action_string = "#{action['name']} #{JSON.generate(action['parameters'])}"
247
338
  begin
248
339
  result = @@runtime.execute_action(action)
249
340
  logger.info "Executing #{action_string} " + (result ? "[OK]" : "[Failed]")
250
341
  return result
251
342
  rescue Exception => e
252
- logger.info "Executing #{action_string} [Failed] #{e}\n#{e.backtrace.join("\n")}"
253
- logger.error "#{e}\n#{e.bracktrace.join("\n")}"
343
+ logger.error "Executing #{action_string} [Failed] #{e}\n#{e.backtrace.join("\n")}"
254
344
  end
255
345
  false
256
346
  end
@@ -266,22 +356,22 @@ module Sfp
266
356
  @@modules = []
267
357
  counter = 0
268
358
  if dir != '' and File.exist?(dir)
269
- @@logger.info "Modules directory: #{dir}"
359
+ Sfp::Agent.logger.info "Modules directory: #{dir}"
270
360
  Dir.entries(dir).each { |name|
271
361
  next if name == '.' or name == '..' or File.file?("#{dir}/#{name}")
272
362
  module_file = "#{dir}/#{name}/#{name}.rb"
273
363
  next if not File.exist?(module_file)
274
364
  begin
275
365
  load module_file #require module_file
276
- @@logger.info "Loading module #{dir}/#{name} [OK]"
366
+ Sfp::Agent.logger.info "Loading module #{dir}/#{name} [OK]"
277
367
  counter += 1
278
368
  @@modules << name
279
369
  rescue Exception => e
280
- @@logger.warn "Loading module #{dir}/#{name} [Failed]\n#{e}"
370
+ Sfp::Agent.logger.warn "Loading module #{dir}/#{name} [Failed]\n#{e}"
281
371
  end
282
372
  }
283
373
  end
284
- @@logger.info "Successfully loading #{counter} modules."
374
+ Sfp::Agent.logger.info "Successfully loading #{counter} modules."
285
375
  end
286
376
 
287
377
  def self.get_schemata(module_name)
@@ -312,17 +402,16 @@ module Sfp
312
402
  data = {}
313
403
  @@modules.each { |m| data[m] = get_module_hash(m) }
314
404
  data
315
- #(defined?(@@modules) and @@modules.is_a?(Array) ? @@modules : [])
316
405
  end
317
406
 
318
407
  def self.uninstall_all_modules(p={})
319
408
  return true if @@config[:modules_dir] == ''
320
409
  if system("rm -rf #{@@config[:modules_dir]}/*")
321
410
  load_modules(@@config)
322
- @@logger.info "Deleting all modules [OK]"
411
+ Sfp::Agent.logger.info "Deleting all modules [OK]"
323
412
  return true
324
413
  end
325
- @@logger.info "Deleting all modules [Failed]"
414
+ Sfp::Agent.logger.info "Deleting all modules [Failed]"
326
415
  false
327
416
  end
328
417
 
@@ -336,7 +425,7 @@ module Sfp
336
425
  result = true
337
426
  end
338
427
  load_modules(@@config)
339
- @@logger.info "Deleting module #{name} " + (result ? "[OK]" : "[Failed]")
428
+ Sfp::Agent.logger.info "Deleting module #{name} " + (result ? "[OK]" : "[Failed]")
340
429
  result
341
430
  end
342
431
 
@@ -366,7 +455,11 @@ module Sfp
366
455
  system("cd #{module_dir}; rm data.tgz")
367
456
  }
368
457
  load_modules(@@config)
369
- @@logger.info "Installing module #{name} [OK]"
458
+
459
+ # rebuild the model
460
+ build_model({:complete => true})
461
+
462
+ Sfp::Agent.logger.info "Installing module #{name} [OK]"
370
463
 
371
464
  true
372
465
  end
@@ -399,9 +492,12 @@ module Sfp
399
492
  true
400
493
  end
401
494
 
495
+ @@agents_data = nil
496
+ @@agents_data_modified_time = nil
402
497
  def self.get_agents
403
498
  return {} if not File.exist?(AgentsDataFile)
404
- JSON[File.read(AgentsDataFile)]
499
+ return @@agents_data if File.mtime(AgentsDataFile) == @@agents_data_modified_time
500
+ @@agents_data = JSON[File.read(AgentsDataFile)]
405
501
  end
406
502
 
407
503
  # A class that handles each request.
@@ -445,6 +541,9 @@ module Sfp
445
541
  elsif path == '/model'
446
542
  status, content_type, body = get_model
447
543
 
544
+ elsif path == '/bsig'
545
+ status, content_Type, body = get_bsig
546
+
448
547
  elsif path =~ /^\/schemata\/.+/
449
548
  status, content_type, body = get_schemata({:module => path[10, path.length-10]})
450
549
 
@@ -469,8 +568,6 @@ module Sfp
469
568
  #
470
569
  # uri:
471
570
  # /execute => receive an action's schema and execute it
472
- # /migrate => SFP object migration
473
- # /duplicate => SFP object duplication
474
571
  #
475
572
  def do_POST(request, response)
476
573
  status = 400
@@ -481,14 +578,6 @@ module Sfp
481
578
  path = (request.path[-1,1] == '/' ? ryyequest.path.chop : request.path)
482
579
  if path == '/execute'
483
580
  status, content_type, body = self.execute({:query => request.query})
484
-
485
- elsif path =~ /\/migrate\/.+/
486
- status, content_type, body = self.migrate({:src => path[8, path.length-8],
487
- :dest => request.query['destination']})
488
-
489
- elsif path =~ /\/duplicate\/.+/
490
- # TODO
491
-
492
581
  end
493
582
  end
494
583
 
@@ -524,6 +613,12 @@ module Sfp
524
613
  elsif path == '/agents'
525
614
  status, content_type, body = self.manage_agents({:query => request.query})
526
615
 
616
+ elsif path == '/bsig'
617
+ status, content_type, body = self.set_bsig({:query => request.query})
618
+
619
+ elsif path == '/bsig/satisfier'
620
+ status, content_type, body = self.satisfy_bsig_request({:query => request.query})
621
+
527
622
  end
528
623
  end
529
624
 
@@ -532,35 +627,6 @@ module Sfp
532
627
  response.body = body
533
628
  end
534
629
 
535
- def migrate(p={})
536
- # migrate: source path, destination path
537
- #@logger.info "migrate #{p[:src]} => #{p[:dest]}"
538
- return [400, 'plain/text', 'Destination path should begin with "/"'] if p[:dest].to_s[0,1] != '/'
539
- begin
540
- # reformat the source and destination paths to SFP reference
541
- p[:src] = '$' + p[:src].gsub(/\//, '.')
542
- p[:dest] = '$' + p[:dest].gsub(/\//, '.')
543
-
544
- # find the target in agents' database
545
- agents = Sfp::Agent.get_agents
546
- data = agents.at?(p[:dest])
547
- return [404, 'plain/text', 'Unrecognized destination!'] if !data.is_a?(Hash)
548
-
549
- # send the sub-model to destination
550
- model = Sfp::Agent.get_model
551
- return [404, '', ''] if model.nil?
552
- submodel = model.at?(p[:src])
553
-
554
- # TODO
555
- # 1. send the configuration to destination
556
-
557
- return [200, 'plain/text', "#{p[:src]} #{p[:dest]}:#{data.inspect}"]
558
- rescue Exception => e
559
- @logger.error "Migration failed #{e}\n#{e.backtrace.join("\n")}"
560
- end
561
- return [500, 'plain/text', e.to_s]
562
- end
563
-
564
630
  def manage_agents(p={})
565
631
  begin
566
632
  if p[:query].has_key?('agents')
@@ -614,11 +680,11 @@ module Sfp
614
680
  end
615
681
 
616
682
  def set_model(p={})
617
- if p[:query].has_key?('model')
618
- Setting the model was success, and then return '200' status.
683
+ if p[:query] and p[:query].has_key?('model')
684
+ If setting the model was success, then return '200' status.
619
685
  return [200, '', ''] if Sfp::Agent.set_model(JSON[p[:query]['model']])
620
686
  else
621
- # Remove the existing model by setting an empty model
687
+ # Removing the existing model by setting an empty model, if it's success then return '200' status.
622
688
  return [200, '', ''] if Sfp::Agent.set_model({})
623
689
  end
624
690
 
@@ -632,7 +698,7 @@ module Sfp
632
698
  # The model is not exist.
633
699
  return [404, '', ''] if model.nil?
634
700
 
635
- # The model is exist, and then send the model in JSON.
701
+ # The model is exist, and then send it in JSON.
636
702
  return [200, 'application/json', JSON.generate(model)] if !!model
637
703
 
638
704
  # There is an error when retrieving the model!
@@ -657,15 +723,48 @@ module Sfp
657
723
  [500, '', '']
658
724
  end
659
725
 
726
+ def set_bsig(p={})
727
+ if p[:query] and p[:query].has_key?('bsig')
728
+ # If setting the BSig model was success, then return '200' status
729
+ return [200, '', ''] if Sfp::Agent.set_bsig(JSON[p[:query]['bsig']])
730
+ else
731
+ # Deleting the existing BSig model by setting with Nil, if it's success then return '200' status.
732
+ return [200, '', ''] if Sfp::Agent.set_bsig(nil)
733
+ end
734
+
735
+ # There is an error on setting/deleting the BSig model
736
+ [500, '', '']
737
+ end
738
+
739
+ def get_bsig(p={})
740
+ bsig = Sfp::Agent.get_bsig
741
+
742
+ # The BSig model is not exist
743
+ return [404, '', ''] if bsig.nil?
744
+
745
+ # The BSig model is exist, and then send it in JSON
746
+ return [200, 'application/json', JSON.generate(bsig)] if !!bsig
747
+
748
+ [500, '', '']
749
+ end
750
+
751
+ def satisfy_bsig_request(p={})
752
+ return [400, '', ''] if not p[:query]
753
+
754
+ Sfp::Agent.logger.info Sfp::Agent.bsig_engine.to_s
755
+
756
+ return [500, '', ''] if Sfp::Agent.bsig_engine.nil?
757
+
758
+ req = p[:query]
759
+ return [200, '', ''] if Sfp::Agent.bsig_engine.receive_goal_from_agent(req['id'].to_i, JSON[req['goal']], req['pi'].to_i)
760
+
761
+ [500, '', '']
762
+ end
763
+
660
764
  def trusted(address)
661
765
  true
662
766
  end
663
- end
664
- end
665
767
 
666
- def self.require(gem, pack=nil)
667
- ::Kernel.require gem
668
- rescue LoadError => e
669
- ::Kernel.require gem if system("gem install #{pack||gem} --no-ri --no-rdoc")
768
+ end
670
769
  end
671
770
  end