stompserver_ng 1.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +159 -0
- data/Manifest.txt +71 -0
- data/README.txt +172 -0
- data/Rakefile +38 -0
- data/STATUS +5 -0
- data/bin/stompserver_ng +63 -0
- data/client/README.txt +1 -0
- data/client/both.rb +25 -0
- data/client/consume.rb +14 -0
- data/client/send.rb +17 -0
- data/config/stompserver_ng.conf +11 -0
- data/etc/19xcompat/notes.txt +223 -0
- data/etc/arutils/README-activerecord.txt +78 -0
- data/etc/arutils/cre_mysql.rb +34 -0
- data/etc/arutils/cre_postgres.rb +33 -0
- data/etc/arutils/cre_sqlite3.rb +28 -0
- data/etc/arutils/mysql_boot.sql +12 -0
- data/etc/arutils/postgres_boot.sql +14 -0
- data/etc/database.mysql.yml +9 -0
- data/etc/database.postgres.yml +9 -0
- data/etc/passwd.example +3 -0
- data/etc/ppqinfo.rb +15 -0
- data/etc/runserver.sh +17 -0
- data/etc/stompserver_ng +50 -0
- data/etc/stompserver_ng.conf +13 -0
- data/lib/stomp_server_ng.rb +471 -0
- data/lib/stomp_server_ng/protocols/http.rb +128 -0
- data/lib/stomp_server_ng/protocols/stomp.rb +407 -0
- data/lib/stomp_server_ng/qmonitor.rb +58 -0
- data/lib/stomp_server_ng/queue.rb +248 -0
- data/lib/stomp_server_ng/queue/activerecord_queue.rb +118 -0
- data/lib/stomp_server_ng/queue/ar_message.rb +21 -0
- data/lib/stomp_server_ng/queue/ar_reconnect.rb +18 -0
- data/lib/stomp_server_ng/queue/dbm_queue.rb +72 -0
- data/lib/stomp_server_ng/queue/file_queue.rb +56 -0
- data/lib/stomp_server_ng/queue/memory_queue.rb +64 -0
- data/lib/stomp_server_ng/queue_manager.rb +302 -0
- data/lib/stomp_server_ng/stomp_auth.rb +26 -0
- data/lib/stomp_server_ng/stomp_frame.rb +32 -0
- data/lib/stomp_server_ng/stomp_frame_recognizer.rb +77 -0
- data/lib/stomp_server_ng/stomp_id.rb +32 -0
- data/lib/stomp_server_ng/stomp_user.rb +17 -0
- data/lib/stomp_server_ng/test_server.rb +21 -0
- data/lib/stomp_server_ng/topic_manager.rb +46 -0
- data/setup.rb +1585 -0
- data/stompserver_ng.gemspec +136 -0
- data/test/devserver/props.yaml +5 -0
- data/test/devserver/runserver.sh +16 -0
- data/test/devserver/stompserver_ng.dbm.conf +12 -0
- data/test/devserver/stompserver_ng.file.conf +12 -0
- data/test/devserver/stompserver_ng.memory.conf +12 -0
- data/test/noserver/mocklogger.rb +12 -0
- data/test/noserver/test_queue_manager.rb +134 -0
- data/test/noserver/test_stomp_frame.rb +138 -0
- data/test/noserver/test_topic_manager.rb +79 -0
- data/test/noserver/ts_all_no_server.rb +12 -0
- data/test/props.yaml +5 -0
- data/test/runalltests.sh +14 -0
- data/test/runtest.sh +4 -0
- data/test/test_0000_base.rb +107 -0
- data/test/test_0001_conn.rb +47 -0
- data/test/test_0002_conn_sr.rb +94 -0
- data/test/test_0006_client.rb +41 -0
- data/test/test_0011_send_recv.rb +74 -0
- data/test/test_0015_ack_conn.rb +78 -0
- data/test/test_0017_ack_client.rb +78 -0
- data/test/test_0019_ack_no_ack.rb +145 -0
- data/test/test_0022_ack_noack_conn.rb +123 -0
- data/test/test_0030_subscr_id.rb +44 -0
- data/test/test_0040_receipt_conn.rb +87 -0
- data/test/ts_all_server.rb +10 -0
- metadata +196 -0
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'stomp'
|
3
|
+
#
|
4
|
+
require 'test/unit'
|
5
|
+
$:.unshift File.dirname(__FILE__)
|
6
|
+
require 'test_0000_base'
|
7
|
+
#
|
8
|
+
# Test "ack" and :ack on a subscribe to a Stomp Connection.
|
9
|
+
#
|
10
|
+
class Test_0015_Ack_Conn < Test_0000_Base
|
11
|
+
|
12
|
+
# Setup.
|
13
|
+
# * Open a Stomp Connection
|
14
|
+
# * Set the test queue name
|
15
|
+
# * Set the message to use.
|
16
|
+
# * Set counter for looping tests
|
17
|
+
def setup
|
18
|
+
super
|
19
|
+
open_conn()
|
20
|
+
@queuename = "/queue/connack/" + name
|
21
|
+
@test_message = "What's up doc?"
|
22
|
+
@times = 10
|
23
|
+
#
|
24
|
+
end
|
25
|
+
|
26
|
+
# Teardown.
|
27
|
+
# # Connection disconnect.
|
28
|
+
def teardown
|
29
|
+
disconnect_conn()
|
30
|
+
end
|
31
|
+
|
32
|
+
# Test ACK of a single message
|
33
|
+
def test_0010_ack_conn_one
|
34
|
+
ack_conn_test("ack")
|
35
|
+
end
|
36
|
+
=begin
|
37
|
+
# Test ACK of a single message using symbol header
|
38
|
+
def test_0020_ack_conn_one_sym
|
39
|
+
ack_conn_test(:ack)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Test ACK of multiple messages
|
43
|
+
def test_0030_ack_conn_mult
|
44
|
+
ack_conn_test("ack", @times)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Test ACK of multiple messages using symbol header
|
48
|
+
def test_0040_ack_conn_mult_sym
|
49
|
+
ack_conn_test(:ack, @times)
|
50
|
+
end
|
51
|
+
=end
|
52
|
+
private
|
53
|
+
|
54
|
+
def ack_conn_test(ackparm = nil, ntimes = 1)
|
55
|
+
#
|
56
|
+
received = nil
|
57
|
+
assert_nothing_raised() {
|
58
|
+
ntimes.times do |n|
|
59
|
+
@conn.publish(@queuename, "#{@test_message} #{n+1}")
|
60
|
+
end
|
61
|
+
}
|
62
|
+
#
|
63
|
+
connection_subscribe(@queuename, { ackparm => "client" })
|
64
|
+
#
|
65
|
+
count = 0
|
66
|
+
assert_nothing_raised() {
|
67
|
+
ntimes.times do |n|
|
68
|
+
received = @conn.receive
|
69
|
+
@conn.ack(received.headers["message-id"])
|
70
|
+
count += 1
|
71
|
+
end
|
72
|
+
}
|
73
|
+
#
|
74
|
+
assert_equal(ntimes,count,"count should be the same: #{@queuename}")
|
75
|
+
end
|
76
|
+
|
77
|
+
end # of class
|
78
|
+
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'stomp'
|
3
|
+
#
|
4
|
+
require 'test/unit'
|
5
|
+
$:.unshift File.dirname(__FILE__)
|
6
|
+
require 'test_0000_base'
|
7
|
+
#
|
8
|
+
# Test ack => client using a Stomp Client.
|
9
|
+
#
|
10
|
+
class Test_0017_Ack_Client < Test_0000_Base
|
11
|
+
|
12
|
+
# Setup.
|
13
|
+
# * Queue Name
|
14
|
+
# * Message body
|
15
|
+
# * Count for multiples
|
16
|
+
# * Open a Stomp Client
|
17
|
+
def setup
|
18
|
+
super
|
19
|
+
@queue_name = "/queue/ackclisgl/" + name()
|
20
|
+
@test_message = "The Answer is Blowin' in the Wind."
|
21
|
+
@times = 10
|
22
|
+
open_client()
|
23
|
+
end
|
24
|
+
|
25
|
+
# Teardown.
|
26
|
+
# * Close the Stomp Client
|
27
|
+
def teardown
|
28
|
+
close_client()
|
29
|
+
end
|
30
|
+
|
31
|
+
# Test ACK from client
|
32
|
+
def test_0010_ack_send_receive
|
33
|
+
ack_client_test(:ackparm => "ack", :times => 1, :mod => "0010")
|
34
|
+
end
|
35
|
+
|
36
|
+
# Test ACK from client with symbol
|
37
|
+
def test_0020_ack_send_receive_sym
|
38
|
+
ack_client_test(:ackparm => :ack, :times => 1, :mod => "0020")
|
39
|
+
end
|
40
|
+
|
41
|
+
# Test ACK from client with miltiple messages
|
42
|
+
def test_0030_ack_send_receive_mult
|
43
|
+
ack_client_test(:ackparm => "ack", :times => @times, :mod => "0030")
|
44
|
+
end
|
45
|
+
|
46
|
+
# Test ACK from client with symbol and multiple messages
|
47
|
+
def test_0040_ack_send_receive_mult_sym
|
48
|
+
ack_client_test(:ackparm => :ack, :times => @times, :mod => "0040")
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def ack_client_test(params = {})
|
54
|
+
received = nil
|
55
|
+
count = 0
|
56
|
+
assert_nothing_raised() {
|
57
|
+
params[:times].times do |n|
|
58
|
+
@client.publish(@queue_name, "#{@test_message} #{n+1}",
|
59
|
+
{"persistent" => true,
|
60
|
+
"client-id" => "0017_putr_#{params[:mod]}",
|
61
|
+
"reply-to" => @queue_name} )
|
62
|
+
end
|
63
|
+
@client.subscribe(@queue_name,
|
64
|
+
{"persistent" => true,
|
65
|
+
"client-id" => "0017_getr_#{params[:mod]}",
|
66
|
+
params[:ackparm] => "client" }
|
67
|
+
) do |message|
|
68
|
+
received = message
|
69
|
+
@client.acknowledge(received) # ACK the message
|
70
|
+
count += 1
|
71
|
+
end
|
72
|
+
sleep 2.0 until received
|
73
|
+
}
|
74
|
+
assert_equal(params[:times],count,"counts should match: #{@queue_name}")
|
75
|
+
end
|
76
|
+
|
77
|
+
end # of class
|
78
|
+
|
@@ -0,0 +1,145 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'stomp'
|
3
|
+
#
|
4
|
+
require 'test/unit'
|
5
|
+
$:.unshift File.dirname(__FILE__)
|
6
|
+
require 'test_0000_base'
|
7
|
+
#
|
8
|
+
# Test situations with a Stomp Client where ack mode is specified on a
|
9
|
+
# subscribe, but the message is initially never actually ACK'd.
|
10
|
+
#
|
11
|
+
class Test_0019_Ack_No_Ack < Test_0000_Base
|
12
|
+
|
13
|
+
# Setup.
|
14
|
+
# * Queue name
|
15
|
+
# * Message body
|
16
|
+
# * Connect stagger/reconnect wait time
|
17
|
+
def setup
|
18
|
+
super
|
19
|
+
@queue_name = "/queue/acknoack/" + name()
|
20
|
+
@test_message = "Bad moon risin' ....."
|
21
|
+
@reconnect_stagger = 0.5
|
22
|
+
end
|
23
|
+
|
24
|
+
# Teardown.
|
25
|
+
def teardown
|
26
|
+
end
|
27
|
+
|
28
|
+
# Test Ack No Ack Reget:
|
29
|
+
# * Send a messsage
|
30
|
+
# * Subscribe with ack, and receive
|
31
|
+
# * Never send an ACK
|
32
|
+
# * Reconnect and subscribe with ack => auto
|
33
|
+
# * Re-receive the same message
|
34
|
+
# Expectation: no client errors, and no server crashes.
|
35
|
+
def test_0020_ack_no_ack_reget
|
36
|
+
#
|
37
|
+
open_client()
|
38
|
+
#
|
39
|
+
received = no_ack_get()
|
40
|
+
# But now, do _not_ ack the message, just close the client connection
|
41
|
+
close_client()
|
42
|
+
#
|
43
|
+
# The re-connect and re-get sequence
|
44
|
+
#
|
45
|
+
sleep @reconnect_stagger # Server needs to asynchronously complete disconnect
|
46
|
+
open_client()
|
47
|
+
#
|
48
|
+
received_02 = get_again("auto")
|
49
|
+
#
|
50
|
+
assert_equal(received.body, received_02.body, "message content should be the same")
|
51
|
+
# And so should the message ID.
|
52
|
+
assert_equal(received.headers["message-id"],received_02.headers["message-id"],
|
53
|
+
"message ID should be the same")
|
54
|
+
#
|
55
|
+
close_client()
|
56
|
+
end
|
57
|
+
|
58
|
+
# Test Ack No Ack Reget:
|
59
|
+
# * Send a messsage
|
60
|
+
# * Subscribe with ack, and receive
|
61
|
+
# * Never send an ACK
|
62
|
+
# * Reconnect and subscribe with ack => client
|
63
|
+
# * Re-receive the same message
|
64
|
+
# * Actually ACK the message
|
65
|
+
# Expectation: no client errors, and no server crashes.
|
66
|
+
def test_0030_ack_no_ack_reget
|
67
|
+
#
|
68
|
+
open_client()
|
69
|
+
#
|
70
|
+
received = no_ack_get()
|
71
|
+
# But now, do _not_ ack the message, just close the client connection
|
72
|
+
close_client()
|
73
|
+
#
|
74
|
+
# The re-connect and re-get sequence
|
75
|
+
#
|
76
|
+
sleep @reconnect_stagger # Server needs to asynchronously complete disconnect
|
77
|
+
open_client()
|
78
|
+
#
|
79
|
+
received_02 = get_again("client")
|
80
|
+
#
|
81
|
+
assert_equal(received.body, received_02.body, "message content should be the same")
|
82
|
+
# And so should the message ID.
|
83
|
+
assert_equal(received.headers["message-id"],received_02.headers["message-id"],
|
84
|
+
"message ID should be the same")
|
85
|
+
#
|
86
|
+
close_client()
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
# Send a message, subscribe with "ack" => "client", and receive it.
|
92
|
+
# Do *not* send ACK reply.
|
93
|
+
def no_ack_get()
|
94
|
+
sleep @sleep_time if @sleep_time > 0
|
95
|
+
#
|
96
|
+
received = nil
|
97
|
+
assert_nothing_raised() {
|
98
|
+
# Send a single message to a queue
|
99
|
+
@client.publish(@queue_name, @test_message,
|
100
|
+
{"persistent" => true,
|
101
|
+
"client-id" => "ana_client_put",
|
102
|
+
"reply-to" => @queue_name} )
|
103
|
+
sleep @sleep_time if @sleep_time > 0
|
104
|
+
# Subscribe with "ack" => "client", and receive the message
|
105
|
+
@client.subscribe(@queue_name,
|
106
|
+
{"persistent" => true, "client-id" => "ana_client_get",
|
107
|
+
"ack" => "client" } ) do |message|
|
108
|
+
received = message
|
109
|
+
end
|
110
|
+
sleep 0.5 until received
|
111
|
+
#
|
112
|
+
sleep @sleep_time if @sleep_time > 0
|
113
|
+
# Make sure what was received is the same is what was sent
|
114
|
+
assert_equal(@test_message, received.body, "get what ya' give .....")
|
115
|
+
}
|
116
|
+
received
|
117
|
+
end
|
118
|
+
|
119
|
+
# Subscribe and reget a message. The subscription may or may not be
|
120
|
+
# ack => client, depending on the caller. If ack => client is indicated,
|
121
|
+
# the message is actually ACK'd.
|
122
|
+
def get_again(ackmode)
|
123
|
+
sleep @sleep_time if @sleep_time > 0
|
124
|
+
#
|
125
|
+
received = nil
|
126
|
+
assert_nothing_raised() {
|
127
|
+
# Subscribe with ack as specified by caller
|
128
|
+
@client.subscribe(@queue_name,
|
129
|
+
{"persistent" => true, "client-id" => "anareg_client_reget",
|
130
|
+
"ack" => ackmode } ) do |message|
|
131
|
+
received = message
|
132
|
+
end
|
133
|
+
sleep 1.0 until received
|
134
|
+
#
|
135
|
+
sleep @sleep_time if @sleep_time > 0
|
136
|
+
# Make sure what was received is the same is what was sent
|
137
|
+
assert_equal(@test_message, received.body, "get again what ya' gave .....")
|
138
|
+
# Possible ACK, caller decides
|
139
|
+
@client.acknowledge(received) if ackmode == "client"
|
140
|
+
}
|
141
|
+
received
|
142
|
+
end
|
143
|
+
|
144
|
+
end # of class
|
145
|
+
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'stomp'
|
3
|
+
#
|
4
|
+
require 'test/unit'
|
5
|
+
$:.unshift File.dirname(__FILE__)
|
6
|
+
require 'test_0000_base'
|
7
|
+
#
|
8
|
+
# Test situations with a Stomp Connection where ack mode is specified on a
|
9
|
+
# connection_subscribe, but the message is initially never actually ACK'd.
|
10
|
+
#
|
11
|
+
#
|
12
|
+
class Test_0022_Ack_Noack_Conn < Test_0000_Base
|
13
|
+
|
14
|
+
# Setup.
|
15
|
+
# * Queue name
|
16
|
+
# * Message body
|
17
|
+
# * Connect stagger/reconnect wait time
|
18
|
+
def setup
|
19
|
+
super
|
20
|
+
open_conn()
|
21
|
+
@queuename = "/queue/connana1/" + name()
|
22
|
+
@test_message = "Blue Suede Shoes ..."
|
23
|
+
@reconnect_stagger = 0.5
|
24
|
+
#
|
25
|
+
end
|
26
|
+
|
27
|
+
# Teardown.
|
28
|
+
def teardown
|
29
|
+
disconnect_conn()
|
30
|
+
end
|
31
|
+
|
32
|
+
# Test Ack Conn No Ack Reget:
|
33
|
+
# * Send a messsage
|
34
|
+
# * Subscribe with ack, and receive
|
35
|
+
# * Never send an ACK
|
36
|
+
# * Reconnect and subscribe with ack => auto
|
37
|
+
# * Re-receive the same message
|
38
|
+
# Expectation: no client errors, and no server crashes.
|
39
|
+
|
40
|
+
def test_0020_ack_conn_no_ack_reget
|
41
|
+
received = no_ack_get()
|
42
|
+
#
|
43
|
+
disconnect_conn()
|
44
|
+
#
|
45
|
+
sleep @reconnect_stagger # Let server clean up
|
46
|
+
open_conn()
|
47
|
+
received_02 = get_again("auto")
|
48
|
+
#
|
49
|
+
assert_equal(received.body, received_02.body, "message content should be the same")
|
50
|
+
# And so should the message ID.
|
51
|
+
assert_equal(received.headers["message-id"],received_02.headers["message-id"],
|
52
|
+
"message ID should be the same")
|
53
|
+
#
|
54
|
+
end
|
55
|
+
|
56
|
+
# Test Ack No Ack Reget:
|
57
|
+
# * Send a messsage
|
58
|
+
# * Subscribe with ack, and receive
|
59
|
+
# * Never send an ACK
|
60
|
+
# * Reconnect and subscribe with ack => client
|
61
|
+
# * Re-receive the same message
|
62
|
+
# * Actually ACK the message
|
63
|
+
# Expectation: no client errors, and no server crashes.
|
64
|
+
|
65
|
+
def test_0030_ack_conn_no_ack
|
66
|
+
received = no_ack_get()
|
67
|
+
#
|
68
|
+
disconnect_conn()
|
69
|
+
#
|
70
|
+
sleep @reconnect_stagger # Let server clean up
|
71
|
+
open_conn()
|
72
|
+
received_02 = get_again("client")
|
73
|
+
#
|
74
|
+
assert_equal(received.body, received_02.body, "message content should be the same")
|
75
|
+
# And so should the message ID.
|
76
|
+
assert_equal(received.headers["message-id"],received_02.headers["message-id"],
|
77
|
+
"message ID should be the same")
|
78
|
+
#
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
# Send a message, subscribe with "ack" => "client", and receive it.
|
84
|
+
# Do *not* send ACK reply.
|
85
|
+
def no_ack_get()
|
86
|
+
received = nil
|
87
|
+
assert_nothing_raised() {
|
88
|
+
@conn.publish(@queuename, @test_message)
|
89
|
+
#
|
90
|
+
connection_subscribe(@queuename, { "ack" => "client" })
|
91
|
+
received = @conn.receive
|
92
|
+
}
|
93
|
+
#
|
94
|
+
assert_not_nil(received, "something should be received")
|
95
|
+
assert_equal(@test_message, received.body, "received should match sent")
|
96
|
+
#
|
97
|
+
assert_not_nil(received.headers["message-id"], "message ID should be present")
|
98
|
+
#
|
99
|
+
received
|
100
|
+
end
|
101
|
+
|
102
|
+
# Subscribe and reget a message. The subscription may or may not be
|
103
|
+
# ack => client, depending on the caller. If ack => client is indicated,
|
104
|
+
# the message is actually ACK'd.
|
105
|
+
def get_again(ackmode)
|
106
|
+
received = nil
|
107
|
+
assert_nothing_raised() {
|
108
|
+
connection_subscribe(@queuename, { "ack" => ackmode })
|
109
|
+
received = @conn.receive
|
110
|
+
}
|
111
|
+
#
|
112
|
+
assert_not_nil(received, "something should be received")
|
113
|
+
assert_equal(@test_message, received.body, "received should again match sent")
|
114
|
+
assert_not_nil(received.headers["message-id"], "message ID should be present")
|
115
|
+
#
|
116
|
+
assert_nothing_raised() {
|
117
|
+
@conn.ack(received.headers["message-id"]) if ackmode == "client"
|
118
|
+
}
|
119
|
+
received
|
120
|
+
end
|
121
|
+
|
122
|
+
end # of class
|
123
|
+
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'stomp'
|
3
|
+
#
|
4
|
+
require 'test/unit'
|
5
|
+
$:.unshift File.dirname(__FILE__)
|
6
|
+
require 'test_0000_base'
|
7
|
+
#
|
8
|
+
# Basic connection tests.
|
9
|
+
#
|
10
|
+
class Test_0030_Subscr_Id < Test_0000_Base
|
11
|
+
|
12
|
+
# Setup
|
13
|
+
def setup
|
14
|
+
super
|
15
|
+
open_conn()
|
16
|
+
end
|
17
|
+
|
18
|
+
# Teardown
|
19
|
+
def teardown
|
20
|
+
disconnect_conn()
|
21
|
+
end
|
22
|
+
|
23
|
+
# Sanity check parameters
|
24
|
+
def test_0000_params
|
25
|
+
check_parms()
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
# Make sure we get 'subscription' header back from the server
|
30
|
+
def test_0010_subscribe_with_id
|
31
|
+
qname = "/queue/subscr/id/a.b"
|
32
|
+
send_message = "Subscribe with ID check message"
|
33
|
+
sub_id = "id-0010"
|
34
|
+
@conn.publish(qname,send_message)
|
35
|
+
@conn.subscribe(qname, {'id' => 'id-0010'})
|
36
|
+
#
|
37
|
+
rec_message = @conn.receive
|
38
|
+
assert_not_nil rec_message
|
39
|
+
assert_not_nil rec_message.headers['subscription']
|
40
|
+
assert_equal sub_id, rec_message.headers['subscription']
|
41
|
+
end
|
42
|
+
|
43
|
+
end # of class
|
44
|
+
|