ruote-stomp 2.2.0.a
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.txt +10 -0
- data/CREDITS.txt +32 -0
- data/PostInstall.txt +12 -0
- data/README.rdoc +77 -0
- data/Rakefile +101 -0
- data/TODO.txt +4 -0
- data/lib/ruote-stomp/launchitem_listener.rb +22 -0
- data/lib/ruote-stomp/participant.rb +225 -0
- data/lib/ruote-stomp/receiver.rb +156 -0
- data/lib/ruote-stomp/version.rb +6 -0
- data/lib/ruote-stomp/workitem_listener.rb +12 -0
- data/lib/ruote-stomp.rb +96 -0
- data/ruote-stomp.gemspec +34 -0
- data/spec/launchitem_listener_spec.rb +68 -0
- data/spec/participant_spec.rb +208 -0
- data/spec/participant_spec_kit.rb +192 -0
- data/spec/receiver_spec.rb +142 -0
- data/spec/receiver_spec_kit.rb +126 -0
- data/spec/ruote_stomp_spec.rb +18 -0
- data/spec/spec_helper.rb +96 -0
- data/spec/support/ruote_helpers.rb +29 -0
- data/spec/support/ruote_matchers.rb +51 -0
- data/spec/workitem_listener_spec.rb +74 -0
- data/spec/workitem_listener_spec_kit.rb +66 -0
- metadata +171 -0
@@ -0,0 +1,192 @@
|
|
1
|
+
|
2
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
3
|
+
|
4
|
+
|
5
|
+
describe RuoteStomp::ParticipantProxy, :type => :ruote do
|
6
|
+
|
7
|
+
it "supports 'forget' as participant attribute" do
|
8
|
+
|
9
|
+
pdef = ::Ruote.process_definition :name => 'test' do
|
10
|
+
sequence do
|
11
|
+
stomp :queue => 'test1', :forget => true
|
12
|
+
echo 'done.'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
@engine.register_participant(:stomp, RuoteStomp::ParticipantProxy)
|
17
|
+
|
18
|
+
run_definition(pdef)
|
19
|
+
|
20
|
+
@tracer.to_s.should == 'done.'
|
21
|
+
|
22
|
+
begin
|
23
|
+
Timeout::timeout(10) do
|
24
|
+
@msg = nil
|
25
|
+
MQ.queue('test1', :durable => true).subscribe { |msg| @msg = msg }
|
26
|
+
|
27
|
+
loop do
|
28
|
+
break unless @msg.nil?
|
29
|
+
sleep 0.1
|
30
|
+
end
|
31
|
+
end
|
32
|
+
rescue Timeout::Error
|
33
|
+
violated "Timeout waiting for message"
|
34
|
+
end
|
35
|
+
|
36
|
+
@msg.should match(/^\{.*\}$/) # JSON message by default
|
37
|
+
end
|
38
|
+
|
39
|
+
it "supports 'forget' as participant option" do
|
40
|
+
|
41
|
+
pdef = ::Ruote.process_definition :name => 'test' do
|
42
|
+
sequence do
|
43
|
+
stomp :queue => 'test4'
|
44
|
+
echo 'done.'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
@engine.register_participant(
|
49
|
+
:stomp, RuoteStomp::ParticipantProxy, 'forget' => true)
|
50
|
+
|
51
|
+
run_definition(pdef)
|
52
|
+
|
53
|
+
@tracer.to_s.should == "done."
|
54
|
+
|
55
|
+
begin
|
56
|
+
Timeout::timeout(5) do
|
57
|
+
@msg = nil
|
58
|
+
MQ.queue('test4', :durable => true).subscribe { |msg| @msg = msg }
|
59
|
+
|
60
|
+
loop do
|
61
|
+
break unless @msg.nil?
|
62
|
+
sleep 0.1
|
63
|
+
end
|
64
|
+
end
|
65
|
+
rescue Timeout::Error
|
66
|
+
violated "Timeout waiting for message"
|
67
|
+
end
|
68
|
+
|
69
|
+
@msg.should match(/^\{.*\}$/) # JSON message by default
|
70
|
+
end
|
71
|
+
|
72
|
+
it "supports custom messages instead of workitems" do
|
73
|
+
|
74
|
+
pdef = ::Ruote.process_definition :name => 'test' do
|
75
|
+
sequence do
|
76
|
+
stomp :queue => 'test2', :message => 'foo', :forget => true
|
77
|
+
echo 'done.'
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
@engine.register_participant(:stomp, RuoteStomp::ParticipantProxy)
|
82
|
+
|
83
|
+
run_definition(pdef)
|
84
|
+
|
85
|
+
@tracer.to_s.should == "done."
|
86
|
+
|
87
|
+
begin
|
88
|
+
Timeout::timeout(5) do
|
89
|
+
@msg = nil
|
90
|
+
MQ.queue('test2', :durable => true).subscribe { |msg| @msg = msg }
|
91
|
+
|
92
|
+
loop do
|
93
|
+
break unless @msg.nil?
|
94
|
+
sleep 0.1
|
95
|
+
end
|
96
|
+
end
|
97
|
+
rescue Timeout::Error
|
98
|
+
violated "Timeout waiting for message"
|
99
|
+
end
|
100
|
+
|
101
|
+
@msg.should == 'foo'
|
102
|
+
end
|
103
|
+
|
104
|
+
it "supports 'queue' as a participant option" do
|
105
|
+
|
106
|
+
pdef = ::Ruote.process_definition :name => 'test' do
|
107
|
+
sequence do
|
108
|
+
stomp :forget => true
|
109
|
+
echo 'done.'
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
@engine.register_participant(
|
114
|
+
:stomp, RuoteStomp::ParticipantProxy, 'queue' => 'test5')
|
115
|
+
|
116
|
+
run_definition(pdef)
|
117
|
+
|
118
|
+
@tracer.to_s.should == 'done.'
|
119
|
+
|
120
|
+
begin
|
121
|
+
Timeout::timeout(5) do
|
122
|
+
@msg = nil
|
123
|
+
MQ.queue('test5', :durable => true).subscribe { |msg| @msg = msg }
|
124
|
+
|
125
|
+
loop do
|
126
|
+
break unless @msg.nil?
|
127
|
+
sleep 0.1
|
128
|
+
end
|
129
|
+
end
|
130
|
+
rescue Timeout::Error
|
131
|
+
violated "Timeout waiting for message"
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
it "passes 'participant_options' over stomp" do
|
136
|
+
|
137
|
+
pdef = ::Ruote.process_definition :name => 'test' do
|
138
|
+
stomp :queue => 'test6', :forget => true
|
139
|
+
end
|
140
|
+
|
141
|
+
@engine.register_participant(:stomp, RuoteStomp::ParticipantProxy)
|
142
|
+
|
143
|
+
run_definition(pdef)
|
144
|
+
|
145
|
+
msg = nil
|
146
|
+
|
147
|
+
begin
|
148
|
+
Timeout::timeout(10) do
|
149
|
+
|
150
|
+
MQ.queue('test6', :durable => true).subscribe { |m| msg = m }
|
151
|
+
|
152
|
+
loop do
|
153
|
+
break unless msg.nil?
|
154
|
+
sleep 0.1
|
155
|
+
end
|
156
|
+
end
|
157
|
+
rescue Timeout::Error
|
158
|
+
violated "Timeout waiting for message"
|
159
|
+
end
|
160
|
+
|
161
|
+
wi = Rufus::Json.decode(msg)
|
162
|
+
params = wi['fields']['params']
|
163
|
+
|
164
|
+
params['queue'].should == 'test6'
|
165
|
+
params['forget'].should == true
|
166
|
+
params['participant_options'].should == { 'forget' => false, 'queue' => nil }
|
167
|
+
end
|
168
|
+
|
169
|
+
it "doesn't create 1 queue instance per delivery" do
|
170
|
+
|
171
|
+
pdef = ::Ruote.process_definition do
|
172
|
+
stomp :queue => 'test7', :forget => true
|
173
|
+
end
|
174
|
+
|
175
|
+
mq_count = 0
|
176
|
+
ObjectSpace.each_object(MQ) { |o| mq_count += 1 }
|
177
|
+
|
178
|
+
@engine.register_participant(:stomp, RuoteStomp::ParticipantProxy)
|
179
|
+
|
180
|
+
10.times do
|
181
|
+
run_definition(pdef)
|
182
|
+
end
|
183
|
+
|
184
|
+
sleep 1
|
185
|
+
|
186
|
+
count = 0
|
187
|
+
ObjectSpace.each_object(MQ) { |o| count += 1 }
|
188
|
+
|
189
|
+
count.should == mq_count + 1
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
@@ -0,0 +1,142 @@
|
|
1
|
+
|
2
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
3
|
+
|
4
|
+
require 'ruote/participant'
|
5
|
+
|
6
|
+
|
7
|
+
describe RuoteStomp::Receiver do
|
8
|
+
|
9
|
+
after(:each) do
|
10
|
+
purge_engine
|
11
|
+
end
|
12
|
+
|
13
|
+
it "handles replies" do
|
14
|
+
|
15
|
+
pdef = Ruote.process_definition :name => 'test' do
|
16
|
+
set :field => 'foo', :value => 'foo'
|
17
|
+
sequence do
|
18
|
+
echo '${f:foo}'
|
19
|
+
stomp :queue => '/queue/test3'
|
20
|
+
echo '${f:foo}'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
@engine.register_participant(:stomp, RuoteStomp::ParticipantProxy)
|
25
|
+
|
26
|
+
RuoteStomp::Receiver.new(@engine)
|
27
|
+
|
28
|
+
wfid = @engine.launch(pdef)
|
29
|
+
|
30
|
+
workitem = nil
|
31
|
+
|
32
|
+
begin
|
33
|
+
Timeout::timeout(5) do
|
34
|
+
|
35
|
+
# MQ.queue('test3', :durable => true).subscribe { |msg|
|
36
|
+
# wi = Ruote::Workitem.new(Rufus::Json.decode(msg))
|
37
|
+
# workitem = wi if wi.wfid == wfid
|
38
|
+
# }
|
39
|
+
|
40
|
+
$stomp.subscribe("/queue/test3", {}) do |message|
|
41
|
+
wi = Ruote::Workitem.new(Rufus::Json.decode(message.body))
|
42
|
+
workitem = wi if wi.wfid == wfid
|
43
|
+
end
|
44
|
+
|
45
|
+
loop do
|
46
|
+
break unless workitem.nil?
|
47
|
+
sleep 0.1
|
48
|
+
end
|
49
|
+
end
|
50
|
+
rescue Timeout::Error
|
51
|
+
fail "Timeout waiting for message"
|
52
|
+
end
|
53
|
+
|
54
|
+
workitem.fields['foo'] = "bar"
|
55
|
+
|
56
|
+
#MQ.queue('ruote_workitems', :durable => true).publish(Rufus::Json.encode(workitem.to_h), :persistent => true)
|
57
|
+
$stomp.publish '/queue/ruote_workitems',
|
58
|
+
Rufus::Json.encode(workitem.to_h),
|
59
|
+
{ :persistent => true }
|
60
|
+
@engine.wait_for(wfid)
|
61
|
+
|
62
|
+
@engine.should_not have_errors
|
63
|
+
@engine.should_not have_remaining_expressions
|
64
|
+
|
65
|
+
@tracer.to_s.should == "foo\nbar"
|
66
|
+
end
|
67
|
+
|
68
|
+
it "launches processes" do
|
69
|
+
|
70
|
+
json = {
|
71
|
+
'definition' => %{
|
72
|
+
Ruote.process_definition :name => 'test' do
|
73
|
+
sequence do
|
74
|
+
echo '${f:foo}'
|
75
|
+
end
|
76
|
+
end
|
77
|
+
},
|
78
|
+
'fields' => { 'foo' => 'bar' }
|
79
|
+
}.to_json
|
80
|
+
|
81
|
+
RuoteStomp::Receiver.new(@engine, :launchitems => true, :unsubscribe => true)
|
82
|
+
|
83
|
+
# MQ.queue(
|
84
|
+
# 'ruote_workitems', :durable => true
|
85
|
+
# ).publish(
|
86
|
+
# json, :persistent => true
|
87
|
+
# )
|
88
|
+
|
89
|
+
$stomp.publish '/queue/ruote_workitems', json, { :persistent => true }
|
90
|
+
|
91
|
+
|
92
|
+
sleep 0.5
|
93
|
+
|
94
|
+
@engine.should_not have_errors
|
95
|
+
@engine.should_not have_remaining_expressions
|
96
|
+
|
97
|
+
@tracer.to_s.should == 'bar'
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'accepts a custom :queue' do
|
101
|
+
|
102
|
+
RuoteStomp::Receiver.new(
|
103
|
+
@engine, :queue => '/queue/mario', :launchitems => true, :unsubscribe => true)
|
104
|
+
|
105
|
+
@engine.register_participant 'alpha', Ruote::StorageParticipant
|
106
|
+
|
107
|
+
json = Rufus::Json.encode({
|
108
|
+
'definition' => "Ruote.define { alpha }"
|
109
|
+
})
|
110
|
+
|
111
|
+
# MQ.queue(
|
112
|
+
# 'ruote_workitems', :durable => true
|
113
|
+
# ).publish(
|
114
|
+
# json, :persistent => true
|
115
|
+
# )
|
116
|
+
|
117
|
+
$stomp.publish '/queue/ruote_workitems',
|
118
|
+
json,
|
119
|
+
{ :persistent => true }
|
120
|
+
|
121
|
+
sleep 1
|
122
|
+
|
123
|
+
@engine.processes.size.should == 0
|
124
|
+
# nothing happened
|
125
|
+
|
126
|
+
# MQ.queue(
|
127
|
+
# 'mario', :durable => true
|
128
|
+
# ).publish(
|
129
|
+
# json, :persistent => true
|
130
|
+
# )
|
131
|
+
|
132
|
+
$stomp.publish '/queue/mario',
|
133
|
+
json,
|
134
|
+
{ :persistent => true }
|
135
|
+
|
136
|
+
sleep 1
|
137
|
+
|
138
|
+
@engine.processes.size.should == 1
|
139
|
+
# launch happened
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
@@ -0,0 +1,126 @@
|
|
1
|
+
|
2
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
3
|
+
|
4
|
+
require 'ruote/participant'
|
5
|
+
|
6
|
+
|
7
|
+
describe RuoteStomp::Receiver do
|
8
|
+
|
9
|
+
after(:each) do
|
10
|
+
purge_engine
|
11
|
+
end
|
12
|
+
|
13
|
+
it "handles replies" do
|
14
|
+
|
15
|
+
pdef = Ruote.process_definition :name => 'test' do
|
16
|
+
set :field => 'foo', :value => 'foo'
|
17
|
+
sequence do
|
18
|
+
echo '${f:foo}'
|
19
|
+
stomp :queue => 'test3'
|
20
|
+
echo '${f:foo}'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
@engine.register_participant(:stomp, RuoteStomp::ParticipantProxy)
|
25
|
+
|
26
|
+
RuoteStomp::Receiver.new(@engine)
|
27
|
+
|
28
|
+
wfid = @engine.launch(pdef)
|
29
|
+
|
30
|
+
workitem = nil
|
31
|
+
|
32
|
+
begin
|
33
|
+
Timeout::timeout(5) do
|
34
|
+
|
35
|
+
MQ.queue('test3', :durable => true).subscribe { |msg|
|
36
|
+
wi = Ruote::Workitem.new(Rufus::Json.decode(msg))
|
37
|
+
workitem = wi if wi.wfid == wfid
|
38
|
+
}
|
39
|
+
|
40
|
+
loop do
|
41
|
+
break unless workitem.nil?
|
42
|
+
sleep 0.1
|
43
|
+
end
|
44
|
+
end
|
45
|
+
rescue Timeout::Error
|
46
|
+
violated "Timeout waiting for message"
|
47
|
+
end
|
48
|
+
|
49
|
+
workitem.fields['foo'] = "bar"
|
50
|
+
|
51
|
+
MQ.queue('ruote_workitems', :durable => true).publish(Rufus::Json.encode(workitem.to_h), :persistent => true)
|
52
|
+
|
53
|
+
@engine.wait_for(wfid)
|
54
|
+
|
55
|
+
@engine.should_not have_errors
|
56
|
+
@engine.should_not have_remaining_expressions
|
57
|
+
|
58
|
+
@tracer.to_s.should == "foo\nbar"
|
59
|
+
end
|
60
|
+
|
61
|
+
it "launches processes" do
|
62
|
+
|
63
|
+
json = {
|
64
|
+
'definition' => %{
|
65
|
+
Ruote.process_definition :name => 'test' do
|
66
|
+
sequence do
|
67
|
+
echo '${f:foo}'
|
68
|
+
end
|
69
|
+
end
|
70
|
+
},
|
71
|
+
'fields' => { 'foo' => 'bar' }
|
72
|
+
}.to_json
|
73
|
+
|
74
|
+
RuoteStomp::Receiver.new(@engine, :launchitems => true, :unsubscribe => true)
|
75
|
+
|
76
|
+
MQ.queue(
|
77
|
+
'ruote_workitems', :durable => true
|
78
|
+
).publish(
|
79
|
+
json, :persistent => true
|
80
|
+
)
|
81
|
+
|
82
|
+
sleep 0.5
|
83
|
+
|
84
|
+
@engine.should_not have_errors
|
85
|
+
@engine.should_not have_remaining_expressions
|
86
|
+
|
87
|
+
@tracer.to_s.should == 'bar'
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'accepts a custom :queue' do
|
91
|
+
|
92
|
+
#@engine.noisy = true
|
93
|
+
|
94
|
+
RuoteStomp::Receiver.new(
|
95
|
+
@engine, :queue => 'mario', :launchitems => true, :unsubscribe => true)
|
96
|
+
|
97
|
+
@engine.register_participant 'alpha', Ruote::StorageParticipant
|
98
|
+
|
99
|
+
json = Rufus::Json.encode({
|
100
|
+
'definition' => "Ruote.define { alpha }"
|
101
|
+
})
|
102
|
+
|
103
|
+
MQ.queue(
|
104
|
+
'ruote_workitems', :durable => true
|
105
|
+
).publish(
|
106
|
+
json, :persistent => true
|
107
|
+
)
|
108
|
+
|
109
|
+
sleep 1
|
110
|
+
|
111
|
+
@engine.processes.size.should == 0
|
112
|
+
# nothing happened
|
113
|
+
|
114
|
+
MQ.queue(
|
115
|
+
'mario', :durable => true
|
116
|
+
).publish(
|
117
|
+
json, :persistent => true
|
118
|
+
)
|
119
|
+
|
120
|
+
sleep 1
|
121
|
+
|
122
|
+
@engine.processes.size.should == 1
|
123
|
+
# launch happened
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|