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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/examples/README.md +76 -0
  3. data/examples/broker.rb +167 -0
  4. data/examples/client.rb +79 -0
  5. data/examples/direct_recv.rb +61 -0
  6. data/examples/direct_send.rb +67 -0
  7. data/examples/example_test.rb +109 -0
  8. data/examples/helloworld.rb +57 -0
  9. data/examples/server.rb +70 -0
  10. data/examples/simple_recv.rb +57 -0
  11. data/examples/simple_send.rb +63 -0
  12. data/examples/ssl_certs/README.txt +24 -0
  13. data/examples/ssl_certs/tclient-certificate.p12 +0 -0
  14. data/examples/ssl_certs/tclient-certificate.pem +19 -0
  15. data/examples/ssl_certs/tclient-full.p12 +0 -0
  16. data/examples/ssl_certs/tclient-private-key.pem +30 -0
  17. data/examples/ssl_certs/tserver-certificate.p12 +0 -0
  18. data/examples/ssl_certs/tserver-certificate.pem +19 -0
  19. data/examples/ssl_certs/tserver-full.p12 +0 -0
  20. data/examples/ssl_certs/tserver-private-key.pem +30 -0
  21. data/examples/ssl_send.rb +70 -0
  22. data/ext/cproton/cproton.c +105 -74
  23. data/lib/core/container.rb +2 -1
  24. data/lib/core/ssl_domain.rb +1 -1
  25. data/lib/core/uri.rb +15 -9
  26. data/lib/handler/messaging_adapter.rb +20 -5
  27. data/tests/old_examples/broker.rb +200 -0
  28. data/tests/old_examples/client.rb +81 -0
  29. data/tests/old_examples/direct_recv.rb +64 -0
  30. data/tests/old_examples/direct_send.rb +63 -0
  31. data/tests/old_examples/helloworld.rb +72 -0
  32. data/tests/old_examples/helloworld_direct.rb +73 -0
  33. data/tests/old_examples/lib/debugging.rb +25 -0
  34. data/tests/old_examples/lib/driver.rb +68 -0
  35. data/tests/old_examples/lib/qpid_examples.rb +26 -0
  36. data/tests/old_examples/lib/selectable.rb +119 -0
  37. data/tests/old_examples/lib/send_and_receive.rb +89 -0
  38. data/tests/old_examples/old_example_test.rb +107 -0
  39. data/tests/old_examples/recv.rb +23 -0
  40. data/tests/old_examples/send.rb +21 -0
  41. data/tests/old_examples/server.rb +75 -0
  42. data/tests/old_examples/simple_recv.rb +57 -0
  43. data/tests/old_examples/simple_send.rb +54 -0
  44. data/tests/test_connection_driver.rb +134 -0
  45. data/tests/test_container.rb +319 -0
  46. data/tests/test_data.rb +66 -0
  47. data/tests/test_delivery.rb +110 -0
  48. data/tests/test_interop.rb +131 -0
  49. data/tests/test_messaging_adapter.rb +223 -0
  50. data/tests/test_old_adapter.rb +228 -0
  51. data/tests/test_tools.rb +147 -0
  52. data/tests/test_uri.rb +83 -0
  53. metadata +49 -3
