nebulous_stomp 2.0.1 → 2.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.hgtags +1 -0
- data/lib/nebulous_stomp/nebrequest.rb +32 -23
- data/lib/nebulous_stomp/redis_handler.rb +6 -2
- data/lib/nebulous_stomp/stomp_handler.rb +19 -11
- data/lib/nebulous_stomp/version.rb +1 -1
- data/md/nebulous_protocol.md +113 -139
- data/spec/nebrequest_null_spec.rb +10 -9
- data/spec/nebrequest_spec.rb +6 -6
- data/spec/stomp_handler_spec.rb +0 -1
- data/spec/through_test_spec.rb +3 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a4ac7c514b6d925e6186924b2dd93a175de94e02
|
4
|
+
data.tar.gz: 8aca7aa180be4c84fe6ccbe89b172980cd2a56a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: abb4de512e2aec3d8720505f9f06d7a00b2d5aa4caba2a1e9dab977f6c36cb6970f791289509cc6fbe96b945d6eeec84a65d7fe86b54d7402b97104dcd71c18d
|
7
|
+
data.tar.gz: 3e44c452fa7f94cd331cfc637b90b427c5171bd7fa9663b4ebe5118320e8d1ea8554628b57bcecfcc55cbc2f7f69aed9d13f49951c8e1ce82836db55cb7b26d5
|
data/.hgtags
CHANGED
@@ -18,18 +18,6 @@ module NebulousStomp
|
|
18
18
|
# The target name as set up by call to Nebulous::add_target
|
19
19
|
attr_reader :target
|
20
20
|
|
21
|
-
# The 'verb' part of the message
|
22
|
-
attr_reader :verb
|
23
|
-
|
24
|
-
# The 'parameters' part of the message
|
25
|
-
attr_reader :params
|
26
|
-
|
27
|
-
# The 'description' part of the message
|
28
|
-
attr_reader :desc
|
29
|
-
|
30
|
-
# The 'replyID' header to use in this message
|
31
|
-
attr_reader :replyID
|
32
|
-
|
33
21
|
# Message timeout in seconds
|
34
22
|
attr_reader :mTimeout
|
35
23
|
|
@@ -73,21 +61,23 @@ module NebulousStomp
|
|
73
61
|
NebulousStomp.logger.debug(__FILE__) {"New NebRequest for verb #{verb}"}
|
74
62
|
|
75
63
|
@target = target.to_s
|
76
|
-
@verb = verb.to_s
|
77
|
-
@params = params.nil? ? nil : params.to_s
|
78
|
-
@desc = desc.nil? ? nil : desc.to_s
|
79
64
|
@stomp_handler = stompHandler
|
80
65
|
@redis_handler = redisHandler
|
81
66
|
@requestQ = nil
|
82
67
|
@responseQ = nil
|
83
68
|
@message = nil
|
84
|
-
@replyID = nil
|
85
69
|
@mTimeout = 0
|
86
70
|
@cTimeout = 0
|
87
71
|
|
72
|
+
xverb = verb.to_s
|
73
|
+
xparams = params.nil? ? nil : params.to_s
|
74
|
+
xdesc = desc.nil? ? nil : desc.to_s
|
75
|
+
|
88
76
|
@redis_handler ||= RedisHandler.new( Param.get(:redisConnectHash) )
|
89
77
|
@stomp_handler ||= StompHandler.new( Param.get(:stompConnectHash) )
|
90
78
|
|
79
|
+
neb_setup if nebulous_on?
|
80
|
+
@message = Message.from_parts(@responseQ, nil, xverb, xparams, xdesc)
|
91
81
|
neb_connect if nebulous_on?
|
92
82
|
end
|
93
83
|
|
@@ -112,7 +102,7 @@ module NebulousStomp
|
|
112
102
|
|
113
103
|
# If we've lost the connection then reconnect but *keep replyID*
|
114
104
|
@stomp_handler.stomp_connect unless @stomp_handler.connected?
|
115
|
-
@
|
105
|
+
@message.reply_id = @stomp_handler.calc_reply_id if @message.reply_id.nil?
|
116
106
|
|
117
107
|
neb_qna(mTimeout)
|
118
108
|
|
@@ -201,14 +191,23 @@ module NebulousStomp
|
|
201
191
|
end
|
202
192
|
|
203
193
|
|
194
|
+
#
|
195
|
+
# Some of our attributes are actually on Message
|
196
|
+
#
|
197
|
+
|
198
|
+
def verb; @message ? @message.verb : nil; end
|
199
|
+
def params; @message ? @message.params : nil; end
|
200
|
+
def desc; @message ? @message.desc : nil; end
|
201
|
+
def replyID; @message ? @message.reply_id : nil; end
|
202
|
+
|
203
|
+
|
204
204
|
private
|
205
205
|
|
206
206
|
|
207
207
|
##
|
208
208
|
# Connect to STOMP etc and do initial setup
|
209
|
-
# Called automatically by initialize, if Nebulous is 'on' in the config.
|
210
209
|
#
|
211
|
-
def
|
210
|
+
def neb_setup
|
212
211
|
targetHash = Param.get_target(@target)
|
213
212
|
raise NebulousError, "Unknown target #{target}" if targetHash.nil?
|
214
213
|
|
@@ -216,11 +215,16 @@ module NebulousStomp
|
|
216
215
|
@mTimeout = targetHash[:messageTimeout] || Param.get(:messageTimeout)
|
217
216
|
@requestQ = targetHash[:sendQueue]
|
218
217
|
@responseQ = targetHash[:receiveQueue]
|
219
|
-
@message = Message.from_parts(@responseQ, nil, verb, params, desc)
|
220
218
|
|
221
|
-
|
222
|
-
|
219
|
+
self
|
220
|
+
end
|
223
221
|
|
222
|
+
|
223
|
+
# Called automatically by initialize, if Nebulous is 'on' in the config.
|
224
|
+
#
|
225
|
+
def neb_connect
|
226
|
+
@stomp_handler.stomp_connect
|
227
|
+
@message.reply_id = @stomp_handler.calc_reply_id
|
224
228
|
self
|
225
229
|
end
|
226
230
|
|
@@ -236,7 +240,12 @@ module NebulousStomp
|
|
236
240
|
|
237
241
|
response = nil
|
238
242
|
@stomp_handler.listen_with_timeout(@responseQ, mTimeout) do |msg|
|
239
|
-
|
243
|
+
if replyID && msg.in_reply_to != replyID
|
244
|
+
false
|
245
|
+
else
|
246
|
+
response = msg
|
247
|
+
true
|
248
|
+
end
|
240
249
|
end
|
241
250
|
|
242
251
|
response
|
@@ -17,11 +17,15 @@ module NebulousStomp
|
|
17
17
|
##
|
18
18
|
# Initialise an instance of the handler by passing it the connection hash
|
19
19
|
#
|
20
|
+
# If no hash is passed, we try and get it from Nebulous::Params
|
21
|
+
#
|
20
22
|
# We use the optional testRedis parameter to mock connections to Redis, for
|
21
23
|
# testing. It's probably of no use to anyone else.
|
22
24
|
#
|
23
|
-
def initialize(connectHash, testRedis=nil)
|
24
|
-
@redis_hash
|
25
|
+
def initialize(connectHash=nil, testRedis=nil)
|
26
|
+
@redis_hash = connectHash ? connectHash.dup : nil
|
27
|
+
@redis_hash ||= Param.get(:redisConnectHash)
|
28
|
+
|
25
29
|
@test_redis = testRedis
|
26
30
|
@redis = nil
|
27
31
|
end
|
@@ -110,10 +110,14 @@ module NebulousStomp
|
|
110
110
|
|
111
111
|
##
|
112
112
|
# Initialise StompHandler by passing the parameter hash.
|
113
|
+
#
|
114
|
+
# If no hash is set we try and get it from NebulousStomp::Param.
|
113
115
|
# ONLY set testClient when testing.
|
114
116
|
#
|
115
|
-
def initialize(connectHash, testClient=nil)
|
116
|
-
@stomp_hash
|
117
|
+
def initialize(connectHash=nil, testClient=nil)
|
118
|
+
@stomp_hash = connectHash ? connectHash.dup : nil
|
119
|
+
@stomp_hash ||= Param.get(:stompConnectHash)
|
120
|
+
|
117
121
|
@test_client = testClient
|
118
122
|
@client = nil
|
119
123
|
end
|
@@ -207,11 +211,13 @@ module NebulousStomp
|
|
207
211
|
##
|
208
212
|
# As listen() but give up after yielding a single message, and only wait
|
209
213
|
# for a set number of seconds before giving up anyway.
|
210
|
-
|
211
|
-
#
|
212
|
-
#
|
213
|
-
#
|
214
|
-
|
214
|
+
#
|
215
|
+
# The behaviour here is slightly different than listen(). If you return true from your block,
|
216
|
+
# the message will be consumed and the method will end. Otherwise it will continue until it
|
217
|
+
# sees another message, or reaches the timeout.
|
218
|
+
#
|
219
|
+
# Put another way, since most things are truthy -- if you want to examine messages to find the
|
220
|
+
# right one, return false from the block to get another.
|
215
221
|
#
|
216
222
|
def listen_with_timeout(queue, timeout)
|
217
223
|
return unless nebulous_on?
|
@@ -230,11 +236,13 @@ module NebulousStomp
|
|
230
236
|
@client.subscribe( queue, {ack: "client-individual"} ) do |msg|
|
231
237
|
|
232
238
|
begin
|
233
|
-
|
234
|
-
|
235
|
-
|
239
|
+
if msg.body == "boo"
|
240
|
+
@client.ack(msg)
|
241
|
+
else
|
242
|
+
done = yield Message.from_stomp(msg)
|
243
|
+
@client.ack(msg) if done
|
236
244
|
end
|
237
|
-
|
245
|
+
|
238
246
|
rescue =>e
|
239
247
|
NebulousStomp.logger.error(__FILE__) {"Error during polling: #{e}" }
|
240
248
|
end
|
data/md/nebulous_protocol.md
CHANGED
@@ -1,59 +1,51 @@
|
|
1
1
|
Nebulous: The Protocol
|
2
2
|
======================
|
3
3
|
|
4
|
-
(It was going to be "The Nebulous Protocol", but that sounds like something with
|
5
|
-
Matt Damon in it.)
|
4
|
+
(It was going to be "The Nebulous Protocol", but that sounds like something with Matt Damon in it.)
|
6
5
|
|
7
6
|
|
8
7
|
Introduction
|
9
8
|
------------
|
10
|
-
Project Nebulous is a STOMP client written in ABL, and also the protocol that
|
11
|
-
|
12
|
-
obviously, concentrates on the protocol.
|
9
|
+
Project Nebulous is a STOMP client written in ABL, and also the protocol that allows our different
|
10
|
+
systems, ABL or not, to pass messages. This document, obviously, concentrates on the protocol.
|
13
11
|
|
14
|
-
The basic idea is this: one system passes a message, a _request_; and then
|
15
|
-
|
16
|
-
|
12
|
+
The basic idea is this: one system passes a message, a _request_; and then waits for an answer to
|
13
|
+
that message, a _response_, from another system. STOMP doesn't explicitly support that; the
|
14
|
+
protocol does it.
|
17
15
|
|
18
|
-
(Note that a request and a response are just notional terms; you might in
|
19
|
-
|
20
|
-
|
21
|
-
and the terms get rather less useful.)
|
16
|
+
(Note that a request and a response are just notional terms; you might in theory have a request
|
17
|
+
which provokes a response which provokes another response in return, in which case the second
|
18
|
+
message is both a response and a request, and the terms get rather less useful.)
|
22
19
|
|
23
20
|
|
24
21
|
The Protocol
|
25
22
|
------------
|
26
|
-
Let's start with the actual protocol, the rules. They won't make sense without
|
27
|
-
reading the rest of the document, but:
|
23
|
+
Let's start with the actual protocol, the rules. They won't make sense without reading the rest of the document, but:
|
28
24
|
|
29
|
-
1. Every valid request (that is, every message with an identifiable verb other
|
30
|
-
|
31
|
-
|
32
|
-
the verb
|
33
|
-
response is required, you should still receive the success verb.
|
25
|
+
1. Every valid request (that is, every message with an identifiable verb other than "success" or
|
26
|
+
"error") will always generate a response. If the handling routine cannot generate a valid
|
27
|
+
response, or if there is no routine to handle the verb in question, then the response should be
|
28
|
+
the error verb. If no response is required, you should still receive the success verb.
|
34
29
|
|
35
|
-
2. You should expect that requests that do not have a verb will not be responded
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
response is outside the remit of The Protocol.)
|
30
|
+
2. You should expect that requests that do not have a verb will not be responded to or even
|
31
|
+
understood. (However, there is no general requirement for message bodies to follow the verb /
|
32
|
+
parameters / description format. If you have a program that sends a request and waits for a
|
33
|
+
response, the format of that response is outside the remit of The Protocol.)
|
40
34
|
|
41
|
-
3. If a request has the _neb-reply-to_ header, the response should use that as
|
42
|
-
|
43
|
-
request was sent to.
|
35
|
+
3. If a request has the _neb-reply-to_ header, the response should use that as a destination;
|
36
|
+
otherwise it should be sent to the same destination that the request was sent to.
|
44
37
|
|
45
|
-
4. If the request has a _neb-reply-id_ header, then the response should set the
|
46
|
-
|
38
|
+
4. If the request has a _neb-reply-id_ header, then the response should set the _neb-in-reply-to_
|
39
|
+
header to that.
|
47
40
|
|
48
|
-
5. The request may specify the content type of a response (JSON or text) by
|
49
|
-
|
50
|
-
|
41
|
+
5. The request may specify the content type of a response (JSON or text) by it's own content type.
|
42
|
+
That is, if a response can be in either form, it should take the form of the request as an
|
43
|
+
indication as which to use.
|
51
44
|
|
52
|
-
6. A given queue that is the target of requests within The Protocol will be for
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
consumed from it at random.
|
45
|
+
6. A given queue that is the target of requests within The Protocol will be for only one system or
|
46
|
+
common group of systems. They may consume (ACK) messages sent to it even if they do not have the
|
47
|
+
facility to process them. If multiple systems share a queue, they should understand that
|
48
|
+
messages will be consumed from it at random.
|
57
49
|
|
58
50
|
|
59
51
|
Components
|
@@ -64,130 +56,112 @@ By way of an explanation of the above section.
|
|
64
56
|
|
65
57
|
STOMP allows you to define custom headers. We have three.
|
66
58
|
|
67
|
-
* _neb-reply-to_ is may be set on a request to the destination that any
|
68
|
-
|
59
|
+
* _neb-reply-to_ is may be set on a request to the destination that any response should be posted
|
60
|
+
to. (See rule 3.)
|
69
61
|
|
70
|
-
* _neb-reply-id_ may be set on a request to an arbitrary string to help
|
71
|
-
you identify the response.
|
62
|
+
* _neb-reply-id_ may be set on a request to an arbitrary string to help you identify the response.
|
72
63
|
|
73
|
-
* _neb-in-reply-to_ is set on a response and contains the
|
74
|
-
of the request.
|
64
|
+
* _neb-in-reply-to_ is set on a response and contains the neb-reply-id of the request. (see rule 4.)
|
75
65
|
|
76
66
|
### Message Body ###
|
77
67
|
|
78
|
-
The Protocol specifies a format for the message body. It consists of three
|
79
|
-
fields:
|
68
|
+
The Protocol specifies a format for the message body. It consists of three fields:
|
80
69
|
|
81
|
-
* _verb_ is the keyword that tells the receiving system how to process the
|
82
|
-
message.
|
70
|
+
* _verb_ is the keyword that tells the receiving system how to process the message.
|
83
71
|
|
84
|
-
* _parameters_ is an arbitrary field that is context-dependant on verb. The
|
85
|
-
|
86
|
-
optional.
|
72
|
+
* _parameters_ is an arbitrary field that is context-dependant on verb. The routine that handles
|
73
|
+
the verb is expected to be able to parse it. It is optional.
|
87
74
|
|
88
75
|
* _description_ is a text field and can contain anything. It is optional.
|
89
76
|
|
90
|
-
Nebulous supports message bodies in either JSON (in which case parameters is an
|
91
|
-
|
92
|
-
|
93
|
-
consists of the field name, a colon, and the value).
|
77
|
+
Nebulous supports message bodies in either JSON (in which case parameters is probably an array) or
|
78
|
+
plain text (in which case it expects to find the fields formatted in the same way as STOMP headers:
|
79
|
+
seperated by line breaks, where each line consists of the field name, a colon, and the value).
|
94
80
|
|
95
81
|
There are a couple of special verbs:
|
96
82
|
|
97
|
-
* _success_ as a verb in a response is used when no information needs to be
|
98
|
-
|
83
|
+
* _success_ as a verb in a response is used when no information needs to be returned except that
|
84
|
+
the request operation went ahead without problem.
|
99
85
|
|
100
|
-
* _error_ as a verb is used when the requested operation failed. The
|
101
|
-
|
102
|
-
you can use parameters as you see fit, of course.
|
86
|
+
* _error_ as a verb is used when the requested operation failed. The expectation is that you will
|
87
|
+
put an error message in the description field; you can use parameters as you see fit, of course.
|
103
88
|
|
104
89
|
|
105
90
|
Notes on usage
|
106
91
|
--------------
|
107
|
-
|
108
|
-
|
109
|
-
second (let's call it _Responder_) is at the
|
110
|
-
camps onto one or more queues waiting for requests, and arranges for
|
111
|
-
to be sent.
|
92
|
+
|
93
|
+
There are two use cases here. The first (let's call it _Q & A_) is when a process needs information
|
94
|
+
and sends a request, then waits for a response. The second (let's call it _Responder_) is at the
|
95
|
+
other end of that process; it camps onto one or more queues waiting for requests, and arranges for
|
96
|
+
responses to be sent.
|
112
97
|
|
113
98
|
### Responder ###
|
114
99
|
|
115
|
-
Let's talk about the Responder use case first, since it's simpler; we've
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
combination of verb, expected parameters, and the nature of the returned
|
137
|
-
message form a sort of contract, ie "verb x always expects parameters like
|
138
|
-
this, and always behaves like that in response". This is partly implied by Rule
|
139
|
-
2, I think.
|
100
|
+
Let's talk about the Responder use case first, since it's simpler; we've basically been talking
|
101
|
+
about it for the whole of this document. You'll need to designate a queue for incoming requests on
|
102
|
+
any given system. You might want more than one; in ABL, where traffic jams are likely because I
|
103
|
+
can't just spawn up a thread to handle each incoming message, my current thinking is to have two
|
104
|
+
incoming queues, one for reqests that take a few seconds, and another for requests that take
|
105
|
+
longer.
|
106
|
+
|
107
|
+
Remember that rule 6 says that any messages that go to a queue like this will be consumed without
|
108
|
+
concern for whether the message will make sense to the system in question; this is basically there
|
109
|
+
so that the ABL code can split up the process of grabbing new messages from the process of working
|
110
|
+
out what they are and how to answer them.
|
111
|
+
|
112
|
+
But the simplicity is appealing, regardless: post to this queue and the Responder that looks after
|
113
|
+
this system will process it. Rule 1 guarantees you an answer so long as the system is up, so if you
|
114
|
+
don't get one then either the target system is down or it's too busy to respond.
|
115
|
+
|
116
|
+
The expectation is that the Responder system should use the verb of the message to control how it
|
117
|
+
is dealt with. The parameters field is verb-specific; the combination of verb, expected parameters,
|
118
|
+
and the nature of the returned message form a sort of contract, ie "verb x always expects
|
119
|
+
parameters like this, and always behaves like that in response". This is partly implied by Rule 2,
|
120
|
+
I think.
|
140
121
|
|
141
122
|
### Q & A ###
|
142
123
|
|
143
|
-
The Q & A use case is more interesting since it's what the whole thing is for,
|
144
|
-
|
145
|
-
|
146
|
-
In theory, Rule 3 says you can fail to use _neb-reply-to_ and pick up your
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
that
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
you
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
to
|
185
|
-
|
186
|
-
the same message. I think that to do otherwise would be very confusing. But The
|
187
|
-
Protocol can't enforce that.
|
188
|
-
|
189
|
-
Note also that while The Protocol says that a request should always result in a
|
190
|
-
response, there is nothing to say that the sender of the request should care --
|
191
|
-
say, in the example of a request that results in a report being emailed, which
|
192
|
-
takes 20 minutes.
|
124
|
+
The Q & A use case is more interesting since it's what the whole thing is for, but some of it
|
125
|
+
really falls outside of The Protocol.
|
126
|
+
|
127
|
+
In theory, Rule 3 says you can fail to use _neb-reply-to_ and pick up your response from the same
|
128
|
+
queue you posted the message to. But rule 6 says that if you do that you don't have any guarantee
|
129
|
+
at all of getting your message; the Responder will take it. So for practical purposes you almost
|
130
|
+
always *have* to set a reply-to queue in your request.
|
131
|
+
|
132
|
+
Likewise, Rule 4 says that _neb-reply-id_ is optional. But in practice you should almost certainly
|
133
|
+
set it. Yes, you can specify a brand new queue that is unique to your request -- or probably
|
134
|
+
unique, anyway -- but it turns out that some message servers, our RabbitMQ included, don't let you
|
135
|
+
subscribe to a queue that doesn't exist. It's easy enough to create a queue: you just send a
|
136
|
+
message to it. But now there are two messages in that queue (or more if turns out that you've got
|
137
|
+
some queue namespace collision after all) and you have to pick your response from it, and the
|
138
|
+
easiest way is to set a reply id.
|
139
|
+
|
140
|
+
So let's assume a median worst case: you're posting a request to a Responder queue with a reply-id
|
141
|
+
set to something hopefully unique, and reply-to set to a common queue that many processes use to
|
142
|
+
pick up replies. There are two challenges here: first, working out which message is yours; second,
|
143
|
+
avoiding consuming those messages that are not.
|
144
|
+
|
145
|
+
For a unique reply-id you could do worse than starting with the session ID that STOMP returns when
|
146
|
+
you send a CONNECT frame; clearly the message server thinks that is unique, and it should know. In
|
147
|
+
the Ruby Stomp gem, you can get it with `client.connection_frame().headers["session"]` where client
|
148
|
+
is your `Stomp::Client` instance; in my ABL jhstomp.p library call `get_session_id()`.
|
149
|
+
|
150
|
+
Now that you have a good reply ID you can tell which is yours by Rule 4; just test the
|
151
|
+
_neb-in-reply-to_ header of each message.
|
152
|
+
|
153
|
+
The second problem, of avoiding consuming messages that don't match your reply-id, is handled by
|
154
|
+
careful use of STOMP. If when subscribing you set the header `ack:client-individual`, then you must
|
155
|
+
manually acknowledge each message you want to consume with an ACK frame.
|
156
|
+
|
157
|
+
Finally, you get to handle the response. Rule 1 says that it will either be an error verb, a
|
158
|
+
success verb ... or something else specific to the verb. The nature of messages in responses is
|
159
|
+
really outside of The Protocol; you are free to use the verb / parameters / description format if
|
160
|
+
you wish. Again, I'm assuming that a given verb will always require the same parameters and return
|
161
|
+
the same message. I think that to do otherwise would be very confusing. But The Protocol can't
|
162
|
+
enforce that.
|
163
|
+
|
164
|
+
Note also that while The Protocol says that a request should always result in a response, there is
|
165
|
+
nothing to say that the sender of the request should care -- say, in the example of a request that
|
166
|
+
results in a report being emailed, which takes 20 minutes.
|
193
167
|
|
@@ -14,9 +14,9 @@ describe NebRequestNull do
|
|
14
14
|
|
15
15
|
def disable(thing)
|
16
16
|
NebulousStomp.init( :stompConnectHash => thing == :stomp ? {} : stomp_hash,
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
:redisConnectHash => thing == :redis ? {} : redis_hash,
|
18
|
+
:messageTimeout => 5,
|
19
|
+
:cacheTimeout => 20 )
|
20
20
|
|
21
21
|
NebulousStomp.add_target( :accord,
|
22
22
|
:sendQueue => "/queue/laplace.dev",
|
@@ -36,6 +36,7 @@ describe NebRequestNull do
|
|
36
36
|
|
37
37
|
let(:redis_hash) { {host: '127.0.0.1', port: 6379, db: 0} }
|
38
38
|
|
39
|
+
|
39
40
|
before do
|
40
41
|
disable(:nothing)
|
41
42
|
end
|
@@ -95,7 +96,7 @@ describe NebRequestNull do
|
|
95
96
|
|
96
97
|
it "returns something from STOMP" do
|
97
98
|
req = new_request('accord', 'foo')
|
98
|
-
req.insert_fake_stomp( Message.from_parts(
|
99
|
+
req.insert_fake_stomp( Message.from_parts(nil, req.replyID, 'foo', 'bar', 'baz') )
|
99
100
|
response = req.send_no_cache
|
100
101
|
|
101
102
|
expect( response ).to be_a NebulousStomp::Message
|
@@ -124,7 +125,7 @@ describe NebRequestNull do
|
|
124
125
|
|
125
126
|
it "returns a Message object from STOMP the first time" do
|
126
127
|
req = new_request('accord', 'foo')
|
127
|
-
req.insert_fake_stomp( Message.from_parts(
|
128
|
+
req.insert_fake_stomp( Message.from_parts(nil, req.replyID, 'foo', 'bar', 'baz') )
|
128
129
|
|
129
130
|
response = req.send
|
130
131
|
expect( response ).to be_a NebulousStomp::Message
|
@@ -133,7 +134,7 @@ describe NebRequestNull do
|
|
133
134
|
|
134
135
|
it "returns the answer from the cache if there is one" do
|
135
136
|
req = new_request('accord', 'foo')
|
136
|
-
req.insert_fake_stomp( Message.from_parts(
|
137
|
+
req.insert_fake_stomp( Message.from_parts(nil, req.replyID, 'foo', 'bar', 'baz') )
|
137
138
|
req.insert_fake_redis('xxx', {'verb' => 'frog'}.to_json)
|
138
139
|
response = req.send
|
139
140
|
|
@@ -143,14 +144,14 @@ describe NebRequestNull do
|
|
143
144
|
|
144
145
|
it "allows you to specify a message timeout" do
|
145
146
|
req = new_request('accord', 'foo')
|
146
|
-
req.insert_fake_stomp( Message.from_parts(
|
147
|
+
req.insert_fake_stomp( Message.from_parts(nil, req.replyID, 'foo', 'bar', 'baz') )
|
147
148
|
|
148
149
|
expect{ req.send(3) }.not_to raise_exception
|
149
150
|
end
|
150
151
|
|
151
152
|
it "allows you to specify a message timeout & cache timeout" do
|
152
153
|
req = new_request('accord', 'foo')
|
153
|
-
req.insert_fake_stomp( Message.from_parts(
|
154
|
+
req.insert_fake_stomp( Message.from_parts(nil, req.replyID, 'foo', 'bar', 'baz') )
|
154
155
|
|
155
156
|
expect{ req.send(3, 120) }.not_to raise_exception
|
156
157
|
end
|
@@ -163,7 +164,7 @@ describe NebRequestNull do
|
|
163
164
|
it 'still works if Redis is turned off in the config' do
|
164
165
|
disable(:redis)
|
165
166
|
r = new_request('accord', 'tom')
|
166
|
-
r.insert_fake_stomp( Message.from_parts(
|
167
|
+
r.insert_fake_stomp( Message.from_parts(nil, r.replyID, 'foo', 'bar', 'baz') )
|
167
168
|
|
168
169
|
response = r.send
|
169
170
|
expect( response ).to be_a NebulousStomp::Message
|
data/spec/nebrequest_spec.rb
CHANGED
@@ -104,8 +104,8 @@ describe NebRequest do
|
|
104
104
|
describe "#send_no_cache" do
|
105
105
|
|
106
106
|
it "returns something from STOMP" do
|
107
|
-
stomp_h.insert_fake( Message.from_parts('', '', 'foo', 'bar', 'baz') )
|
108
107
|
request = new_request('accord', 'foo')
|
108
|
+
stomp_h.insert_fake( Message.from_parts(nil, request.replyID, 'foo', 'bar', 'baz') )
|
109
109
|
response = request.send_no_cache
|
110
110
|
|
111
111
|
expect( response ).to be_a NebulousStomp::Message
|
@@ -133,8 +133,8 @@ describe NebRequest do
|
|
133
133
|
describe "#send" do
|
134
134
|
|
135
135
|
it "returns a Message object from STOMP the first time" do
|
136
|
-
stomp_h.insert_fake( Message.from_parts('', '', 'foo', 'bar', 'baz') )
|
137
136
|
request = new_request('accord', 'foo')
|
137
|
+
stomp_h.insert_fake( Message.from_parts(nil, request.replyID, 'foo', 'bar', 'baz') )
|
138
138
|
|
139
139
|
response = request.send
|
140
140
|
expect( response ).to be_a NebulousStomp::Message
|
@@ -142,7 +142,7 @@ describe NebRequest do
|
|
142
142
|
end
|
143
143
|
|
144
144
|
it "returns the answer from the cache the second time" do
|
145
|
-
stomp_h.insert_fake( Message.from_parts(
|
145
|
+
stomp_h.insert_fake( Message.from_parts(nil, nil, 'foo', 'bar', 'baz') )
|
146
146
|
redis_h.insert_fake('xxx', {'verb' => 'frog'}.to_json)
|
147
147
|
|
148
148
|
# First time
|
@@ -158,15 +158,15 @@ describe NebRequest do
|
|
158
158
|
end
|
159
159
|
|
160
160
|
it "allows you to specify a message timeout" do
|
161
|
-
stomp_h.insert_fake( Message.from_parts('', '', 'foo', 'bar', 'baz') )
|
162
161
|
request = new_request('accord', 'foo')
|
162
|
+
stomp_h.insert_fake( Message.from_parts(nil, request.replyID, 'foo', 'bar', 'baz') )
|
163
163
|
|
164
164
|
expect{ request.send(3) }.not_to raise_exception
|
165
165
|
end
|
166
166
|
|
167
167
|
it "allows you to specify a message timeout & cache timeout" do
|
168
|
-
stomp_h.insert_fake( Message.from_parts('', '', 'foo', 'bar', 'baz') )
|
169
168
|
request = new_request('accord', 'foo')
|
169
|
+
stomp_h.insert_fake( Message.from_parts(nil, request.replyID, 'foo', 'bar', 'baz') )
|
170
170
|
|
171
171
|
expect{ request.send(3, 120) }.not_to raise_exception
|
172
172
|
end
|
@@ -178,8 +178,8 @@ describe NebRequest do
|
|
178
178
|
|
179
179
|
it 'still works if Redis is turned off in the config' do
|
180
180
|
rh = RedisHandlerNull.new({})
|
181
|
-
stomp_h.insert_fake( Message.from_parts('', '', 'foo', 'bar', 'baz') )
|
182
181
|
r = NebRequest.new('accord', 'tom', nil, nil, stomp_h, rh)
|
182
|
+
stomp_h.insert_fake( Message.from_parts(nil, r.replyID, 'foo', 'bar', 'baz') )
|
183
183
|
|
184
184
|
response = r.send
|
185
185
|
expect( response ).to be_a NebulousStomp::Message
|
data/spec/stomp_handler_spec.rb
CHANGED
data/spec/through_test_spec.rb
CHANGED
@@ -6,8 +6,9 @@ require 'nebulous_stomp'
|
|
6
6
|
# It's really only here to double check that the Stomp gem hasn't moved the
|
7
7
|
# goalposts (again).
|
8
8
|
#
|
9
|
-
# In order for it to work, the JH RabbitMQ server has to be where we left it.
|
10
|
-
# So this test won't work for you
|
9
|
+
# In order for it to work, the JH RabbitMQ server has to be where we left it. And you need a
|
10
|
+
# responder listening to /queue/nebulout.test for the 'ping' verb. So this test won't work for you
|
11
|
+
# out of the box, unless you are me.
|
11
12
|
#
|
12
13
|
describe 'through test' do
|
13
14
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nebulous_stomp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Jones
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-08-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|