Class: NebulousStomp::Message
- Inherits:
-
Object
- Object
- NebulousStomp::Message
- Extended by:
- Forwardable
- Defined in:
- lib/nebulous_stomp/message.rb
Overview
A class to encapsulate a Nebulous message (which is built on top of a STOMP message)
This class is entirely read-only, except for reply_id, which is set by Request when the message is sent.
Much of this class is handled by two helper classes: the message headers are handled by Msg::Header and the message body by Msg::Body. You should look at them, too, for the full picture.
Class Method Summary collapse
-
.from_cache(json) ⇒ Object
:call-seq: Message.from_cache(hash) -> Message.
-
.from_stomp(stompMsg) ⇒ Object
:call-seq: Message.from_stomp(stompmessage) -> Message.
-
.in_reply_to(msg, args) ⇒ Object
:call-seq: Message.in_reply_to(message, args) -> Message.
Instance Method Summary collapse
-
#initialize(hash) ⇒ Message
constructor
Create a new message,.
-
#respond(body) ⇒ Object
:call-seq: message.respond_with_protocol(body) -> queue, Message.
-
#respond_with_error(err, fields = []) ⇒ Object
(also: #respond_error)
:call-seq: message.respond_with_error(error, fields=[]) -> queue, Message.
-
#respond_with_protocol(verb, params = [], desc = "") ⇒ Object
:call-seq: message.respond_with_protocol(verb, params=[], desc=“”) -> queue, Message.
-
#respond_with_success ⇒ Object
(also: #respond_success)
:call-seq: message.respond_with_success -> queue, Message.
-
#to_h ⇒ Object
(also: #to_cache)
Output a hash for serialization to the Redis cache.
- #to_s ⇒ Object
Constructor Details
#initialize(hash) ⇒ Message
Create a new message,
There are three ways that a message could get created:
1. The user could create one directly.
2. A message could be created from an incoming STOMP message, in which case we should
call Message.from_stomp to create it.
3. A message could be created because we have retreived it from the Redis cache, in which
case we should call Message.from_cache to create it (and, note, it will originally
have been created in one of the other two ways...)
The full list of useful hash keys is (as per Message.from_cache, #to_h):
* :body -- the message body
* :contentType -- Stomp content type string
* :description / :desc -- part of The Protocol
* :inReplyTo -- message ID that message is a response to
* :parameters / :params -- part of The Protocol
* :replyId -- the 'unique' ID of this Nebulous message
* :replyTo -- for a request, the queue to be used for the response
* :stompBody -- for a message from Stomp, the raw Stomp message body
* :stompHeaders -- for a message from Stomp, the raw Stomp Headers string
* :verb -- part of The Protocol
Note that body is taken to be a string if the content type is text, and is taken to be JSON if the content type is JSON.
141 142 143 144 |
# File 'lib/nebulous_stomp/message.rb', line 141 def initialize(hash) @header = Msg::Header.new(hash) @body = Msg::Body.new(content_is_json?, hash) end |
Class Method Details
.from_cache(json) ⇒ Object
:call-seq: Message.from_cache(hash) -> Message
To build a Nebmessage from a record in the Redis cache.
See #to_h for details of the hash that Redis should be storing
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/nebulous_stomp/message.rb', line 90 def from_cache(json) fail ArgumentError, "That can't be JSON, it's not a string" unless json.kind_of? String NebulousStomp.logger.debug(__FILE__){ "New message from cache" } # Note that the message body at this point, for a JSON message, is actually encoded to JSON # *twice* - the second time was when the cache hash as a whole was encoded for store in # Redis. the JSON gem copes with this so long as the whole string is not double-encoded. hash = JSON.parse(json, :symbolize_names => true) fail ArgumentError, 'Empty cache entry' if hash == {} # So now if the content type is JSON then the body is still JSON now. It's only the rest of # the cache hash that is a now a hash. Confused? Now join us for this weeks' episode... self.new( hash.clone ) rescue JSON::ParserError => err fail ArgumentError, "Bad JSON: #{err.}" end |
.from_stomp(stompMsg) ⇒ Object
:call-seq: Message.from_stomp(stompmessage) -> Message
Build a Message from a (presumably incoming) STOMP message; stompmessage must be a Stomp::Message.
74 75 76 77 78 79 80 |
# File 'lib/nebulous_stomp/message.rb', line 74 def from_stomp(stompMsg) fail ArgumentError, 'not a stomp message' unless stompMsg.kind_of? Stomp::Message NebulousStomp.logger.debug(__FILE__){ "New message from STOMP" } s = Marshal.load( Marshal.dump(stompMsg) ) self.new(stompHeaders: s.headers, stompBody: s.body) end |
.in_reply_to(msg, args) ⇒ Object
:call-seq: Message.in_reply_to(message, args) -> Message
Build a Message that replies to an existing Message
* msg - the Nebulous::Message that you are replying to
* args - hash as per Message.new
See also #respond, #respond_with_protocol, etc, etc. (which you are probably better off calling, to be honest).
Note that this method absolutely enforces the protocol with regard to the content type and (of course) the id of the message it is replying to; for example, even if you pass a different content type it will take the content type of the msg in preference. If you want something weirder, you will have to use Message.new.
54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/nebulous_stomp/message.rb', line 54 def in_reply_to(msg, args) fail ArgumentError, 'bad message' unless msg.kind_of? Message fail ArgumentError, 'bad hash' unless args.kind_of? Hash fail ArgumentError, 'message has no reply ID' unless msg.reply_id NebulousStomp.logger.debug(__FILE__){ "New message in reply to #{msg}" } hash = { inReplyTo: msg.reply_id, contentType: msg.content_type } self.new(args.merge hash) end |
Instance Method Details
#respond(body) ⇒ Object
:call-seq: message.respond_with_protocol(body) -> queue, Message
Repond with a message body (presumably a custom one that’s non-Protocol). If the content type is JSON, this can be an array or a Hash. If the content type is text, it must be a String.
194 195 196 197 198 199 200 201 202 |
# File 'lib/nebulous_stomp/message.rb', line 194 def respond(body) fail NebulousError, "Don't know which queue to reply to" unless reply_to # Easy to do by mistake, pain in the arse to work out what's going on if you do fail ArgumentError, "Respond takes a body, not a message" if body.is_a? Message mess = Message.in_reply_to(self, body: body) [ reply_to, mess ] end |
#respond_with_error(err, fields = []) ⇒ Object Also known as: respond_error
:call-seq: message.respond_with_error(error, fields=[]) -> queue, Message
Make a new ‘error verb’ message in response to this one.
Error can be a string or an exception. Fields is an arbitrary array of values, designed as a list of the parameter keys with problems; but of course you can use it for whatever you like.
226 227 228 229 |
# File 'lib/nebulous_stomp/message.rb', line 226 def respond_with_error(err, fields=[]) fail NebulousError, "Don't know which queue to reply to" unless reply_to respond_with_protocol('error', Array(fields).flatten.map(&:to_s), err.to_s) end |
#respond_with_protocol(verb, params = [], desc = "") ⇒ Object
:call-seq: message.respond_with_protocol(verb, params=[], desc=“”) -> queue, Message
Repond with a message using The Protocol.
180 181 182 183 184 185 |
# File 'lib/nebulous_stomp/message.rb', line 180 def respond_with_protocol(verb, params=[], desc="") fail NebulousError, "Don't know which queue to reply to" unless reply_to hash = {verb: verb, params: params, desc: desc} [ reply_to, Message.in_reply_to(self, hash) ] end |
#respond_with_success ⇒ Object Also known as: respond_success
:call-seq: message.respond_with_success -> queue, Message
Make a new ‘success verb’ message in response to this one.
210 211 212 213 |
# File 'lib/nebulous_stomp/message.rb', line 210 def respond_with_success fail NebulousError, "Don't know which queue to reply to" unless reply_to respond_with_protocol('success') end |
#to_h ⇒ Object Also known as: to_cache
Output a hash for serialization to the Redis cache.
Currently this looks like:
{ stompHeaders: @stomp_headers,
stompBody: @stomp_body,
body: @body
verb: @verb,
params: @params,
desc: @desc,
replyTo: @reply_to,
replyId: @reply_id,
inReplyTo: @in_reply_to,
contentType: @content_type }
Note that if :stompBody is set then :body will be nil. This is to attempt to reduce duplication of what might be a rather large string.
168 169 170 |
# File 'lib/nebulous_stomp/message.rb', line 168 def to_h @header.to_h.merge @body.to_h end |
#to_s ⇒ Object
146 147 148 |
# File 'lib/nebulous_stomp/message.rb', line 146 def to_s "<Message[#{reply_id}] to:#{reply_to} r-to:#{in_reply_to} v:#{verb}>" end |