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.



672
673
674
# File 'lib/sfpagent/agent.rb', line 672

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


828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
# File 'lib/sfpagent/agent.rb', line 828

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


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
726
727
728
729
730
731
732
733
734
735
736
737
738
# File 'lib/sfpagent/agent.rb', line 687

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

 Handle HTTP POST request

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



745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
# File 'lib/sfpagent/agent.rb', line 745

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 in order to achieve it


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
802
803
804
805
806
807
808
809
810
811
812
813
814
# File 'lib/sfpagent/agent.rb', line 773

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



979
980
981
982
983
984
985
986
# File 'lib/sfpagent/agent.rb', line 979

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



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

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



902
903
904
905
906
907
908
909
# File 'lib/sfpagent/agent.rb', line 902

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



965
966
967
968
969
970
971
972
973
974
975
976
977
# File 'lib/sfpagent/agent.rb', line 965

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



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

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



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

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



862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
# File 'lib/sfpagent/agent.rb', line 862

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



911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
# File 'lib/sfpagent/agent.rb', line 911

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



881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
# File 'lib/sfpagent/agent.rb', line 881

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



1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
# File 'lib/sfpagent/agent.rb', line 1022

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



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

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



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

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



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

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



1033
1034
1035
# File 'lib/sfpagent/agent.rb', line 1033

def trusted(request)
	true
end