class Sfp::Agent::Handler

 A class that handles HTTP request.

Public Class Methods

new(server, logger) click to toggle source
# File lib/sfpagent/agent.rb, line 716
def initialize(server, logger)
        @logger = logger
end

Public Instance Methods

do_DELETE(request, response) click to toggle source

Handle HTTP DELETE request

uri:

/model            => delete existing model
/model/cache      => delete all cache models
/model/cache/name => delete cache model of agent "name"
/modules          => delete all modules from module database
/modules/name     => delete module "name" from module database
/agents           => delete all agents from agent database
/agents/name      => delete "name" from agent database
/bsig             => delete existing BSig model
# File lib/sfpagent/agent.rb, line 880
def do_DELETE(request, response)
        status = 400
        content_type = body = ''
        if not self.trusted(request)
                status = 403
        else
                path = (request.path[-1,1] == '/' ? ryyequest.path.chop : request.path)

                if path == '/model'
                        status, content_type, body = self.set_model

                elsif path == '/model/cache'
                        status, content_type, body = self.manage_cache_model({:delete => true, :name => :all})

                elsif path =~ /\/model\/cache\/.+/
                        status, content_type, body = self.manage_cache_model({:delete => true, :name => path[13, path.length-13]})

                elsif path == '/modules'
                        status, content_type, body = self.manage_modules({:uninstall => true, :name => :all})

                elsif path =~ /\/modules\/.+/
                        status, content_type, body = self.manage_modules({:uninstall => true, :name => path[9, path.length-9]})

                elsif path == '/agents'
                        status, content_type, body = self.manage_agents({:delete => true, :name => :all})

                elsif path == '/bsig'
                        status, content_type, body = self.set_bsig

                end

        end
end
do_GET(request, response) click to toggle source

Process HTTP GET request

uri:

/pid          => save daemon's PID to a file (only requested from localhost)
/state        => return the current state
/model        => return the current model
/model/cache  => return the cached model
/sfp          => return the SFP description of a module
/modules      => return a list of available modules
/agents       => return a list of agents database
/log          => return last 100 lines of log file
/bsig         => return BSig model
/bsig/flaws   => return flaws of BSig model
# File lib/sfpagent/agent.rb, line 734
def do_GET(request, response)
        status = 400
        content_type = body = ''
        if not trusted(request)
                status = 403
        else
                path = (request.path[-1,1] == '/' ? request.path.chop : request.path)
                if path == '/pid' and (request.peeraddr[2] == 'localhost' or request.peeraddr[3] == '127.0.0.1')
                        status, content_type, body = save_pid

                elsif path == '/state'
                        status, content_type, body = get_state

                elsif path == '/sfpstate'
                        status, content_type, body = get_state({:as_sfp => true})

                elsif path =~ /^\/state\/.+/
                        status, content_type, body = get_state({:path => path[7, path.length-7]})

                elsif path =~ /^\/sfpstate\/.+/
                        status, content_type, body = get_state({:path => path[10, path.length-10]})

                elsif path == '/model'
                        status, content_type, body = get_model

                elsif path =~ /\/model\/cache\/.+/
                        status, content_type, body = self.get_cache_model({:name => path[13, path.length-13]})

                elsif path == '/bsig'
                        status, content_type, body = get_bsig

                elsif path == '/bsig/flaws'
                        status = 200
                        content_type = 'application/json'
                        body = JSON.generate(Sfp::Agent.bsig_engine.get_flaws)

                elsif path =~ /^\/sfp\/.+/
                        status, content_type, body = get_sfp({:module => path[10, path.length-10]})

                elsif path == '/modules'
                        mods = {}
                        Sfp::Agent.get_modules.each { |name,data| mods[name] = data[:hash] }
                        status, content_type, body = [200, 'application/json', JSON.generate(mods)]

                elsif path == '/agents'
                        status, content_type, body = [200, 'application/JSON', JSON.generate(Sfp::Agent.get_agents)]

                elsif path == '/log'
                        status, content_type, body = [200, 'text/plain', Sfp::Agent.get_log(100)]

                end
        end

        response.status = status
        response['Content-Type'] = content_type
        response.body = body
end
do_POST(request, response) click to toggle source

 Handle HTTP POST request

uri:
   /execute => receive an action's schema and execute it
