Class: Sfp::Agent::Handler

Inherits:
WEBrick::HTTPServlet::AbstractServlet
  • Object
show all
Defined in:
lib/sfpagent/agent.rb

Overview

 A class that handles HTTP request.

Instance Method Summary collapse

Constructor Details

#initialize(server, logger) ⇒ Handler

Returns a new instance of Handler.



661
662
663
# File 'lib/sfpagent/agent.rb', line 661

def initialize(server, logger)
	@logger = logger
end

Instance Method Details

#do_DELETE(request, response) ⇒ Object

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


815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
# File 'lib/sfpagent/agent.rb', line 815

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) ⇒ Object

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 /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


676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
# File 'lib/sfpagent/agent.rb', line 676

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 =~ /^\/sfp\/.+/
			status, content_type, body = get_sfp({:module => path[10, path.length-10]})

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

		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) ⇒ Object

 Handle HTTP Post request

uri: /execute => receive an action’s schema and execute it



732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
# File 'lib/sfpagent/agent.rb', line 732

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) ⇒ Object

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 to try to achieve it


760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
# File 'lib/sfpagent/agent.rb', line 760

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})

		end
	end

	response.status = status
	response['Content-Type'] = content_type
	response.body = body
end

#execute(p = {}) ⇒ Object



966
967
968
969
970
971
972
973
# File 'lib/sfpagent/agent.rb', line 966

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 = {}) ⇒ Object



997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
# File 'lib/sfpagent/agent.rb', line 997

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 = {}) ⇒ Object



889
890
891
892
893
894
895
896
# File 'lib/sfpagent/agent.rb', line 889

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_modelObject



952
953
954
955
956
957
958
959
960
961
962
963
964
# File 'lib/sfpagent/agent.rb', line 952

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 = {}) ⇒ Object



914
915
916
917
918
919
920
921
922
# File 'lib/sfpagent/agent.rb', line 914

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 = {}) ⇒ Object



924
925
926
927
928
929
930
931
932
933
934
935
936
937
# File 'lib/sfpagent/agent.rb', line 924

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 = {}) ⇒ Object



849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
# File 'lib/sfpagent/agent.rb', line 849

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 = {}) ⇒ Object



898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
# File 'lib/sfpagent/agent.rb', line 898

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 = {}) ⇒ Object



868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
# File 'lib/sfpagent/agent.rb', line 868

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 = {}) ⇒ Object



1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
# File 'lib/sfpagent/agent.rb', line 1009

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)

	[500, '', '']
end

#save_pidObject



975
976
977
978
979
980
981
982
# File 'lib/sfpagent/agent.rb', line 975

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 = {}) ⇒ Object



984
985
986
987
988
989
990
991
992
993
994
995
# File 'lib/sfpagent/agent.rb', line 984

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 = {}) ⇒ Object



939
940
941
942
943
944
945
946
947
948
949
950
# File 'lib/sfpagent/agent.rb', line 939

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) ⇒ Object



1020
1021
1022
# File 'lib/sfpagent/agent.rb', line 1020

def trusted(request)
	true
end