Project

General

Profile

« Previous | Next » 

Revision feb16bd0

Added by Marc Dequènes about 13 years ago

  • ID feb16bd04a7ec187c0b34b06c5680c51197af84f

[evol] Cyborg/Interface: support returning API call replies asynchronously

View differences:

IDEAS
ordered_list.empty? ? nil : ordered_list.first.range
end
- leaf node feature: declare a node as leaf and pass all other node elements as parameters
- list node detection: when no on_request is specified, list of children nodes are given,
back, which could be very useful for auto-completion on the future CLI interface, but
we need to know when a real action is to be run, to avoid completion triggering them
Clerk:
- API:
......
+ I18n parameters (list of translation prefs)
Tasks:
- default error handler to avoid repeating on_error blocks with the
same code
- inheritance: thread data (auth token, I18n prefs…)
- wait notif on multiple channels:
by registering the same callback on multiple channels,
lib/cyborghood-librarian/interface/0_base.rb
on_request do |request|
request.reply.results = object_list.call
request.send_reply
end
attr_search_node do |criterias|
......
node object_list do
on_request do |request|
request.reply.results = object_list.call(node_name, :format => :data_hash)
request.send_reply
end
end
end
lib/cyborghood-mapmaker/interface/_zone/0_base.rb
node 'content' do
on_request do |request|
request.reply.results = {:content => zone.content}
request.send_reply
end
end
......
on_request do |request|
content = request.args.shift
if content.empty?
request.errors << "Zone content missing"
return
request.reply.errors << "Zone content missing"
else
begin
zone.content = content
rescue CyberError => e
request.reply.errors << e.message
end
end
begin
zone.content = content
rescue CyberError => e
request.reply.errors << e.message
end
request.send_reply
end
end
lib/cyborghood-mapmaker/interface/services/dns.rb
node 'DNS' do
on_request do |request|
request.reply.results = store.dns.info
request.send_reply
end
node 'check_config' do
on_request do |request|
request.reply.results = store.dns.check_config
request.send_reply
end
end
end
lib/cyborghood-mapmaker/interface/services/dnssec.rb
node 'DNSSEC' do
on_request do |request|
request.reply.results = bot.services.dnssec.info
request.send_reply
end
end
lib/cyborghood/cyborg/botnet.rb
:core_api_version => CORE_API_VERSION,
:cyborg_api_version => version
}
request.send_reply
end
end
end
lib/cyborghood/cyborg/botnet/interface.rb
request.reply.results = list.nil? ? search_among_children(request, lookup_node) :
search_in_list(request, lookup_node, list)
end
request.send_reply
end
end
end
......
not node.nil?
end
def _call(session, node_path, args = nil)
def _call(session, node_path, args = nil, &send_result_cb)
args ||= []
raise CyberError.new(:unrecoverable, 'api/cyborghood', "wrong format for arguments when calling node '#{node_path}'") unless args.is_a? Array
......
raise CyberError.new(:unrecoverable, 'api/cyborghood', "unknown node '#{node_path}'") if node.nil?
logger.debug "[Server API] Node '#{node_path}' found"
node.__send__(:request, session, args)
node.__send__(:request, session, args, &send_result_cb)
end
protected
......
class Request
attr_reader :session, :args, :reply
def initialize(session, args = [])
def initialize(session, args = [], &send_result_cb)
@session = session
@args = args
@send_result_cb = send_result_cb
@reply = {
:results => {},
......
:errors => []
}.to_ostruct
end
def send_reply
@send_result_cb.call @reply.to_hash
end
end
def request(session, args = [])
def request(session, args = [], &send_result_cb)
request = Request.new(session, args, &send_result_cb)
if @request_cb
request = Request.new(session, args)
begin
@request_cb.call(request)
# TODO: full reply needed
request.reply.results
rescue
logger.debug "node request error message: " + $!
logger.debug "node request error backtrace: " + $!.backtrace.join("\n")
raise CyberError.new(:unrecoverable, 'api/cyborghood', "call failed on node '#{node_path}': " + $!)
end
else
visible_nodes_names
request.reply.results = visible_nodes_names
request.send_reply
end
end
lib/cyborghood/cyborg/botnet/protocol.rb
end
def process_request_result(result)
# TODO: better processing of result (info/warnings/…)
if result[:error]
send_error_action(result[:reply_message], result[:error])
send_error_action(result[:reply_message], result[:errors])
else
send_reply_result(result[:reply_message], result[:action_result])
send_reply_result(result[:reply_message], result[:results])
end
end
......
:message => "missing parameters"
})
end
send_reply_ack(message)
@conversation.bot.schedule_task(@@request_callback) do
result = {
:reply_message => message
}
process_result_cb = Proc.new do |reply|
reply[:reply_message] = message
@@request_callback.call reply
end
@conversation.bot.schedule_task do
begin
result[:action_result] = @conversation.bot.interface._call(message.conv_thread.session,
@conversation.bot.interface._call(message.conv_thread.session,
message.action_parameters[:node],
message.action_parameters[:parameters])
message.action_parameters[:parameters],
&process_result_cb)
rescue CyberError => e
result[:error] = {
process_result_cb.call(:errors => [{
:category => e.category,
:severity => e.severity,
:message => e.message
}
}])
rescue
result[:error] = {
process_result_cb.call(:errors => [{
:category => 'unknown',
:severity => :unrecoverable,
:message => $!.to_s
}
}])
end
result
end
end
......
@conversation.bot.schedule_task(@@request_callback) do
{
:reply_message => message,
:action_result => @conversation.bot.interface._is_node?(message.conv_thread.session, message.action_parameters[:node])
:results => @conversation.bot.interface._is_node?(message.conv_thread.session, message.action_parameters[:node])
}
end
end

Also available in: Unified diff