# File lib/sfpagent/agent.rb, line 797
def do_POST(request, response)
        status = 400
        content_type, body = ''
        if not self.trusted(request)
                status = 403
        else
                path = (request.path[-1,1] == '/' ? ryyequest.path.chop : request.path)
                if path == '/execute'
                        status, content_type, body = self.execute({:query => request.query})
                end
        end

        response.status = status
        response['Content-Type'] = content_type
        response.body = body
end
do_PUT(request, response) click to toggle source

Handle HTTP PUT request

uri:

/model          => receive a new model and then save it
/model/cache    => receive a "cache" model and then save it
/modules        => save the module if parameter "module" is provided
/agents         => save the agents' list if parameter "agents" is provided
/bsig           => receive BSig model and receive it in cached directory
/bsig/satisfier => receive goal request from other agents and then start
                   a satisfier thread in order to achieve it
# File lib/sfpagent/agent.rb, line 825
def do_PUT(request, response)
        status = 400
        content_type = body = ''
        if not self.trusted(request)
                status = 403
        else
                path = (request.path[-1,1] == '/' ? ryyequest.path.chop : request.path)

                if path == '/model' and request.query.has_key?('model')
                        status, content_type, body = self.set_model({:model => request.query['model']})

                elsif path =~ /\/model\/cache\/.+/ and request.query.length > 0
                        status, content_type, body = self.manage_cache_model({:set => true,
                                                                              :name => path[13, path.length-13],
                                                                              :model => request.query['model']})

                elsif path =~ /\/modules\/.+/ and request.query.length > 0
                        status, content_type, body = self.manage_modules({:install => true,
                                                                          :name => path[9, path.length-9],
                                                                          :module => request.query['module']})

                elsif path == '/modules' and request.query.length > 0
                        status, content_type, body = self.manage_modules({:install => true,
                                                                          :modules => request.query})

                elsif path == '/agents' and request.query.has_key?('agents')
                        status, content_type, body = self.manage_agents({:set => true,
                                                                         :agents => request.query['agents']})

                elsif path == '/bsig' and request.query.has_key?('bsig')
                        status, content_type, body = self.set_bsig({:query => request.query})

                elsif path == '/bsig/satisfier'
                        status, content_type, body = self.satisfy_bsig_request({:query => request.query, :client => request.remote_ip})

                end
        end

        response.status = status
        response['Content-Type'] = content_type
        response.body = body
end
execute(p={}) click to toggle source
# File lib/sfpagent/agent.rb, line 1031
def execute(p={})
        return [400, '', ''] if not (p[:query] and p[:query].has_key?('action'))
        begin
                return [200, '', ''] if Sfp::Agent.execute_action(JSON[p[:query]['action']])
        rescue
        end
        [500, '', '']
end
get_bsig(p={}) click to toggle source
# File lib/sfpagent/agent.rb, line 1062
def get_bsig(p={})
        bsig = Sfp::Agent.get_bsig

        # The BSig model is not exist
        return [404, '', ''] if bsig.nil?

        # The BSig model is exist, and then send it in JSON
        return [200, 'application/json', JSON.generate(bsig)] if !!bsig

        [500, '', '']
end
get_cache_model(p={}) click to toggle source
# File lib/sfpagent/agent.rb, line 954
def get_cache_model(p={})
        model = Sfp::Agent.get_cache_model(p[:name])
        if model
                [200, 'application/json', JSON.generate(model)]
        else
                [404, '', '']
        end
end
get_model() click to toggle source
# File lib/sfpagent/agent.rb, line 1017
def get_model
        # The model is not exist.
        return [404, '', ''] if not File.exist?(Sfp::Agent::ModelFile)

        begin
                # The model is exist, and then send it in JSON.
                return [200, 'application/json', File.read(Sfp::Agent::ModelFile)]
        rescue
        end

        # There is an error when retrieving the model!
        [500, '', '']
end
get_sfp(p={}) click to toggle source
# File lib/sfpagent/agent.rb, line 979
def get_sfp(p={})
        begin
                module_name, _ = p[:module].split('/', 2)
                return [200, 'application/json', Sfp::Agent.get_sfp(module_name)]
        rescue Exception => e
                @logger.error "Sending schemata [Failed]\n#{e}"
        end
        [500, '', '']
