Module: Nuri::Choreographer

Includes:
Helper
Included in:
Master
Defined in:
lib/nuri/choreographer.rb

Constant Summary

Constants included from Helper

Helper::DefaultHTTPOpenTimeout, Helper::DefaultHTTPReadTimeout

Instance Method Summary collapse

Methods included from Helper

#delete_data, #get_data, #post_data, #put_data

Instance Method Details

#deploy_bsig(p = {}) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/nuri/choreographer.rb', line 51

def deploy_bsig(p={})
	fail "BSig model is not exist (parameter :bsig)!" if p[:bsig].nil?

	return false if not push_cache_model(p)

	return false if not clear_agents_list

	push_agents_list

	success = true
	p[:bsig].each do |name,bsig|
		address = @model.at?("$.#{name}.sfpAddress")
		port = @model.at?("$.#{name}.sfpPort")
		if !address.is_a?(String) or address.length <= 0 or !port.is_a?(Fixnum) or port <= 0
			puts (p[:color] ? "[Warn]".yellow : "[Warn]") + " Agent #{name} is not exist!"
			next
		end

		data = {'bsig' => JSON.generate(bsig)}
		code = nil
		begin
			code, _ = put_data(address, port, '/bsig', data)
		rescue
		end
		if code == '200'
			puts "Deploying BSig model to #{name}@#{address}:#{port} " + (p[:color] ? "[OK]".green : "[OK]")
		else
			$stderr.puts "Deploying BSig model to #{name}@#{address}:#{port} " + (p[:color] ? "[Failed]".red : "[Failed]")
			success = false
		end
	end
	success
end

#get_bsig(p = {}) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/nuri/choreographer.rb', line 6

def get_bsig(p={})
	def postprocess(bsig)
		# postprocessing BSig model by removing operator's condition/effect and BSig's goal that has value Sfp::Undefined
		bsig['operators'].each { |op|
			op['condition'].keys.each { |var| op['condition'].delete(var) if op['condition'][var].is_a?(Sfp::Undefined) }
			op['effect'].keys.each { |var| op['effect'].delete(var) if op['effect'][var].is_a?(Sfp::Undefined) }
		}
		bsig['goal'].keys.each { |var|
			if bsig['goal'][var].is_a?(Sfp::Undefined)
				bsig['goal'].delete(var)
				bsig['goal_operator'].delete(var)
			end
		}
	end

	# set parameters value to be given to the planner
	p[:sfp] = self.create_plan_task(p)
	p[:sas_post_processor] = @sas_post_processor
	p[:parallel] = true
	p[:bsig] = true

	bsig = local_bsigs = plan = nil
	choreographing_time = Benchmark.measure do
		# generate Global BSig model
		planner = Sfp::Planner.new
		bsig = planner.solve(p)

		postprocess(bsig)

		# generate local BSig model
		local_bsigs = {}
		self.get_agents.each do |name,model|
			namespace = model.ref + '.'
			local = {'id' => bsig['id'], 'operators' => [], 'goal' => {}}
			bsig['operators'].each { |op| local['operators'] << op if op['name'][0, namespace.length] == namespace }
			bsig['goal_operator'].each { |var,op_name| local['goal'][var] = bsig['goal'][var] if op_name[0, namespace.length] == namespace }
			local_bsigs[name] = local
		end
	end
	puts "Choreographing " + format_benchmark(choreographing_time)

	# bsig
	local_bsigs
end

#postprocess(bsig) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
# File 'lib/nuri/choreographer.rb', line 7

def postprocess(bsig)
	# postprocessing BSig model by removing operator's condition/effect and BSig's goal that has value Sfp::Undefined
	bsig['operators'].each { |op|
		op['condition'].keys.each { |var| op['condition'].delete(var) if op['condition'][var].is_a?(Sfp::Undefined) }
		op['effect'].keys.each { |var| op['effect'].delete(var) if op['effect'][var].is_a?(Sfp::Undefined) }
	}
	bsig['goal'].keys.each { |var|
		if bsig['goal'][var].is_a?(Sfp::Undefined)
			bsig['goal'].delete(var)
			bsig['goal_operator'].delete(var)
		end
	}
end

#purge_bsig(p = {}) ⇒ Object



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/nuri/choreographer.rb', line 123

def purge_bsig(p={})
	# update the model to populate VM's IP address
	self.get_state(p)

	# purge BSig model by requesting: HTTP PUT /bsig
	# but without parameter 'bsig' (empty data)
	success = true
	self.get_agents.each do |name,model|
		address = model['sfpAddress']
		port = model['sfpPort']
		next if !address.is_a?(String) or address.length <= 0 or !port.is_a?(Fixnum) or port <= 0

		code = nil
		begin			
			code1, _ = delete_data(address, port, '/bsig')
			code2, _ = delete_data(address, port, '/agents')
		rescue
		end
		if code1 == '200' and code2 == '200'
			puts "Purging BSig model: #{name}@#{address}:#{port} " + (p[:color] ? "[OK]".green : "[OK]")
		else
			$stderr.puts "Purging BSig model: #{name}@#{address}:#{port} " + (p[:color] ? "[Failed]".red : "[Failed]")
			success = false
		end
	end
	
	success		
end

#push_cache_model(p = {}) ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/nuri/choreographer.rb', line 85

def push_cache_model(p={})
	p[:bsig].each do |name,bsig|
		address = @model.at?("$.#{name}.sfpAddress")
		port = @model.at?("$.#{name}.sfpPort")
		next if !address.is_a?(String) or address.length <= 0 or !port.is_a?(Fixnum) or port <= 0

		bsig['operators'].each { |operator|	
			if operator['name'] =~ /^\$(\.[a-zA-Z0-9_]+)*\.create_vm/
				target_ref = operator['parameters']['$.vm']
				_, target_name, _ = target_ref.split('.', 3)

				data = { 'model' => Sfp::Helper.deep_clone(@model[target_name]),
				         'bsig' => p[:bsig][target_name] }
				data.accept(Sfp::Visitor::ParentEliminator.new)

				push_modules(@model[target_name], address, port)

				data = {'model' => JSON.generate(data)}
				code = nil
				begin
					code, _ = put_data(address, port, "/model/cache/#{target_name}", data)
				rescue
				end
				if code == '200'
					puts "Sending model of #{name} to #{address}:#{port} " + (p[:color] ? "[OK]".green : "[OK]")
				else
					$stderr.puts "Sending model of #{name} to #{address}:#{port} " + (p[:color] ? "[Failed]".red : "[Failed]")
					return false
				end
			end
		}

		return true
	end

	false
end