qpid_proton 0.19.0 → 0.21.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/examples/README.md +76 -0
- data/examples/broker.rb +167 -0
- data/examples/client.rb +79 -0
- data/examples/direct_recv.rb +61 -0
- data/examples/direct_send.rb +67 -0
- data/examples/example_test.rb +109 -0
- data/examples/helloworld.rb +57 -0
- data/examples/server.rb +70 -0
- data/examples/simple_recv.rb +57 -0
- data/examples/simple_send.rb +63 -0
- data/examples/ssl_certs/README.txt +24 -0
- data/examples/ssl_certs/tclient-certificate.p12 +0 -0
- data/examples/ssl_certs/tclient-certificate.pem +19 -0
- data/examples/ssl_certs/tclient-full.p12 +0 -0
- data/examples/ssl_certs/tclient-private-key.pem +30 -0
- data/examples/ssl_certs/tserver-certificate.p12 +0 -0
- data/examples/ssl_certs/tserver-certificate.pem +19 -0
- data/examples/ssl_certs/tserver-full.p12 +0 -0
- data/examples/ssl_certs/tserver-private-key.pem +30 -0
- data/examples/ssl_send.rb +70 -0
- data/ext/cproton/cproton.c +105 -74
- data/lib/core/container.rb +2 -1
- data/lib/core/ssl_domain.rb +1 -1
- data/lib/core/uri.rb +15 -9
- data/lib/handler/messaging_adapter.rb +20 -5
- data/tests/old_examples/broker.rb +200 -0
- data/tests/old_examples/client.rb +81 -0
- data/tests/old_examples/direct_recv.rb +64 -0
- data/tests/old_examples/direct_send.rb +63 -0
- data/tests/old_examples/helloworld.rb +72 -0
- data/tests/old_examples/helloworld_direct.rb +73 -0
- data/tests/old_examples/lib/debugging.rb +25 -0
- data/tests/old_examples/lib/driver.rb +68 -0
- data/tests/old_examples/lib/qpid_examples.rb +26 -0
- data/tests/old_examples/lib/selectable.rb +119 -0
- data/tests/old_examples/lib/send_and_receive.rb +89 -0
- data/tests/old_examples/old_example_test.rb +107 -0
- data/tests/old_examples/recv.rb +23 -0
- data/tests/old_examples/send.rb +21 -0
- data/tests/old_examples/server.rb +75 -0
- data/tests/old_examples/simple_recv.rb +57 -0
- data/tests/old_examples/simple_send.rb +54 -0
- data/tests/test_connection_driver.rb +134 -0
- data/tests/test_container.rb +319 -0
- data/tests/test_data.rb +66 -0
- data/tests/test_delivery.rb +110 -0
- data/tests/test_interop.rb +131 -0
- data/tests/test_messaging_adapter.rb +223 -0
- data/tests/test_old_adapter.rb +228 -0
- data/tests/test_tools.rb +147 -0
- data/tests/test_uri.rb +83 -0
- metadata +49 -3
@@ -38,7 +38,7 @@ module Qpid::Proton
|
|
38
38
|
def on_container_start(container) delegate(:on_container_start, container); end
|
39
39
|
def on_container_stop(container) delegate(:on_container_stop, container); end
|
40
40
|
|
41
|
-
# Define repetative on_xxx_open/close methods for
|
41
|
+
# Define repetative on_xxx_open/close methods for session and connection
|
42
42
|
def self.open_close(endpoint)
|
43
43
|
Module.new do
|
44
44
|
define_method(:"on_#{endpoint}_remote_open") do |event|
|
@@ -61,7 +61,24 @@ module Qpid::Proton
|
|
61
61
|
end
|
62
62
|
# Generate and include open_close modules for each endpoint type
|
63
63
|
# Using modules so we can override to extend the behavior later in the handler.
|
64
|
-
[:connection, :session
|
64
|
+
[:connection, :session].each { |endpoint| include open_close(endpoint) }
|
65
|
+
|
66
|
+
# Link open/close is handled separately because links are split into
|
67
|
+
# sender and receiver on the messaging API
|
68
|
+
def on_link_remote_open(event)
|
69
|
+
delegate(event.link.sender? ? :on_sender_open : :on_receiver_open, event.link)
|
70
|
+
event.link.open if event.link.local_uninit?
|
71
|
+
add_credit(event)
|
72
|
+
rescue StopAutoResponse
|
73
|
+
end
|
74
|
+
|
75
|
+
def on_link_remote_close(event)
|
76
|
+
s = event.link.sender?
|
77
|
+
delegate_error(s ? :on_sender_error : :on_receiver_error, event.link) if event.link.condition
|
78
|
+
delegate(s ? :on_sender_close : :on_receiver_close, event.link)
|
79
|
+
event.link.close if event.link.local_active?
|
80
|
+
rescue StopAutoResponse
|
81
|
+
end
|
65
82
|
|
66
83
|
def on_transport_error(event)
|
67
84
|
delegate_error(:on_transport_error, event.context)
|
@@ -71,10 +88,8 @@ module Qpid::Proton
|
|
71
88
|
delegate(:on_transport_close, event.context) rescue StopAutoResponse
|
72
89
|
end
|
73
90
|
|
74
|
-
# Add flow control for link
|
91
|
+
# Add flow control for local link open
|
75
92
|
def on_link_local_open(event) add_credit(event); end
|
76
|
-
def on_link_remote_open(event) super; add_credit(event); end
|
77
|
-
|
78
93
|
|
79
94
|
def on_delivery(event)
|
80
95
|
if event.link.receiver? # Incoming message
|
@@ -0,0 +1,200 @@
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
2
|
+
# or more contributor license agreements. See the NOTICE file
|
3
|
+
# distributed with this work for additional information
|
4
|
+
# regarding copyright ownership. The ASF licenses this file
|
5
|
+
# to you under the Apache License, Version 2.0 (the
|
6
|
+
# "License"); you may not use this file except in compliance
|
7
|
+
# with the License. You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
12
|
+
# software distributed under the License is distributed on an
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
14
|
+
# KIND, either express or implied. See the License for the
|
15
|
+
# specific language governing permissions and limitations
|
16
|
+
# under the License.
|
17
|
+
|
18
|
+
|
19
|
+
require 'qpid_proton'
|
20
|
+
require 'optparse'
|
21
|
+
require 'pathname'
|
22
|
+
|
23
|
+
require_relative 'lib/debugging'
|
24
|
+
|
25
|
+
class Exchange
|
26
|
+
|
27
|
+
include Debugging
|
28
|
+
|
29
|
+
def initialize(dynamic = false)
|
30
|
+
@dynamic = dynamic
|
31
|
+
@queue = Queue.new
|
32
|
+
@consumers = []
|
33
|
+
end
|
34
|
+
|
35
|
+
def subscribe(consumer)
|
36
|
+
debug("subscribing #{consumer}") if $options[:debug]
|
37
|
+
@consumers << (consumer)
|
38
|
+
debug(" there are #{@consumers.size} consumers") if $options[:debug]
|
39
|
+
end
|
40
|
+
|
41
|
+
def unsubscribe(consumer)
|
42
|
+
debug("unsubscribing #{consumer}") if $options[:debug]
|
43
|
+
if @consumers.include?(consumer)
|
44
|
+
@consumers.delete(consumer)
|
45
|
+
else
|
46
|
+
debug(" consumer doesn't exist") if $options[:debug]
|
47
|
+
end
|
48
|
+
debug(" there are #{@consumers.size} consumers") if $options[:debug]
|
49
|
+
@consumers.empty? && (@dynamic || @queue.empty?)
|
50
|
+
end
|
51
|
+
|
52
|
+
def publish(message)
|
53
|
+
debug("queueing message: #{message.body}") if $options[:debug]
|
54
|
+
@queue << message
|
55
|
+
self.dispatch
|
56
|
+
end
|
57
|
+
|
58
|
+
def dispatch(consumer = nil)
|
59
|
+
debug("dispatching: consumer=#{consumer}") if $options[:debug]
|
60
|
+
if consumer
|
61
|
+
c = [consumer]
|
62
|
+
else
|
63
|
+
c = @consumers
|
64
|
+
end
|
65
|
+
|
66
|
+
while self.deliver_to(c) do
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def deliver_to(consumers)
|
71
|
+
debug("delivering to #{consumers.size} consumer(s)") if $options[:debug]
|
72
|
+
result = false
|
73
|
+
consumers.each do |consumer|
|
74
|
+
debug(" current consumer=#{consumer} credit=#{consumer.credit}") if $options[:debug]
|
75
|
+
if consumer.credit > 0 && !@queue.empty?
|
76
|
+
consumer.send(@queue.pop(true))
|
77
|
+
result = true
|
78
|
+
end
|
79
|
+
end
|
80
|
+
return result
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
class Broker < Qpid::Proton::Handler::MessagingHandler
|
86
|
+
|
87
|
+
include Debugging
|
88
|
+
|
89
|
+
def initialize(url)
|
90
|
+
super()
|
91
|
+
@url = url
|
92
|
+
@queues = {}
|
93
|
+
end
|
94
|
+
|
95
|
+
def on_start(event)
|
96
|
+
debug("on_start event") if $options[:debug]
|
97
|
+
@acceptor = event.container.listen(@url)
|
98
|
+
print "Listening on #{@url}\n"
|
99
|
+
STDOUT.flush
|
100
|
+
end
|
101
|
+
|
102
|
+
def queue(address)
|
103
|
+
debug("fetching queue for #{address}: (there are #{@queues.size} queues)") if $options[:debug]
|
104
|
+
unless @queues.has_key?(address)
|
105
|
+
debug(" creating new queue") if $options[:debug]
|
106
|
+
@queues[address] = Exchange.new
|
107
|
+
else
|
108
|
+
debug(" using existing queue") if $options[:debug]
|
109
|
+
end
|
110
|
+
result = @queues[address]
|
111
|
+
debug(" returning #{result}") if $options[:debug]
|
112
|
+
return result
|
113
|
+
end
|
114
|
+
|
115
|
+
def on_link_opening(event)
|
116
|
+
debug("processing on_link_opening") if $options[:debug]
|
117
|
+
debug("link is#{event.link.sender? ? '' : ' not'} a sender") if $options[:debug]
|
118
|
+
if event.link.sender?
|
119
|
+
if event.link.remote_source.dynamic?
|
120
|
+
address = SecureRandom.uuid
|
121
|
+
event.link.source.address = address
|
122
|
+
q = Exchange.new(true)
|
123
|
+
@queues[address] = q
|
124
|
+
q.subscribe(event.link)
|
125
|
+
elsif event.link.remote_source.address
|
126
|
+
event.link.source.address = event.link.remote_source.address
|
127
|
+
self.queue(event.link.source.address).subscribe(event.link)
|
128
|
+
end
|
129
|
+
elsif event.link.remote_target.address
|
130
|
+
event.link.target.address = event.link.remote_target.address
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def unsubscribe(link)
|
135
|
+
debug("unsubscribing #{link.address}") if $options[:debug]
|
136
|
+
if @queues.has_key?(link.source.address)
|
137
|
+
if @queues[link.source.address].unsubscribe(link)
|
138
|
+
@queues.delete(link.source.address)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def on_link_closing(event)
|
144
|
+
self.unsubscribe(event.link) if event.link.sender?
|
145
|
+
end
|
146
|
+
|
147
|
+
def on_connection_closing(event)
|
148
|
+
self.remove_stale_consumers(event.connection)
|
149
|
+
end
|
150
|
+
|
151
|
+
def on_disconnected(event)
|
152
|
+
self.remove_stale_consumers(event.connection)
|
153
|
+
end
|
154
|
+
|
155
|
+
def remove_stale_consumers(connection)
|
156
|
+
l = connection.link_head(Qpid::Proton::Endpoint::REMOTE_ACTIVE)
|
157
|
+
while !l.nil?
|
158
|
+
self.unsubscribe(l) if l.sender?
|
159
|
+
l = l.next(Qpid::Proton::Endpoint::REMOTE_ACTIVE)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def on_sendable(event)
|
164
|
+
debug("on_sendable event") if $options[:debug]
|
165
|
+
q = self.queue(event.link.source.address)
|
166
|
+
debug(" dispatching #{event.message} to #{q}") if $options[:debug]
|
167
|
+
q.dispatch(event.link)
|
168
|
+
end
|
169
|
+
|
170
|
+
def on_message(event)
|
171
|
+
debug("on_message event") if $options[:debug]
|
172
|
+
q = self.queue(event.link.target.address)
|
173
|
+
debug(" dispatching #{event.message} to #{q}") if $options[:debug]
|
174
|
+
q.publish(event.message)
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|
178
|
+
|
179
|
+
$options = {
|
180
|
+
:address => "localhost:5672",
|
181
|
+
:debug => false
|
182
|
+
}
|
183
|
+
|
184
|
+
OptionParser.new do |opts|
|
185
|
+
opts.banner = "Usage: #{Pathname.new(__FILE__).basename} [$options]"
|
186
|
+
|
187
|
+
opts.on("-a", "--address=ADDRESS", "Send messages to ADDRESS (def. #{$options[:address]}).") do |address|
|
188
|
+
$options[:address] = address
|
189
|
+
end
|
190
|
+
|
191
|
+
opts.on("-d", "--debug", "Enable debugging output (def. #{$options[:debug]})") do
|
192
|
+
$options[:debug] = true
|
193
|
+
end
|
194
|
+
|
195
|
+
end.parse!
|
196
|
+
|
197
|
+
begin
|
198
|
+
Qpid::Proton::Reactor::Container.new(Broker.new($options[:address])).run
|
199
|
+
rescue Interrupt
|
200
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
2
|
+
# or more contributor license agreements. See the NOTICE file
|
3
|
+
# distributed with this work for additional information
|
4
|
+
# regarding copyright ownership. The ASF licenses this file
|
5
|
+
# to you under the Apache License, Version 2.0 (the
|
6
|
+
# "License"); you may not use this file except in compliance
|
7
|
+
# with the License. You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
12
|
+
# software distributed under the License is distributed on an
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
14
|
+
# KIND, either express or implied. See the License for the
|
15
|
+
# specific language governing permissions and limitations
|
16
|
+
# under the License.
|
17
|
+
|
18
|
+
|
19
|
+
require 'qpid_proton'
|
20
|
+
require 'optparse'
|
21
|
+
|
22
|
+
class Client < Qpid::Proton::Handler::MessagingHandler
|
23
|
+
|
24
|
+
def initialize(url, requests)
|
25
|
+
super()
|
26
|
+
@url = url
|
27
|
+
@requests = requests
|
28
|
+
end
|
29
|
+
|
30
|
+
def on_start(event)
|
31
|
+
@sender = event.container.create_sender(@url)
|
32
|
+
@receiver = event.container.create_receiver(@sender.connection, :dynamic => true)
|
33
|
+
end
|
34
|
+
|
35
|
+
def next_request
|
36
|
+
if @receiver.remote_source.address
|
37
|
+
req = Qpid::Proton::Message.new
|
38
|
+
req.reply_to = @receiver.remote_source.address
|
39
|
+
req.body = @requests.first
|
40
|
+
puts "-> #{req.body}"
|
41
|
+
@sender.send(req)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def on_link_opened(event)
|
46
|
+
if event.receiver == @receiver
|
47
|
+
next_request
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def on_message(event)
|
52
|
+
puts "<- #{event.message.body}"
|
53
|
+
@requests.delete_at(0)
|
54
|
+
if !@requests.empty?
|
55
|
+
next_request
|
56
|
+
else
|
57
|
+
event.connection.close
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def on_transport_error(event)
|
62
|
+
raise "Connection error: #{event.transport.condition}"
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
REQUESTS = ["Twas brillig, and the slithy toves",
|
68
|
+
"Did gire and gymble in the wabe.",
|
69
|
+
"All mimsy were the borogroves,",
|
70
|
+
"And the mome raths outgrabe."]
|
71
|
+
|
72
|
+
options = {
|
73
|
+
:address => "localhost:5672/examples",
|
74
|
+
}
|
75
|
+
|
76
|
+
OptionParser.new do |opts|
|
77
|
+
opts.banner = "Usage: client.rb [options]"
|
78
|
+
opts.on("-a", "--address=ADDRESS", "Send messages to ADDRESS (def. #{options[:address]}).") { |address| options[:address] = address }
|
79
|
+
end.parse!
|
80
|
+
|
81
|
+
Qpid::Proton::Reactor::Container.new(Client.new(options[:address], REQUESTS)).run
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
2
|
+
# or more contributor license agreements. See the NOTICE file
|
3
|
+
# distributed with this work for additional information
|
4
|
+
# regarding copyright ownership. The ASF licenses this file
|
5
|
+
# to you under the Apache License, Version 2.0 (the
|
6
|
+
# "License"); you may not use this file except in compliance
|
7
|
+
# with the License. You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
12
|
+
# software distributed under the License is distributed on an
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
14
|
+
# KIND, either express or implied. See the License for the
|
15
|
+
# specific language governing permissions and limitations
|
16
|
+
# under the License.
|
17
|
+
|
18
|
+
|
19
|
+
require 'qpid_proton'
|
20
|
+
require 'optparse'
|
21
|
+
|
22
|
+
require_relative 'lib/send_and_receive'
|
23
|
+
|
24
|
+
class DirectReceive < ExampleReceive
|
25
|
+
|
26
|
+
def initialize(url, expected)
|
27
|
+
super
|
28
|
+
end
|
29
|
+
|
30
|
+
def on_start(event)
|
31
|
+
@acceptor = event.container.listen(self.url)
|
32
|
+
puts "Listening"; STDOUT.flush
|
33
|
+
end
|
34
|
+
|
35
|
+
def on_connection_opening(event)
|
36
|
+
@acceptor.close
|
37
|
+
end
|
38
|
+
|
39
|
+
def on_message(event)
|
40
|
+
super(event)
|
41
|
+
@acceptor.close if self.finished?
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
options = {
|
47
|
+
:address => "localhost:5672/examples",
|
48
|
+
:messages => 10,
|
49
|
+
}
|
50
|
+
|
51
|
+
OptionParser.new do |opts|
|
52
|
+
opts.banner = "Usage: simple_send.rb [options]"
|
53
|
+
|
54
|
+
opts.on("-a", "--address=ADDRESS", "Send messages to ADDRESS (def. #{options[:address]}).") do |address|
|
55
|
+
options[:address] = address
|
56
|
+
end
|
57
|
+
|
58
|
+
opts.on("-m", "--messages=COUNT", "The number of messages to send (def. #{options[:messages]}",
|
59
|
+
OptionParser::DecimalInteger) do |messages|
|
60
|
+
options[:messages] = messages
|
61
|
+
end
|
62
|
+
end.parse!
|
63
|
+
|
64
|
+
Qpid::Proton::Reactor::Container.new(DirectReceive.new(options[:address], options[:messages])).run
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
2
|
+
# or more contributor license agreements. See the NOTICE file
|
3
|
+
# distributed with this work for additional information
|
4
|
+
# regarding copyright ownership. The ASF licenses this file
|
5
|
+
# to you under the Apache License, Version 2.0 (the
|
6
|
+
# "License"); you may not use this file except in compliance
|
7
|
+
# with the License. You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
12
|
+
# software distributed under the License is distributed on an
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
14
|
+
# KIND, either express or implied. See the License for the
|
15
|
+
# specific language governing permissions and limitations
|
16
|
+
# under the License.
|
17
|
+
|
18
|
+
|
19
|
+
require 'qpid_proton'
|
20
|
+
require 'optparse'
|
21
|
+
|
22
|
+
require_relative 'lib/send_and_receive'
|
23
|
+
|
24
|
+
options = {
|
25
|
+
:address => "localhost:5672/examples",
|
26
|
+
:messages => 10,
|
27
|
+
}
|
28
|
+
|
29
|
+
class SimpleSend < ExampleSend
|
30
|
+
|
31
|
+
def initialize(url, messages)
|
32
|
+
super(url, messages)
|
33
|
+
end
|
34
|
+
|
35
|
+
def on_start(event)
|
36
|
+
@acceptor = event.container.listen(url)
|
37
|
+
puts "Listening"; STDOUT.flush
|
38
|
+
end
|
39
|
+
|
40
|
+
def on_connection_opening(event)
|
41
|
+
@acceptor.close
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
OptionParser.new do |opts|
|
46
|
+
opts.banner = "Usage: simple_send.rb [options]"
|
47
|
+
|
48
|
+
opts.on("-a", "--address=ADDRESS", "Send messages to ADDRESS (def. #{options[:address]}).") do |address|
|
49
|
+
options[:address] = address
|
50
|
+
end
|
51
|
+
|
52
|
+
opts.on("-m", "--messages=COUNT", "The number of messages to send (def. #{options[:messages]}",
|
53
|
+
OptionParser::DecimalInteger) do |messages|
|
54
|
+
options[:messages] = messages
|
55
|
+
end
|
56
|
+
end.parse!
|
57
|
+
|
58
|
+
begin
|
59
|
+
Qpid::Proton::Reactor::Container.new(SimpleSend.new(options[:address], options[:messages]), {:container_id=> "direct_send"}).run
|
60
|
+
|
61
|
+
rescue Interrupt => error
|
62
|
+
puts "ERROR: #{error}"
|
63
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
2
|
+
# or more contributor license agreements. See the NOTICE file
|
3
|
+
# distributed with this work for additional information
|
4
|
+
# regarding copyright ownership. The ASF licenses this file
|
5
|
+
# to you under the Apache License, Version 2.0 (the
|
6
|
+
# "License"); you may not use this file except in compliance
|
7
|
+
# with the License. You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
12
|
+
# software distributed under the License is distributed on an
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
14
|
+
# KIND, either express or implied. See the License for the
|
15
|
+
# specific language governing permissions and limitations
|
16
|
+
# under the License.
|
17
|
+
|
18
|
+
|
19
|
+
require 'qpid_proton'
|
20
|
+
require 'optparse'
|
21
|
+
|
22
|
+
class HelloWorld < Qpid::Proton::Handler::MessagingHandler
|
23
|
+
|
24
|
+
def initialize(server, address)
|
25
|
+
super()
|
26
|
+
@server = server
|
27
|
+
@address = address
|
28
|
+
end
|
29
|
+
|
30
|
+
def on_start(event)
|
31
|
+
conn = event.container.connect(:address => @server)
|
32
|
+
event.container.create_sender(conn, :target => @address)
|
33
|
+
event.container.create_receiver(conn, :source => @address)
|
34
|
+
end
|
35
|
+
|
36
|
+
def on_sendable(event)
|
37
|
+
msg = Qpid::Proton::Message.new
|
38
|
+
msg.body = "Hello world!"
|
39
|
+
event.sender.send(msg)
|
40
|
+
event.sender.close
|
41
|
+
end
|
42
|
+
|
43
|
+
def on_message(event)
|
44
|
+
puts event.message.body
|
45
|
+
event.connection.close
|
46
|
+
end
|
47
|
+
|
48
|
+
def on_transport_error(event)
|
49
|
+
raise "Connection error: #{event.transport.condition}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
options = {
|
54
|
+
:address => "localhost:5672",
|
55
|
+
:queue => "examples"
|
56
|
+
}
|
57
|
+
|
58
|
+
OptionParser.new do |opts|
|
59
|
+
opts.banner = "Usage: helloworld_direct.rb [options]"
|
60
|
+
|
61
|
+
opts.on("-a", "--address=ADDRESS", "Send messages to ADDRESS (def. #{options[:address]}).") do |address|
|
62
|
+
options[:address] = address
|
63
|
+
end
|
64
|
+
|
65
|
+
opts.on("-q", "--queue=QUEUE", "Send messages to QUEUE (def. #{options[:queue]})") do |queue|
|
66
|
+
options[:queue] = queue
|
67
|
+
end
|
68
|
+
|
69
|
+
end.parse!
|
70
|
+
|
71
|
+
hw = HelloWorld.new(options[:address], "examples")
|
72
|
+
Qpid::Proton::Reactor::Container.new(hw).run
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
2
|
+
# or more contributor license agreements. See the NOTICE file
|
3
|
+
# distributed with this work for additional information
|
4
|
+
# regarding copyright ownership. The ASF licenses this file
|
5
|
+
# to you under the Apache License, Version 2.0 (the
|
6
|
+
# "License"); you may not use this file except in compliance
|
7
|
+
# with the License. You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
12
|
+
# software distributed under the License is distributed on an
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
14
|
+
# KIND, either express or implied. See the License for the
|
15
|
+
# specific language governing permissions and limitations
|
16
|
+
# under the License.
|
17
|
+
|
18
|
+
|
19
|
+
require 'qpid_proton'
|
20
|
+
require 'optparse'
|
21
|
+
|
22
|
+
options = {
|
23
|
+
:address => "localhost:5672/examples",
|
24
|
+
}
|
25
|
+
|
26
|
+
class HelloWorldDirect < Qpid::Proton::Handler::MessagingHandler
|
27
|
+
|
28
|
+
include Qpid::Proton::Util::Wrapper
|
29
|
+
|
30
|
+
def initialize(url)
|
31
|
+
super()
|
32
|
+
@url = url
|
33
|
+
end
|
34
|
+
|
35
|
+
def on_start(event)
|
36
|
+
@acceptor = event.container.listen(@url)
|
37
|
+
event.container.create_sender(@url)
|
38
|
+
end
|
39
|
+
|
40
|
+
def on_sendable(event)
|
41
|
+
msg = Qpid::Proton::Message.new
|
42
|
+
msg.body = "Hello world!"
|
43
|
+
event.sender.send(msg)
|
44
|
+
event.sender.close
|
45
|
+
end
|
46
|
+
|
47
|
+
def on_message(event)
|
48
|
+
puts "#{event.message.body}"
|
49
|
+
end
|
50
|
+
|
51
|
+
def on_accepted(event)
|
52
|
+
event.connection.close
|
53
|
+
end
|
54
|
+
|
55
|
+
def on_connection_closed(event)
|
56
|
+
@acceptor.close
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
OptionParser.new do |opts|
|
62
|
+
opts.banner = "Usage: helloworld_direct.rb [options]"
|
63
|
+
|
64
|
+
opts.on("-a", "--address=ADDRESS", "Send messages to ADDRESS (def. #{options[:address]}).") do |address|
|
65
|
+
options[:address] = address
|
66
|
+
end
|
67
|
+
|
68
|
+
end.parse!
|
69
|
+
|
70
|
+
begin
|
71
|
+
Qpid::Proton::Reactor::Container.new(HelloWorldDirect.new(options[:address])).run
|
72
|
+
rescue Interrupt => error
|
73
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
2
|
+
# or more contributor license agreements. See the NOTICE file
|
3
|
+
# distributed with this work for additional information
|
4
|
+
# regarding copyright ownership. The ASF licenses this file
|
5
|
+
# to you under the Apache License, Version 2.0 (the
|
6
|
+
# "License"); you may not use this file except in compliance
|
7
|
+
# with the License. You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
12
|
+
# software distributed under the License is distributed on an
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
14
|
+
# KIND, either express or implied. See the License for the
|
15
|
+
# specific language governing permissions and limitations
|
16
|
+
# under the License.
|
17
|
+
|
18
|
+
|
19
|
+
module Debugging
|
20
|
+
|
21
|
+
def debug(text)
|
22
|
+
print "[#{Time.now.strftime('%s')}] #{text}\n"
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
2
|
+
# or more contributor license agreements. See the NOTICE file
|
3
|
+
# distributed with this work for additional information
|
4
|
+
# regarding copyright ownership. The ASF licenses this file
|
5
|
+
# to you under the Apache License, Version 2.0 (the
|
6
|
+
# "License"); you may not use this file except in compliance
|
7
|
+
# with the License. You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
12
|
+
# software distributed under the License is distributed on an
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
14
|
+
# KIND, either express or implied. See the License for the
|
15
|
+
# specific language governing permissions and limitations
|
16
|
+
# under the License.
|
17
|
+
|
18
|
+
|
19
|
+
class Driver
|
20
|
+
|
21
|
+
def initialize
|
22
|
+
@selectables = {}
|
23
|
+
end
|
24
|
+
|
25
|
+
def add(selectable)
|
26
|
+
@selectables[selectable.fileno] = selectable
|
27
|
+
end
|
28
|
+
|
29
|
+
def process
|
30
|
+
reading = []
|
31
|
+
writing = []
|
32
|
+
|
33
|
+
@selectables.each_value do |sel|
|
34
|
+
if sel.closed? || sel.fileno.nil?
|
35
|
+
@selectables.delete(sel.fileno)
|
36
|
+
else
|
37
|
+
begin
|
38
|
+
reading << sel.to_io if sel.reading?
|
39
|
+
writing << sel.to_io if sel.writing?
|
40
|
+
rescue Exception => error
|
41
|
+
puts "Error: #{error}"
|
42
|
+
puts error.backtrace.join("\n");
|
43
|
+
# @selectables.delete(sel.fileno)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
read_from, write_to = IO.select(reading, writing, [], 0)
|
49
|
+
|
50
|
+
unless read_from.nil?
|
51
|
+
read_from.each do |r|
|
52
|
+
sel = @selectables[r.fileno]
|
53
|
+
sel.readable unless sel.nil? || sel.closed?
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
begin
|
58
|
+
unless write_to.nil?
|
59
|
+
write_to.each do |w|
|
60
|
+
sel = @selectables[w.fileno]
|
61
|
+
sel.writable unless sel.nil? || sel.closed?
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|