nebulous_stomp 2.0.1 → 2.0.2
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/.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
|