haredo 0.0.5 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +355 -16
- data/src/bin/haredo +115 -0
- data/src/lib/haredo/admin/config.rb +178 -0
- data/src/lib/haredo/admin/interface.rb +25 -0
- data/src/lib/haredo/config.rb +54 -0
- data/src/lib/haredo/peer.rb +210 -110
- data/src/lib/haredo/plugin.rb +19 -0
- data/src/lib/haredo/plugins/echo.rb +15 -0
- data/src/lib/haredo/plugins/example.rb +17 -0
- data/src/lib/haredo/plugins/status.rb +31 -0
- data/src/lib/haredo/service/admin/daemon.rb +128 -0
- data/src/lib/haredo/service/config.rb +29 -0
- data/src/lib/haredo/service/daemon.rb +141 -0
- data/src/lib/haredo/version.rb +7 -1
- metadata +19 -6
data/src/bin/haredo
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require 'haredo/version'
|
5
|
+
require 'haredo/admin/config'
|
6
|
+
require 'haredo/service/admin/daemon'
|
7
|
+
require 'haredo/service/daemon'
|
8
|
+
|
9
|
+
$config_dir = '/etc/haredo/config.yaml'
|
10
|
+
|
11
|
+
class CommandLine
|
12
|
+
|
13
|
+
def initialize()
|
14
|
+
@commands = {}
|
15
|
+
|
16
|
+
# Default is global service
|
17
|
+
@service = 'haredo'
|
18
|
+
end
|
19
|
+
|
20
|
+
def load(interface)
|
21
|
+
@commands[interface.name] = interface
|
22
|
+
end
|
23
|
+
|
24
|
+
def daemonize()
|
25
|
+
|
26
|
+
daemon = HareDo::Service::Daemon::new(@service)
|
27
|
+
daemon.run()
|
28
|
+
|
29
|
+
daemon.shutdown()
|
30
|
+
|
31
|
+
puts 'Daemon exiting'
|
32
|
+
end
|
33
|
+
|
34
|
+
def parse()
|
35
|
+
@daemonize = false
|
36
|
+
|
37
|
+
opts = OptionParser.new do |opts|
|
38
|
+
opts.banner = "HareDo #{HareDo::VERSION} (#{HareDo::RELEASE_DATE})\n\n"
|
39
|
+
opts.separator "Usage: haredo <global options> <command> <command_options>\n\n"
|
40
|
+
|
41
|
+
opts.separator 'Global options:'
|
42
|
+
|
43
|
+
opts.on('-c', '--config [val]', String, 'Use specific config file (default /etc/haredo/system.yml)') do |file|
|
44
|
+
@configfile = file
|
45
|
+
end
|
46
|
+
|
47
|
+
opts.on('-d', '--daemonize', String, 'Run in daemon mode') do
|
48
|
+
@daemonize = true
|
49
|
+
end
|
50
|
+
|
51
|
+
opts.on('-s', '--service [val]', String, 'Service to run') do |service|
|
52
|
+
@service = service
|
53
|
+
end
|
54
|
+
|
55
|
+
opts.on_tail("-h", "--help", "Display help") do
|
56
|
+
puts opts
|
57
|
+
puts
|
58
|
+
printHelp()
|
59
|
+
|
60
|
+
exit
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
opts.parse!(ARGV)
|
65
|
+
|
66
|
+
daemonize() if @daemonize == true
|
67
|
+
end
|
68
|
+
|
69
|
+
def printHelp()
|
70
|
+
|
71
|
+
puts "Available commands:\n"
|
72
|
+
|
73
|
+
@commands.keys.sort.each do |key|
|
74
|
+
desc = @commands[key].description
|
75
|
+
puts " %-10s %-25s " % [key, desc]
|
76
|
+
end
|
77
|
+
|
78
|
+
puts
|
79
|
+
puts "For a specific command's options, type: haredo <command> -h "
|
80
|
+
puts
|
81
|
+
end
|
82
|
+
|
83
|
+
def run()
|
84
|
+
command = ARGV[0]
|
85
|
+
|
86
|
+
if @commands.has_key?(command)
|
87
|
+
remaining = @commands[command].parse(ARGV[1..-1])
|
88
|
+
else
|
89
|
+
|
90
|
+
# HAAAAAAAAAAACK. These are shortcuts in case user forgets to type 'daemon
|
91
|
+
# start' or 'daemon {command}'
|
92
|
+
|
93
|
+
if command == 'start'
|
94
|
+
@commands['daemon'].parse(ARGV[0..-1])
|
95
|
+
end
|
96
|
+
|
97
|
+
if command == 'stop'
|
98
|
+
@commands['daemon'].parse(ARGV[0..-1])
|
99
|
+
end
|
100
|
+
|
101
|
+
if command == 'status'
|
102
|
+
@commands['daemon'].parse(ARGV[0..-1])
|
103
|
+
end
|
104
|
+
|
105
|
+
if parse() == false
|
106
|
+
printHelp()
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
program = CommandLine.new()
|
113
|
+
program.load(HareDo::Admin::Config::Interface.new())
|
114
|
+
program.load(HareDo::Admin::Daemon::Interface.new())
|
115
|
+
program.run()
|
@@ -0,0 +1,178 @@
|
|
1
|
+
require 'haredo/admin/interface'
|
2
|
+
|
3
|
+
module HareDo
|
4
|
+
module Admin
|
5
|
+
module Config
|
6
|
+
|
7
|
+
# The class implements to command line interface for configuration module
|
8
|
+
class Interface < Admin::Interface
|
9
|
+
|
10
|
+
def initialize()
|
11
|
+
super('config', 'Modify configuration')
|
12
|
+
|
13
|
+
@commands = {}
|
14
|
+
|
15
|
+
# Configure/test database connection settings
|
16
|
+
@commands['db'] = lambda do | name |
|
17
|
+
|
18
|
+
# Write changes to configuration file
|
19
|
+
if @write == true
|
20
|
+
|
21
|
+
loadConfig()
|
22
|
+
|
23
|
+
settings = {}
|
24
|
+
password = ENV['PGPASSWORD']
|
25
|
+
|
26
|
+
settings['host'] = @host if @host
|
27
|
+
settings['user'] = @username if @username
|
28
|
+
settings['password'] = password if password
|
29
|
+
settings['port'] = @port if @port
|
30
|
+
settings['name'] = @vhost if @vhost
|
31
|
+
settings['ssl'] = true if @ssl
|
32
|
+
|
33
|
+
@config['system']['db'] = settings
|
34
|
+
|
35
|
+
saveConfig()
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
# Configure/test RabbitMQ connection settings
|
41
|
+
@commands['broker'] = lambda do | name |
|
42
|
+
|
43
|
+
if @test == true
|
44
|
+
connected = false
|
45
|
+
params = {
|
46
|
+
:user => @username,
|
47
|
+
:password => ENV['RBQPASSWORD'],
|
48
|
+
:port => @port,
|
49
|
+
:vhost => @vhost,
|
50
|
+
:host => @host,
|
51
|
+
:ssl => @ssl
|
52
|
+
}
|
53
|
+
|
54
|
+
puts params
|
55
|
+
|
56
|
+
client = HareDo::Peer.new()
|
57
|
+
|
58
|
+
begin
|
59
|
+
connected = client.connect(params)
|
60
|
+
rescue
|
61
|
+
exit 1
|
62
|
+
end
|
63
|
+
|
64
|
+
if connected == true
|
65
|
+
puts 'succeeded'
|
66
|
+
client.disconnect()
|
67
|
+
exit 0
|
68
|
+
end
|
69
|
+
|
70
|
+
puts 'failed'
|
71
|
+
exit 1
|
72
|
+
end
|
73
|
+
|
74
|
+
if @write == true
|
75
|
+
# Write changes to configuration file
|
76
|
+
|
77
|
+
loadConfig()
|
78
|
+
|
79
|
+
settings = {}
|
80
|
+
password = ENV['RBQPASSWORD']
|
81
|
+
|
82
|
+
settings['host'] = @host if @host
|
83
|
+
settings['user'] = @username if @username
|
84
|
+
settings['password'] = password if password
|
85
|
+
settings['port'] = @port if @port
|
86
|
+
settings['vhost'] = @vhost if @vhost
|
87
|
+
settings['ssl'] = true if @ssl
|
88
|
+
|
89
|
+
@config['system']['broker'] = settings
|
90
|
+
|
91
|
+
saveConfig()
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def help(opts)
|
97
|
+
puts opts
|
98
|
+
end
|
99
|
+
|
100
|
+
def parse(args)
|
101
|
+
$dir = nil
|
102
|
+
$count = 1
|
103
|
+
|
104
|
+
@ssl = false
|
105
|
+
|
106
|
+
opts = OptionParser.new do |opts|
|
107
|
+
opts.separator ''
|
108
|
+
opts.banner = "Test/update configuration and connection settings\n\n"
|
109
|
+
opts.banner += "Usage: config [options] {db | broker}"
|
110
|
+
|
111
|
+
opts.separator 'Available options:'
|
112
|
+
|
113
|
+
opts.on('-c', '--config [val]', String, 'Use specific config file (default /etc/haredo/system.yml)') do |file|
|
114
|
+
@configfile = file
|
115
|
+
$count += 1
|
116
|
+
end
|
117
|
+
|
118
|
+
opts.on_tail("-t", "--test", "Test connection settings") do
|
119
|
+
@test = true
|
120
|
+
end
|
121
|
+
|
122
|
+
opts.on_tail("-h", "--help", "Display help") do
|
123
|
+
puts opts
|
124
|
+
exit
|
125
|
+
end
|
126
|
+
|
127
|
+
opts.on_tail("-u", "--user [val]", String, "Username to use for connection") do |user|
|
128
|
+
@username = user
|
129
|
+
$count += 1
|
130
|
+
end
|
131
|
+
|
132
|
+
opts.on_tail("-s", "--server-host [val]", String, "Host") do |host|
|
133
|
+
@host = host
|
134
|
+
$count += 1
|
135
|
+
end
|
136
|
+
|
137
|
+
opts.on_tail("-e", "--encryption [val]", String, "Host to use for connection") do |ssl|
|
138
|
+
if ssl == 'true'
|
139
|
+
@ssl = true
|
140
|
+
end
|
141
|
+
|
142
|
+
$count += 1
|
143
|
+
end
|
144
|
+
|
145
|
+
opts.on_tail("-n", "--name [val]", String, "Name (Database name of RabbitMQ VHost)") do |name|
|
146
|
+
@vhost = name
|
147
|
+
$count += 1
|
148
|
+
end
|
149
|
+
|
150
|
+
opts.on_tail("-p", "--port [val]", String, "Port to use for connection)") do |port|
|
151
|
+
@port = port
|
152
|
+
$count += 1
|
153
|
+
end
|
154
|
+
|
155
|
+
opts.on_tail("-w", "--write-changed", "Write account setting to configuration file") do
|
156
|
+
@write = true
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|
160
|
+
|
161
|
+
opts.parse!(args[0..-1])
|
162
|
+
|
163
|
+
command = args[0].chomp
|
164
|
+
|
165
|
+
if not @commands.has_key?(command)
|
166
|
+
help opts
|
167
|
+
|
168
|
+
return
|
169
|
+
end
|
170
|
+
|
171
|
+
@commands[command].call(command)
|
172
|
+
end
|
173
|
+
|
174
|
+
end # class
|
175
|
+
|
176
|
+
end # module Daemon
|
177
|
+
end # module Admin
|
178
|
+
end # module HareDo
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'haredo/peer'
|
2
|
+
require 'haredo/config'
|
3
|
+
|
4
|
+
module HareDo
|
5
|
+
module Admin
|
6
|
+
|
7
|
+
class Interface
|
8
|
+
|
9
|
+
attr_reader :name, :description
|
10
|
+
|
11
|
+
include HareDo::Config
|
12
|
+
|
13
|
+
def initialize(name, desc)
|
14
|
+
@name = name
|
15
|
+
@description = desc
|
16
|
+
end
|
17
|
+
|
18
|
+
def parse(args)
|
19
|
+
# Derived class implements
|
20
|
+
end
|
21
|
+
|
22
|
+
end # class Interface
|
23
|
+
|
24
|
+
end # module Admin
|
25
|
+
end # module HareDo
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'haredo/peer'
|
3
|
+
|
4
|
+
class Time
|
5
|
+
def isoDate()
|
6
|
+
return self.strftime("%Y-%m-%d %H:%M:%S")
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
module HareDo
|
11
|
+
module Config
|
12
|
+
|
13
|
+
def loadConfig()
|
14
|
+
@config_file = '/etc/haredo/haredo.conf'
|
15
|
+
@config = []
|
16
|
+
@config = YAML.load_file(@config_file)
|
17
|
+
@pid_file = '/var/run/haredo.pid'
|
18
|
+
end
|
19
|
+
|
20
|
+
def saveConfig()
|
21
|
+
file = File.open(@config_file, 'w')
|
22
|
+
file.write(YAML::dump(@config))
|
23
|
+
file.close()
|
24
|
+
end
|
25
|
+
|
26
|
+
# Connect to the RabbitMQ broker
|
27
|
+
#
|
28
|
+
# @return Return a client instance if connection was successful, nil otherwise
|
29
|
+
def connectBroker()
|
30
|
+
|
31
|
+
account = @config['system']['broker']
|
32
|
+
|
33
|
+
params = {
|
34
|
+
:user => account['user'],
|
35
|
+
:password => account['password'],
|
36
|
+
:host => account['host'],
|
37
|
+
:port => account['port'],
|
38
|
+
:vhost => account['vhost'],
|
39
|
+
:ssl => account['ssl']
|
40
|
+
}
|
41
|
+
|
42
|
+
peer = HareDo::Peer.new()
|
43
|
+
|
44
|
+
begin
|
45
|
+
connected = peer.connect(params)
|
46
|
+
rescue
|
47
|
+
return nil
|
48
|
+
end
|
49
|
+
|
50
|
+
return peer
|
51
|
+
end
|
52
|
+
|
53
|
+
end # module Config
|
54
|
+
end # module HareDo
|
data/src/lib/haredo/peer.rb
CHANGED
@@ -1,7 +1,20 @@
|
|
1
|
-
require
|
1
|
+
require 'syslog'
|
2
|
+
require 'bunny'
|
2
3
|
require 'haredo/version'
|
3
4
|
|
4
|
-
|
5
|
+
def dump_message(msg)
|
6
|
+
if msg.properties != nil
|
7
|
+
puts ' Headers:'
|
8
|
+
msg.properties.each do |k,v|
|
9
|
+
puts " #{k}: #{v}"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
puts " Data: #{msg.data}"
|
14
|
+
puts
|
15
|
+
end
|
16
|
+
|
17
|
+
module RabbitMQ
|
5
18
|
|
6
19
|
# This is a simple class that represents a message delivered from a queue. The
|
7
20
|
# attributes are as follows:
|
@@ -13,7 +26,7 @@ module HareDo
|
|
13
26
|
|
14
27
|
class Message
|
15
28
|
|
16
|
-
|
29
|
+
attr_accessor :info, :properties, :headers, :data
|
17
30
|
|
18
31
|
def initialize(info=nil, properties=nil, data=nil)
|
19
32
|
@info = info
|
@@ -30,14 +43,137 @@ class Message
|
|
30
43
|
|
31
44
|
end
|
32
45
|
|
33
|
-
#
|
46
|
+
end # module RabbitMQ
|
34
47
|
|
35
|
-
|
48
|
+
module HareDo
|
49
|
+
|
50
|
+
#-------------------------------------------------------------------------------
|
51
|
+
# For managing plugins
|
52
|
+
#-------------------------------------------------------------------------------
|
53
|
+
|
54
|
+
module Plugins
|
36
55
|
|
37
|
-
|
56
|
+
class Instance
|
38
57
|
|
39
|
-
def initialize()
|
58
|
+
def initialize(path)
|
59
|
+
|
60
|
+
# 1. Create an empty, anonymous module
|
61
|
+
@module = Module.new()
|
62
|
+
|
63
|
+
# 2. Get it's binding
|
64
|
+
@binding = @module.instance_eval 'binding'
|
40
65
|
|
66
|
+
# 3. Eval the desired file with the module's binding as
|
67
|
+
# context. Everything global in the module will be restricted to the
|
68
|
+
# module's namespace.
|
69
|
+
Kernel::eval(File.open(path).read(), @binding, path)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Return a top-level object within the module
|
73
|
+
def get(object)
|
74
|
+
return @module.instance_eval object
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# This class loads Ruby files/modules into private namespaces. That is, they are
|
79
|
+
# not globally visible.
|
80
|
+
#
|
81
|
+
# Example:
|
82
|
+
#
|
83
|
+
# instance = Plugins::Manager.load("#{@path}/plugin")
|
84
|
+
# mod = instance.get('Sonar')
|
85
|
+
# plugin = mod::Plugin.new(@config)
|
86
|
+
#
|
87
|
+
# plugins[plugin.uuid] = plugin
|
88
|
+
|
89
|
+
class Manager
|
90
|
+
|
91
|
+
attr_reader :loaded
|
92
|
+
attr_accessor :module_path_prefix
|
93
|
+
|
94
|
+
def initialize(peer)
|
95
|
+
@peer = peer
|
96
|
+
@loaded = {}
|
97
|
+
@config = {}
|
98
|
+
|
99
|
+
@module_path_prefix = 'haredo/plugins'
|
100
|
+
end
|
101
|
+
|
102
|
+
def [](name)
|
103
|
+
return @loaded[name]
|
104
|
+
end
|
105
|
+
|
106
|
+
def loadConfig(config)
|
107
|
+
@config.merge! config
|
108
|
+
|
109
|
+
config.each do |plugin_name, value|
|
110
|
+
load(plugin_name)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def load(plugin_name, base=@module_path_prefix)
|
115
|
+
|
116
|
+
# Iterate through the RUBY_PATH looking for a match
|
117
|
+
$:.each do |dir|
|
118
|
+
path = "#{dir}/#{base}/#{plugin_name}.rb"
|
119
|
+
if File.exists? path
|
120
|
+
instance = Instance.new(path)
|
121
|
+
cls = instance.get('Plugin')
|
122
|
+
plugin = cls.new(@peer, @config[cls::UUID])
|
123
|
+
@loaded[plugin.uuid] = plugin
|
124
|
+
$stderr.puts "Loaded plugin #{path}"
|
125
|
+
|
126
|
+
return
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# Process a message. Looks up module by given by UUID in headers. If found,
|
132
|
+
# passes message off to it.
|
133
|
+
def process(msg)
|
134
|
+
uuid = msg.headers['uuid']
|
135
|
+
|
136
|
+
if @loaded.has_key?(uuid)
|
137
|
+
@loaded[uuid].process(msg)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def shutdown()
|
142
|
+
@loaded.each do|uuid, plugin|
|
143
|
+
plugin.finalize()
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
end # class Manager
|
148
|
+
|
149
|
+
end # module Plugins
|
150
|
+
|
151
|
+
# This is an abstract base class used for both Client and Service.
|
152
|
+
|
153
|
+
class Peer
|
154
|
+
|
155
|
+
attr_reader :queue, :plugins
|
156
|
+
attr_accessor :timeout, :sleep_interval
|
157
|
+
|
158
|
+
def initialize(name=nil)
|
159
|
+
# Message identifier
|
160
|
+
@mid = 0
|
161
|
+
|
162
|
+
# Client attributes
|
163
|
+
@timeout = 1.0
|
164
|
+
@sleep_interval = 0.001
|
165
|
+
@receive_queue = {}
|
166
|
+
|
167
|
+
# Server attributes
|
168
|
+
# The queue name used for listen()
|
169
|
+
@queue_name = name
|
170
|
+
|
171
|
+
@listen_queues = []
|
172
|
+
|
173
|
+
# The number of messages to prefecth from Rabbit
|
174
|
+
@prefetch = 10
|
175
|
+
|
176
|
+
@plugins = Plugins::Manager.new(self)
|
41
177
|
end
|
42
178
|
|
43
179
|
# Connect to RabbitMQ
|
@@ -72,82 +208,38 @@ class Node
|
|
72
208
|
|
73
209
|
@channel = @cnx.create_channel()
|
74
210
|
|
211
|
+
@queue = @channel.queue( '', :auto_delete => true,
|
212
|
+
:arguments => { "x-message-ttl" => 1000 } )
|
213
|
+
|
214
|
+
@exchange = @channel.default_exchange()
|
215
|
+
|
75
216
|
return true
|
76
217
|
end
|
77
218
|
|
78
219
|
# Disconnect from RabbitMQ
|
79
220
|
def disconnect()
|
80
|
-
@cnx.close()
|
81
|
-
end
|
82
221
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
# @param :headers Message headers
|
87
|
-
# @param :headers Message from address
|
88
|
-
# @param :properties Message properties
|
89
|
-
|
90
|
-
def send(to, args)
|
91
|
-
|
92
|
-
data = args[:data] || ''
|
93
|
-
from = args[:from]
|
94
|
-
headers = args[:headers] || {}
|
95
|
-
properties = args[:properties] || {}
|
96
|
-
|
97
|
-
properties[:routing_key] = to
|
98
|
-
properties[:headers] = headers
|
99
|
-
|
100
|
-
if not from.nil?
|
101
|
-
properties[:reply_to] = from
|
102
|
-
else
|
103
|
-
properties[:reply_to] = @queue.name if @queue
|
222
|
+
if @queue != nil
|
223
|
+
@queue.delete()
|
224
|
+
@queue = nil
|
104
225
|
end
|
105
226
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
end
|
110
|
-
|
111
|
-
end # class Node
|
112
|
-
|
113
|
-
# Implements a basic client designed for sending messages asynchronously and
|
114
|
-
# blocking while receiving replies.
|
115
|
-
|
116
|
-
class Client < Node
|
117
|
-
|
118
|
-
attr_reader :queue
|
119
|
-
attr_accessor :timeout, :sleep_interval
|
120
|
-
|
121
|
-
def initialize()
|
122
|
-
super
|
123
|
-
|
124
|
-
@timeout = 1.0
|
125
|
-
@sleep_interval = 0.001
|
126
|
-
@receive_queue = {}
|
127
|
-
|
128
|
-
# Message identifier
|
129
|
-
@mid = 0
|
130
|
-
end
|
131
|
-
|
132
|
-
def connect(args)
|
133
|
-
ret = super
|
134
|
-
|
135
|
-
if ret == true
|
136
|
-
@queue = @channel.queue( '', :auto_delete => true,
|
137
|
-
:arguments => { "x-message-ttl" => 1000 } )
|
138
|
-
|
139
|
-
@exchange = @channel.default_exchange()
|
227
|
+
@listen_queues.each do |listen_queue|
|
228
|
+
listen_queue.delete()
|
229
|
+
listen_queue = nil
|
140
230
|
end
|
231
|
+
|
232
|
+
@listen_queues = {}
|
141
233
|
|
142
|
-
|
143
|
-
|
234
|
+
if @cnx != nil
|
235
|
+
@cnx.close()
|
236
|
+
@cnx = nil
|
237
|
+
end
|
144
238
|
|
145
|
-
|
146
|
-
def disconnect()
|
147
|
-
@queue.delete() if @queue
|
148
|
-
super
|
239
|
+
@plugins.shutdown()
|
149
240
|
end
|
150
241
|
|
242
|
+
# Sends a message.
|
151
243
|
# Sends a message. Adds the @mid as message_id in message properties.
|
152
244
|
# @param to The to address
|
153
245
|
# @param :data Message data
|
@@ -164,13 +256,21 @@ class Client < Node
|
|
164
256
|
headers = args[:headers] || {}
|
165
257
|
properties = args[:properties] || {}
|
166
258
|
|
167
|
-
properties[:
|
168
|
-
|
169
|
-
|
259
|
+
properties[:routing_key] = to
|
260
|
+
properties[:headers] = headers
|
261
|
+
properties[:message_id] = @mid
|
170
262
|
|
171
263
|
rc = @mid
|
172
264
|
@mid += 1
|
173
265
|
|
266
|
+
if not from.nil?
|
267
|
+
properties[:reply_to] = from
|
268
|
+
else
|
269
|
+
properties[:reply_to] = @queue.name if @queue
|
270
|
+
end
|
271
|
+
|
272
|
+
@exchange.publish(data, properties)
|
273
|
+
|
174
274
|
return rc
|
175
275
|
end
|
176
276
|
|
@@ -216,7 +316,7 @@ class Client < Node
|
|
216
316
|
delivery_info, properties, payload = @queue.pop()
|
217
317
|
|
218
318
|
if delivery_info != nil
|
219
|
-
msg = Message.new(delivery_info, properties, payload)
|
319
|
+
msg = RabbitMQ::Message.new(delivery_info, properties, payload)
|
220
320
|
|
221
321
|
if msg.headers.has_key?('id')
|
222
322
|
if mid != nil
|
@@ -246,20 +346,24 @@ class Client < Node
|
|
246
346
|
end
|
247
347
|
end
|
248
348
|
|
249
|
-
|
250
|
-
|
251
|
-
#
|
252
|
-
|
253
|
-
|
349
|
+
# You should use this method to reply back to a peer. It sets the reply header
|
350
|
+
# which tells the remote that this message is a response (as opposed to a
|
351
|
+
# message originating from another source which just happens to have the same
|
352
|
+
# message_id).
|
353
|
+
def reply(msg, args)
|
254
354
|
|
255
|
-
|
256
|
-
|
257
|
-
super()
|
355
|
+
data = args[:data] || ''
|
356
|
+
headers = args[:headers] || {}
|
258
357
|
|
259
|
-
|
358
|
+
id = msg.properties.message_id.to_i
|
359
|
+
to = msg.properties.reply_to
|
260
360
|
|
261
|
-
#
|
262
|
-
|
361
|
+
# Set the reply flag to indicate that this is a response to a message
|
362
|
+
# sent. The message_id should already be set in the headers.
|
363
|
+
headers[:reply] = 1
|
364
|
+
headers[:id] = id.to_i
|
365
|
+
|
366
|
+
send(to, :headers => headers, :data => data)
|
263
367
|
end
|
264
368
|
|
265
369
|
# Defined the queue this service will listen on. Assumes a single-instance
|
@@ -275,40 +379,36 @@ class Service < Node
|
|
275
379
|
|
276
380
|
# @returns Returns nil if non-blocking. Never returns if blocking.
|
277
381
|
|
278
|
-
def
|
279
|
-
|
382
|
+
def listen(args)
|
383
|
+
listen_queue = createQueue()
|
384
|
+
|
385
|
+
@listen_queues << listen_queue
|
386
|
+
|
280
387
|
@exchange = @channel.default_exchange()
|
281
388
|
|
282
389
|
block = args[:blocking] || false
|
283
390
|
|
284
391
|
@channel.prefetch(@prefetch)
|
285
392
|
|
286
|
-
|
287
|
-
|
288
|
-
|
393
|
+
if $syslog.nil?
|
394
|
+
Syslog.open( "haredo #{@name}", Syslog::LOG_PID,
|
395
|
+
Syslog::LOG_DAEMON | Syslog::LOG_LOCAL7 )
|
396
|
+
|
397
|
+
$syslog = true
|
289
398
|
end
|
290
|
-
end
|
291
399
|
|
292
|
-
|
293
|
-
# which tells the remote that this message is a response (as opposed to a
|
294
|
-
# message originating from another source which just happens to have the same
|
295
|
-
# message_id).
|
296
|
-
def reply(msg, args)
|
297
|
-
|
298
|
-
data = args[:data] || ''
|
299
|
-
headers = args[:headers] || {}
|
300
|
-
|
301
|
-
id = msg.properties.message_id.to_i
|
302
|
-
to = msg.properties.reply_to
|
303
|
-
|
304
|
-
# Set the reply flag to indicate that this is a response to a message
|
305
|
-
# sent. The message_id should already be set in the headers.
|
306
|
-
headers[:reply] = 1
|
307
|
-
headers[:id] = id.to_i
|
400
|
+
Syslog.notice('listen()')
|
308
401
|
|
309
|
-
|
402
|
+
listen_queue.subscribe(:block => block, :ack => true) do |info, props, data|
|
403
|
+
@channel.acknowledge(info.delivery_tag, false)
|
404
|
+
serve RabbitMQ::Message.new(info, props, data)
|
405
|
+
end
|
310
406
|
end
|
311
|
-
|
312
|
-
|
407
|
+
|
408
|
+
def serve(msg)
|
409
|
+
@plugins.process(msg)
|
410
|
+
end
|
411
|
+
|
412
|
+
end # class Peer
|
313
413
|
|
314
414
|
end # module HareDo
|