@@ -0,0 +1,26 @@
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
+
21
+ require "selectable"
22
+ require "driver"
23
+ require "socket"
24
+ require "monitor"
25
+
26
+ include Socket::Constants
@@ -0,0 +1,119 @@
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 Selectable
20
+
21
+ attr_reader :transport
22
+
23
+ def initialize(transport, socket)
24
+ @transport = transport
25
+ @socket = socket
26
+ @socket.autoclose = true
27
+ @write_done = false
28
+ @read_done = false
29
+ end
30
+
31
+ def closed?
32
+ return true if @socket.closed?
33
+ return false if !@read_done && !@write_done
34
+ @socket.close
35
+ true
36
+ end
37
+
38
+ def fileno
39
+ @socket.fileno unless @socket.closed?
40
+ end
41
+
42
+ def to_io
43
+ @socket
44
+ end
45
+
46
+ def reading?
47
+ return false if @read_done
48
+ c = @transport.capacity
49
+ if c > 0
50
+ return true
51
+ elsif c < 0
52
+ @read_done = true
53
+ return false
54
+ else
55
+ return false
56
+ end
57
+ end
58
+
59
+ def writing?
60
+ return false if @write_done
61
+ begin
62
+ p = @transport.pending
63
+ if p > 0
64
+ return true
65
+ elsif p < 0
66
+ @write_done = true
67
+ return false
68
+ else
69
+ return false
70
+ end
71
+ rescue Qpid::Proton::TransportError => error
72
+ @write_done = true
73
+ return false
74
+ end
75
+ end
76
+
77
+ def readable
78
+ c = @transport.capacity
79
+ if c > 0
80
+ begin
81
+ data = @socket.recv(c)
82
+ if data
83
+ @transport.push(data)
84
+ else
85
+ @transport.close_tail
86
+ end
87
+ rescue Exception => error
88
+ puts "read error; #{error}"
89
+ @transport.close_tail
90
+ @read_done = true
91
+ end
92
+ elsif c < 0
93
+ @read_done = true
94
+ end
95
+ end
96
+
97
+ def writable
98
+ begin
99
+ p = @transport.pending
100
+ if p > 0
101
+ data = @transport.peek(p)
102
+ n = @socket.send(data, 0)
103
+ @transport.pop(n)
104
+ elsif p < 0
105
+ @write_done = true
106
+ end
107
+ rescue Exception => error
108
+ puts "write error: #{error}"
109
+ puts error.backtrace.join("\n")
110
+ @transport.close_head
111
+ @write_done = true
112
+ end
113
+ end
114
+
115
+ def tick(now)
116
+ @transport.tick(now)
117
+ end
118
+
119
+ end
@@ -0,0 +1,89 @@
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 ExampleSend < Qpid::Proton::Handler::MessagingHandler
20
+
21
+ attr_reader :url
22
+
23
+ def initialize(url, expected)
24
+ super()
25
+ @url = url
26
+ @sent = 0
27
+ @confirmed = 0
28
+ @expected = expected
29
+ end
30
+
31
+ def on_sendable(event)
32
+ while event.sender.credit > 0 && @sent < @expected
33
+ msg = Qpid::Proton::Message.new
34
+ msg.body = "sequence #{@sent}"
35
+ msg.id = @sent
36
+ event.sender.send(msg)
37
+ @sent = @sent + 1
38
+ end
39
+ end
40
+
41
+ def on_accepted(event)
42
+ @confirmed = @confirmed + 1
43
+ if self.finished?
44
+ puts "#{@expected > 1 ? 'All ' : ''}#{@expected} message#{@expected > 1 ? 's' : ''} confirmed!"
45
+ event.connection.close
46
+ end
47
+ end
48
+
49
+ def on_disconnected(event)
50
+ @sent = @confirmed
51
+ end
52
+
53
+ def finished?
54
+ @confirmed == @expected
55
+ end
56
+
57
+ end
58
+
59
+ class ExampleReceive < Qpid::Proton::Handler::MessagingHandler
60
+
61
+ attr_reader :url
62
+
63
+ def initialize(url, expected)
64
+ super()
65
+ @url = url
66
+ @expected = expected
67
+ @received = 0
68
+ end
69
+
70
+ def on_message(event)
71
+ if event.message.id.nil? || event.message.id < @received
72
+ puts "Missing or old message id: id=#{event.message.id}"
73
+ return
74
+ end
75
+ if @expected.zero? || (@received < @expected)
76
+ puts "Received: #{event.message.body}"
77
+ @received = @received + 1
78
+ if finished?
79
+ event.receiver.close
80
+ event.connection.close
81
+ end
82
+ end
83
+ end
84
+
85
+ def finished?
86
+ @received == @expected
87
+ end
88
+
89
+ end
@@ -0,0 +1,107 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Licensed to the Apache Software Foundation (ASF) under one
4
+ # or more contributor license agreements. See the NOTICE file
5
+ # distributed with this work for additional information
6
+ # regarding copyright ownership. The ASF licenses this file
7
+ # to you under the Apache License, Version 2.0 (the
8
+ # "License"); you may not use this file except in compliance
9
+ # with the License. You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing,
14
+ # software distributed under the License is distributed on an
15
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
+ # KIND, either express or implied. See the License for the
17
+ # specific language governing permissions and limitations
18
+ # under the License.
19
+ #
20
+
21
+ require 'minitest/autorun'
22
+ require 'qpid_proton'
23
+ require 'socket'
24
+ require 'rbconfig'
25
+
26
+ begin
27
+ MiniTest::Test
28
+ rescue NameError # For older versions of MiniTest
29
+ MiniTest::Test = MiniTest::Unit::TestCase
30
+ end
31
+
32
+ def unused_port; TCPServer.open(0) { |s| s.addr[1] } end
33
+ def make_url(port, path) "amqp://:#{port}/#{path}"; end
34
+
35
+ class OldExampleTest < MiniTest::Test
36
+
37
+ def run_script(*args)
38
+ IO.popen [RbConfig.ruby, *args];
39
+ end
40
+
41
+ def assert_output(want, args)
42
+ assert_equal want.strip, run_script(*args).read.strip
43
+ end
44
+
45
+ def test_helloworld
46
+ assert_output "Hello world!", ["helloworld.rb", "-a", make_url($port, __method__)]
47
+ end
48
+
49
+ def test_send_recv
50
+ assert_output "All 10 messages confirmed!", ["simple_send.rb", "-a", make_url($port, __method__)]
51
+ want = (0..9).reduce("") { |x,y| x << "Received: sequence #{y}\n" }
52
+ assert_output want, ["simple_recv.rb", "-a", make_url($port, __method__)]
53
+ end
54
+
55
+ def test_smoke
56
+ url = "127.0.0.1:#{unused_port}"
57
+ recv = run_script("recv.rb", "~#{url}")
58
+ recv.readline # Wait for "Listening"
59
+ assert_output("Status: ACCEPTED", ["send.rb", url])
60
+ assert_equal "Got: Hello World!", recv.read.strip
61
+ end
62
+
63
+ def test_client_server
64
+ want = <<EOS
65
+ -> Twas brillig, and the slithy toves
66
+ <- TWAS BRILLIG, AND THE SLITHY TOVES
67
+ -> Did gire and gymble in the wabe.
68
+ <- DID GIRE AND GYMBLE IN THE WABE.
69
+ -> All mimsy were the borogroves,
70
+ <- ALL MIMSY WERE THE BOROGROVES,
71
+ -> And the mome raths outgrabe.
72
+ <- AND THE MOME RATHS OUTGRABE.
73
+ EOS
74
+ srv = run_script("server.rb", "-a", make_url($port, __method__))
75
+ assert_output(want, ["client.rb", "-a", make_url($port, __method__)])
76
+ ensure
77
+ Process.kill :TERM, srv.pid if srv
78
+ end
79
+
80
+ def test_direct_recv
81
+ url = make_url unused_port, __method__
82
+ p = run_script("direct_recv.rb", "-a", url)
83
+ p.readline # Wait till ready
84
+ assert_output("All 10 messages confirmed!", ["simple_send.rb", "-a", url])
85
+ want = (0..9).reduce("") { |x,y| x << "Received: sequence #{y}\n" }
86
+ assert_equal(want.strip, p.read.strip)
87
+ end
88
+
89
+ def test_direct_send
90
+ url = make_url unused_port, __method__
91
+ p = run_script("direct_send.rb", "-a", url)
92
+ p.readline # Wait till ready
93
+ want = (0..9).reduce("") { |x,y| x << "Received: sequence #{y}\n" }
94
+ assert_output(want, ["simple_recv.rb", "-a", url])
95
+ assert_equal("All 10 messages confirmed!", p.read.strip)
96
+ end
97
+ end
98
+
99
+ # Start the broker before all tests.
100
+ $port = unused_port
101
+ $broker = IO.popen [RbConfig.ruby, "broker.rb", "-a", ":#{$port}"]
102
+ $broker.readline # Wait for "Listening"
103
+
104
+ # Kill the broker after all tests
105
+ MiniTest.after_run do
106
+ Process.kill(:TERM, $broker.pid) if $broker
107
+ end
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'qpid_proton.rb'
4
+
5
+ messenger = Qpid::Proton::Messenger::Messenger.new()
6
+ messenger.incoming_window = 1
7
+ message = Qpid::Proton::Message.new()
8
+
9
+ address = ARGV[0]
10
+ if not address then
11
+ address = "~0.0.0.0"
12
+ end
13
+ messenger.subscribe(address)
14
+
15
+ messenger.start()
16
+
17
+ puts "Listening"; STDOUT.flush
18
+ messenger.receive()
19
+ messenger.get(message)
20
+ puts "Got: #{message.body}"
21
+ messenger.accept()
22
+
23
+ messenger.stop()
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'qpid_proton.rb'
4
+
5
+ messenger = Qpid::Proton::Messenger::Messenger.new()
6
+ messenger.outgoing_window = 10
7
+ message = Qpid::Proton::Message.new()
8
+
9
+ address = ARGV[0]
10
+ if not address then
11
+ address = "0.0.0.0"
12
+ end
13
+
14
+ message.address = address
15
+ message.body = "Hello World!"
16
+
17
+ messenger.start()
18
+ tracker = messenger.put(message)
19
+ messenger.send()
20
+ print "Status: ", messenger.status(tracker), "\n"
21
+ messenger.stop()
@@ -0,0 +1,75 @@
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 Server < Qpid::Proton::Handler::MessagingHandler
23
+
24
+ def initialize(url)
25
+ super()
26
+ @url = Qpid::Proton::URL.new url
27
+ @address = @url.path
28
+ @senders = {}
29
+ end
30
+
31
+ def on_start(event)
32
+ @container = event.container
33
+ @conn = @container.connect(:url => @url)
34
+ @receiver = @container.create_receiver(@conn, :source => @address)
35
+ @relay = nil
36
+ end
37
+
38
+ def on_connection_opened(event)
39
+ if event.connection.offered_capabilities &&
40
+ event.connection.offered_capabilities.contain?("ANONYMOUS-RELAY")
41
+ @relay = @container.create_sender(@conn, nil)
42
+ end
43
+ end
44
+
45
+ def on_message(event)
46
+ msg = event.message
47
+ puts "<- #{msg.body}"
48
+ sender = @relay || @senders[msg.reply_to]
49
+ if sender.nil?
50
+ sender = @container.create_sender(@conn, :target => msg.reply_to)
51
+ @senders[msg.reply_to] = sender
52
+ end
53
+ reply = Qpid::Proton::Message.new
54
+ reply.address = msg.reply_to
55
+ reply.body = msg.body.upcase
56
+ puts "-> #{reply.body}"
57
+ reply.correlation_id = msg.correlation_id
58
+ sender.send(reply)
59
+ end
60
+
61
+ def on_transport_error(event)
62
+ raise "Connection error: #{event.transport.condition}"
63
+ end
64
+ end
65
+
66
+ options = {
67
+ :address => "localhost:5672/examples",
68
+ }
69
+
70
+ OptionParser.new do |opts|
71
+ opts.banner = "Usage: server.rb [options]"
72
+ opts.on("-a", "--address=ADDRESS", "Send messages to ADDRESS (def. #{options[:address]}).") { |address| options[:address] = address }
73
+ end.parse!
74
+
75
+ Qpid::Proton::Reactor::Container.new(Server.new(options[:address])).run()
@@ -0,0 +1,57 @@
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 Receiver < ExampleReceive
25
+
26
+ def initialize(url, count)
27
+ super(url, count)
28
+ end
29
+
30
+ def on_start(event)
31
+ event.container.create_receiver(@url)
32
+ end
33
+
34
+ end
35
+
36
+ options = {
37
+ :address => "localhost:5672/examples",
38
+ :messages => 10,
39
+ }
40
+
41
+ OptionParser.new do |opts|
42
+ opts.banner = "Usage: simple_send.rb [options]"
43
+
44
+ opts.on("-a", "--address=ADDRESS", "Send messages to ADDRESS (def. #{options[:address]}).") do |address|
45
+ options[:address] = address
46
+ end
47
+
48
+ opts.on("-m", "--messages=COUNT", "The number of messages to send (def. #{options[:messages]}",
49
+ OptionParser::DecimalInteger) do |messages|
50
+ options[:messages] = messages
51
+ end
52
+ end.parse!
53
+
54
+ begin
55
+ Qpid::Proton::Reactor::Container.new(Receiver.new(options[:address], options[:messages])).run
56
+ rescue Interrupt
57
+ end
@@ -0,0 +1,54 @@
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
+ event.container.create_sender(url)
37
+ end
38
+
39
+ end
40
+
41
+ OptionParser.new do |opts|
42
+ opts.banner = "Usage: simple_send.rb [options]"
43
+
44
+ opts.on("-a", "--address=ADDRESS", "Send messages to ADDRESS (def. #{options[:address]}).") do |address|
45
+ options[:address] = address
46
+ end
47
+
48
+ opts.on("-m", "--messages=COUNT", "The number of messages to send (def. #{options[:messages]}",
49
+ OptionParser::DecimalInteger) do |messages|
50
+ options[:messages] = messages
51
+ end
52
+ end.parse!
53
+
54
+ Qpid::Proton::Reactor::Container.new(SimpleSend.new(options[:address], options[:messages])).run