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.



619
620
621
# File 'lib/sfpagent/agent.rb', line 619

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


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
# File 'lib/sfpagent/agent.rb', line 773

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


634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
# File 'lib/sfpagent/agent.rb', line 634

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



690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
# File 'lib/sfpagent/agent.rb', line 690

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


718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
# File 'lib/sfpagent/agent.rb', line 718

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



924
925
926
927
928
929
930
931
# File 'lib/sfpagent/agent.rb', line 924

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



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

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



847
848
849
850
851
852
853
854
# File 'lib/sfpagent/agent.rb', line 847

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



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

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



872
873
874
875
876
877
878
879
880
# File 'lib/sfpagent/agent.rb', line 872

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



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

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



807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
# File 'lib/sfpagent/agent.rb', line 807

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



856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
# File 'lib/sfpagent/agent.rb', line 856

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



826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
# File 'lib/sfpagent/agent.rb', line 826

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



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

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



933
934
935
936
937
938
939
940
# File 'lib/sfpagent/agent.rb', line 933

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



942
943
944
945
946
947
948
949
950
951
952
953
# File 'lib/sfpagent/agent.rb', line 942

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



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

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



978
979
980
# File 'lib/sfpagent/agent.rb', line 978

def trusted(request)
	true
end