end
get_state(p={}) click to toggle source
# File lib/sfpagent/agent.rb, line 989
def get_state(p={})
        state = Sfp::Agent.get_state(!!p[:as_sfp])

        # The model is not exist.
        return [404, 'text/plain', 'There is no model!'] if state.nil?

        if !!state
                state = state.at?("$." + p[:path].gsub(/\//, '.')) if !!p[:path]
                return [200, 'application/json', JSON.generate({'state'=>state})]
        end

        # There is an error when retrieving the state of the model!
        [500, '', '']
end
manage_agents(p={}) click to toggle source
# File lib/sfpagent/agent.rb, line 914
def manage_agents(p={})
        begin
                if p[:delete]
                        if p[:name] == :all
                                return [200, '', ''] if Sfp::Agent.delete_agents
                        elsif p[:name] != ''
                                return [200, '', ''] if Sfp::Agent.set_agents({p[:name] => nil})
                        else
                                return [400, '', '']
                        end
                elsif p[:set]
                        return [200, '', ''] if Sfp::Agent.set_agents(JSON[p[:agents]])
                end
        rescue Exception => e
                @logger.error "Saving agents list [Failed]\n#{e}\n#{e.backtrace.join("\n")}"
        end
        [500, '', '']
end
manage_cache_model(p={}) click to toggle source
# File lib/sfpagent/agent.rb, line 963
def manage_cache_model(p={})
        if p[:set] and p[:name] and p[:model]
                p[:model] = JSON[p[:model]]
                return [200, '', ''] if Sfp::Agent.set_cache_model(p)
        elsif p[:delete] and p[:name]
                if p[:name] == :all
                        return [200, '', ''] if Sfp::Agent.set_cache_model
                else
                        return [200, '', ''] if Sfp::Agent.set_cache_model({:name => p[:name]})
                end
        else
                return [400, '', '']
        end
        [500, '', '']
end
manage_modules(p={}) click to toggle source
# File lib/sfpagent/agent.rb, line 933
def manage_modules(p={})
        if p[:install]
                if p[:name] and p[:module]
                        return [200, '', ''] if Sfp::Agent.install_module(p[:name], p[:module])
                elsif p[:modules]
                        return [200, '', ''] if Sfp::Agent.install_modules(p[:modules])
                else
                        return [400, '', '']
                end
        elsif p[:uninstall]
                if p[:name] == :all
                        return [200, '', ''] if Sfp::Agent.uninstall_all_modules
                elsif p[:name] != ''
                        return [200, '', ''] if Sfp::Agent.uninstall_module(p[:name])
                else
                        return [400, '', '']
                end
        end
        [500, '', '']
end
satisfy_bsig_request(p={}) click to toggle source
# File lib/sfpagent/agent.rb, line 1074
def satisfy_bsig_request(p={})
        return [400, '', ''] if not p[:query]

        return [500, '', ''] if Sfp::Agent.bsig_engine.nil?

        req = p[:query]
        return [200, '', ''] if Sfp::Agent.bsig_engine.receive_goal_from_agent(req['id'].to_i, JSON[req['goal']], req['pi'].to_i, p[:client])

        [500, '', '']
end
save_pid() click to toggle source
# File lib/sfpagent/agent.rb, line 1040
def save_pid
        begin
                File.open(PIDFile, 'w', 0644) { |f| f.write($$.to_s) }
                return [200, '', $$.to_s]
        rescue Exception
        end
        [500, '', '']
end
set_bsig(p={}) click to toggle source
# File lib/sfpagent/agent.rb, line 1049
def set_bsig(p={})
        if p[:query] and p[:query].has_key?('bsig')
                # If setting the BSig model was success, then return '200' status
                return [200, '', ''] if Sfp::Agent.set_bsig(JSON[p[:query]['bsig']])
        else
                # Deleting the existing BSig model by setting with Nil, if it's success then return '200' status.
                return [200, '', ''] if Sfp::Agent.set_bsig(nil)
        end

        # There is an error on setting/deleting the BSig model
        [500, '', '']
end
set_model(p={}) click to toggle source
# File lib/sfpagent/agent.rb, line 1004
def set_model(p={})
        if p[:model]
                # If setting the model was success, then return '200' status.
                return [200, '', ''] if Sfp::Agent.set_model(JSON[p[:model]])
        else
                # Removing the existing model by setting an empty model, if it's success then return '200' status.
                return [200, '', ''] if Sfp::Agent.set_model({})
        end

        # There is an error on setting the model!
        [500, '', '']
end
trusted(request) click to toggle source
# File lib/sfpagent/agent.rb, line 1085
def trusted(request)
        true
end