Revision e82a264b
Added by Marc Dequènes over 14 years ago
- ID e82a264b9c5f51c4eb0d1cfffb37d5628c41bc88
bin/mapmaker | ||
---|---|---|
|
||
class Zones
|
||
include CyborgServerInterface
|
||
include CyborgServerStatefulInterface
|
||
|
||
def initialize
|
||
@dns = Services::DNS::System.new
|
||
... | ... | |
end
|
||
|
||
def method_missing(method_name, *args)
|
||
if api_methods.include?(method_name.to_s)
|
||
Zone.new(method_name.to_s)
|
||
session = args.shift
|
||
|
||
zone_name = method_name.to_s
|
||
if api_methods.include?(zone_name)
|
||
resource_key = "dns/zones/#{zone_name}"
|
||
session.store.get(resource_key) { Zone.new(zone_name) }
|
||
else
|
||
super
|
||
end
|
||
end
|
||
|
||
class Zone < Services::DNS::Zone
|
||
include CyborgServerEmbededInterface
|
||
include CyborgServerEmbeddedInterface
|
||
end
|
||
end
|
||
end
|
lib/cyborghood/cyborg/interface.rb | ||
---|---|---|
end
|
||
end
|
||
|
||
module CyborgServerEmbededInterface
|
||
module CyborgServerEmbeddedInterface
|
||
def self.included(base)
|
||
base.class_eval("include CyborgServerInterfaceBase")
|
||
base.export_parent_methods
|
||
end
|
||
end
|
||
|
||
module CyborgServerStatefulInterface
|
||
end
|
||
|
||
module CyborgServerInterfaceBase
|
||
NODE_PATTERN = "((?:\/|(?:\/[a-zA-Z0-9._]+)+[?=]?))"
|
||
|
||
... | ... | |
def api_methods
|
||
methods = self.class.exported_methods
|
||
methods += self.class.public_instance_methods(false) if self.class.auto_export_public_instance_methods
|
||
methods -= ["initialize", "__destroy", "method_missing"]
|
||
methods & self.methods
|
||
end
|
||
|
||
... | ... | |
(api_klasses.keys + api_methods).sort
|
||
end
|
||
|
||
def find_node_action(node_name)
|
||
def find_node_action(session, node_name)
|
||
node_name.gsub!(/^\//, "")
|
||
next_node_name, other_nodes_names = node_name.split('/', 2)
|
||
|
||
... | ... | |
# cannot use method(), as this method may not exist at all (but still
|
||
# be usuable through metaprogramming
|
||
return lambda do |*args|
|
||
r = self.send(next_node_name, *args)
|
||
r = child_node(next_node_name, session, *args)
|
||
# dynamic tree construction: method may return a node
|
||
if r.class.ancestors.include? CyborgHood::CyborgServerInterfaceBase
|
||
if r.is_a? CyborgHood::CyborgServerInterfaceBase
|
||
r.api_nodes
|
||
else
|
||
r
|
||
end
|
||
end
|
||
end
|
||
next_node = self.send(next_node_name)
|
||
next_node = child_node(next_node_name, session)
|
||
else
|
||
# unknown method
|
||
return
|
||
... | ... | |
end
|
||
|
||
# search deeper
|
||
if next_node.class.ancestors.include? CyborgHood::CyborgServerInterfaceBase
|
||
next_node.find_node_action(other_nodes_names)
|
||
if next_node.is_a? CyborgHood::CyborgServerInterfaceBase
|
||
next_node.find_node_action(session, other_nodes_names)
|
||
else
|
||
# it is not a node, so there are no children
|
||
return
|
||
end
|
||
end
|
||
|
||
def child_node(next_node_name, session, *args)
|
||
args.unshift session if self.is_a? CyborgHood::CyborgServerStatefulInterface
|
||
self.send(next_node_name, *args)
|
||
end
|
||
|
||
def has_node?(cmd)
|
||
not find_node_action(cmd).nil?
|
||
not find_node_action(nil, cmd).nil?
|
||
end
|
||
|
||
# preliminary incoming message handling
|
||
def call(cmd, data)
|
||
action = find_node_action(cmd)
|
||
def call(session, cmd, data)
|
||
action = find_node_action(session, cmd)
|
||
return "551 unknown node" if action.nil?
|
||
|
||
if data.nil?
|
lib/cyborghood/cyborg/server.rb | ||
---|---|---|
@split_data_mode = false
|
||
@split_data_cmd = nil
|
||
@split_data = []
|
||
@session = Session.new
|
||
end
|
||
|
||
def send_line(msg)
|
||
... | ... | |
|
||
def receive_command(cmd, data = nil)
|
||
logger.debug "Executing command '#{cmd}' [#{identifier}]"
|
||
send_line @interface.call(cmd, data)
|
||
send_line @interface.call(@session, cmd, data)
|
||
end
|
||
|
||
def receive_error(msg)
|
||
... | ... | |
|
||
def unbind
|
||
logger.debug "Conversation finished with #{identifier}"
|
||
@session.clear
|
||
end
|
||
|
||
protected
|
||
... | ... | |
EmptyInterface.instance
|
||
end
|
||
end
|
||
|
||
class Session
|
||
attr_reader :store
|
||
|
||
def initialize
|
||
@store = Store.new
|
||
end
|
||
|
||
def clear
|
||
@store.values.each do |obj|
|
||
obj.__destroy if obj.respond_to? :__destroy
|
||
end
|
||
@store.clear
|
||
end
|
||
|
||
class Store < Hash
|
||
def get(key)
|
||
obj = self[key]
|
||
if obj.nil? and block_given?
|
||
obj = yield
|
||
self[key] = obj
|
||
end
|
||
obj
|
||
end
|
||
end
|
||
end
|
||
end
|
lib/cyborghood/services/dns.rb | ||
---|---|---|
@temp_file = nil
|
||
|
||
@filename = @config.dns.master_zone_pattern.gsub("#ZONE#", @zone)
|
||
|
||
at_exit {cleanup_temp}
|
||
end
|
||
|
||
def content
|
||
... | ... | |
raise CyberError.new(:unrecoverable, "services/dns", "zone activation failed") unless $?.success?
|
||
end
|
||
|
||
def __destroy
|
||
cleanup_temp
|
||
end
|
||
|
||
protected
|
||
|
||
def backup_filename
|
Also available in: Unified diff
[evol] added session management to the cyborg server (refs #31)