haredo 0.0.5 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|