bunny-mock 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,269 +1,260 @@
1
+ # frozen_string_literal: true
1
2
  module BunnyMock
2
- class Exchange
3
-
4
- ##
5
- # Create a new {BunnyMock::Exchange} instance
6
- #
7
- # @param [BunnyMock::Channel] channel Channel this exchange will use
8
- # @param [String] name Name of exchange
9
- # @param [Hash] opts Creation options
10
- #
11
- # @option opts [Boolean] :durable (false) Should this exchange be durable?
12
- # @option opts [Boolean] :auto_delete (false) Should this exchange be automatically deleted when it is no longer used?
13
- # @option opts [Boolean] :arguments ({}) Additional optional arguments (typically used by RabbitMQ extensions and plugins)
14
- #
15
- # @return [BunnyMock::Exchange] A new exchange
16
- # @see BunnyMock::Channel#exchange
17
- # @api public
18
- #
19
- def self.declare(channel, name = '', opts = {})
20
-
21
- # get requested type
22
- type = opts.fetch :type, :direct
23
-
24
- # get needed class type
25
- klazz = BunnyMock::Exchanges.const_get type.to_s.capitalize
26
-
27
- # create exchange of desired type
28
- klazz.new channel, name, type, opts
29
- end
30
-
31
- #
32
- # API
33
- #
34
-
35
- # @return [BunnyMock::Channel] Channel used by exchange
36
- attr_reader :channel
37
-
38
- # @return [String] Exchange name
39
- attr_reader :name
40
-
41
- # @return [String] Exchange type
42
- attr_reader :type
43
-
44
- # @return [Hash] Creation options
45
- attr_reader :opts
46
-
47
- # @private
48
- # @return [Boolean] If exchange has been deleted
49
- attr_reader :deleted
50
-
51
- # @private
52
- def initialize(channel, name, type, opts)
53
-
54
- # store creation information
55
- @channel = channel
56
- @name = name
57
- @opts = opts
58
- @type = type
59
-
60
- # get options
61
- @durable = @opts[:durable]
62
- @auto_delete = @opts[:auto_delete]
63
- @internal = @opts[:internal]
64
- @arguments = @opts[:arguments]
65
-
66
- # create binding storage
67
- @routes = Hash.new
68
- end
69
-
70
- # @group Bunny API
71
-
72
- # @return [Boolean] true if this exchange was declared as durable, false otherwise
73
- # @api public
74
- def durable?
75
- @durable
76
- end
77
-
78
- # @return [Boolean] true if this exchange was set to auto delete, false otherwise
79
- # @api public
80
- def auto_delete?
81
- @auto_delete
82
- end
83
-
84
- # @return [Boolean] true if this exchange was declared as internal, false otherwise
85
- # @api public
86
- def internal?
87
- @internal
88
- end
89
-
90
- # @return [Hash] Additional option arguments
91
- # @api public
92
- def arguments
93
- @arguments
94
- end
95
-
96
- ##
97
- # Publish a message
98
- #
99
- # @param [Object] payload Message payload
100
- # @param [Hash] opts Message properties
101
- #
102
- # @option opts [String] :routing_key Routing key
103
- # @option opts [Boolean] :persistent Should the message be persisted to disk?
104
- # @option opts [Boolean] :mandatory Should the message be returned if it cannot be routed to any queue?
105
- # @option opts [Integer] :timestamp A timestamp associated with this message
106
- # @option opts [Integer] :expiration Expiration time after which the message will be deleted
107
- # @option opts [String] :type Message type, e.g. what type of event or command this message represents. Can be any string
108
- # @option opts [String] :reply_to Queue name other apps should send the response to
109
- # @option opts [String] :content_type Message content type (e.g. application/json)
110
- # @option opts [String] :content_encoding Message content encoding (e.g. gzip)
111
- # @option opts [String] :correlation_id Message correlated to this one, e.g. what request this message is a reply for
112
- # @option opts [Integer] :priority Message priority, 0 to 9. Not used by RabbitMQ, only applications
113
- # @option opts [String] :message_id Any message identifier
114
- # @option opts [String] :user_id Optional user ID. Verified by RabbitMQ against the actual connection username
115
- # @option opts [String] :app_id Optional application ID
116
- #
117
- # @return [BunnyMock::Exchange] self
118
- # @see {BunnyMock::Exchanges::Direct#deliver}
119
- # @see {BunnyMock::Exchanges::Topic#deliver}
120
- # @see {BunnyMock::Exchanges::Fanout#deliver}
121
- # @see {BunnyMock::Exchanges::Headers#deliver}
122
- # @api public
123
- #
124
- def publish(payload, opts = {})
125
-
126
- # handle message sending, varies by type
127
- deliver payload, opts, opts.fetch(:routing_key, '')
128
-
129
- self
130
- end
131
-
132
- ##
133
- # Delete this exchange
134
- #
135
- # @param [Hash] opts Options (insignificant)
136
- #
137
- # @api public
138
- #
139
- def delete(opts = {})
140
-
141
- @channel.deregister_exchange self
142
-
143
- @deleted = true
144
- end
145
-
146
- ##
147
- # Bind this exchange to another exchange
148
- #
149
- # @param [BunnyMock::Exchange,String] exchange Exchange to bind to
150
- # @param [Hash] opts Binding properties
151
- #
152
- # @option opts [String] :routing_key Custom routing key
153
- #
154
- # @return [BunnyMock::Exchange] self
155
- # @api public
156
- #
157
- def bind(exchange, opts = {})
158
-
159
- if exchange.respond_to?(:add_route)
160
-
161
- # we can do the binding ourselves
162
- exchange.add_route opts.fetch(:routing_key, @name), self
163
-
164
- else
165
-
166
- # we need the channel to look up the exchange
167
- @channel.xchg_bind self, opts.fetch(:routing_key, @name), exchange
168
- end
169
-
170
- self
171
- end
172
-
173
- ##
174
- # Unbind this exchange from another exchange
175
- #
176
- # @param [BunnyMock::Exchange,String] exchange Exchange to unbind from
177
- # @param [Hash] opts Binding properties
178
- #
179
- # @option opts [String] :routing_key Custom routing key
180
- #
181
- # @api public
182
- #
183
- def unbind(exchange, opts = {})
184
-
185
- if exchange.respond_to?(:remove_route)
186
-
187
- # we can do the unbinding ourselves
188
- exchange.remove_route opts.fetch(:routing_key, @name)
189
-
190
- else
191
-
192
- # we need the channel to look up the exchange
193
- @channel.xchg_unbind opts.fetch(:routing_key, @name), exchange
194
- end
195
- end
196
-
197
- # @endgroup
198
-
199
- ##
200
- # Check if this exchange is bound to another exchange
201
- #
202
- # @param [BunnyMock::Exchange,String] exchange Exchange to check
203
- # @param [Hash] opts Binding properties
204
- #
205
- # @option opts [String] :routing_key Routing key from binding
206
- #
207
- # @return [Boolean] true if this exchange is bound to the given exchange, false otherwise
208
- # @api public
209
- #
210
- def bound_to?(exchange, opts = {})
211
-
212
- if exchange.respond_to?(:has_binding?)
213
-
214
- # we can find out on the exchange object
215
- exchange.has_binding? self, opts
216
-
217
- else
218
-
219
- # we need the channel to look up the exchange
220
- @channel.xchg_bound_to? self, opts.fetch(:routing_key, @name), exchange
221
- end
222
- end
223
-
224
- ##
225
- # Check if a queue is bound to this exchange
226
- #
227
- # @param [BunnyMock::Queue,String] exchange_or_queue Exchange or queue to check
228
- # @param [Hash] opts Binding properties
229
- #
230
- # @option opts [String] :routing_key Custom routing key
231
- #
232
- # @return [Boolean] true if the given queue or exchange matching options is bound to this exchange, false otherwise
233
- # @api public
234
- #
235
- def has_binding?(exchange_or_queue, opts = {})
236
-
237
- route = exchange_or_queue.respond_to?(:name) ? exchange_or_queue.name : exchange_or_queue
238
-
239
- @routes.key? opts.fetch(:routing_key, route)
240
- end
241
-
242
- ##
243
- # Deliver a message to routes
244
- #
245
- # @see {BunnyMock::Exchanges::Direct#deliver}
246
- # @see {BunnyMock::Exchanges::Topic#deliver}
247
- # @see {BunnyMock::Exchanges::Fanout#deliver}
248
- # @see {BunnyMock::Exchanges::Headers#deliver}
249
- # @api public
250
- #
251
- def deliver(payload, opts, key)
252
- # noOp
253
- end
254
-
255
- #
256
- # Implementation
257
- #
258
-
259
- # @private
260
- def add_route(key, xchg_or_queue)
261
- @routes[key] = xchg_or_queue
262
- end
263
-
264
- # @private
265
- def remove_route(key)
266
- @routes.delete key
267
- end
268
- end
3
+ class Exchange
4
+
5
+ ##
6
+ # Create a new {BunnyMock::Exchange} instance
7
+ #
8
+ # @param [BunnyMock::Channel] channel Channel this exchange will use
9
+ # @param [String] name Name of exchange
10
+ # @param [Hash] opts Creation options
11
+ #
12
+ # @option opts [Boolean] :durable (false) Should this exchange be durable?
13
+ # @option opts [Boolean] :auto_delete (false) Should this exchange be automatically deleted when it is no longer used?
14
+ # @option opts [Boolean] :arguments ({}) Additional optional arguments (typically used by RabbitMQ extensions and plugins)
15
+ #
16
+ # @return [BunnyMock::Exchange] A new exchange
17
+ # @see BunnyMock::Channel#exchange
18
+ # @api public
19
+ #
20
+ def self.declare(channel, name = '', opts = {})
21
+
22
+ # get requested type
23
+ type = opts.fetch :type, :direct
24
+
25
+ # get needed class type
26
+ klazz = BunnyMock::Exchanges.const_get type.to_s.capitalize
27
+
28
+ # create exchange of desired type
29
+ klazz.new channel, name, type, opts
30
+ end
31
+
32
+ #
33
+ # API
34
+ #
35
+
36
+ # @return [BunnyMock::Channel] Channel used by exchange
37
+ attr_reader :channel
38
+
39
+ # @return [String] Exchange name
40
+ attr_reader :name
41
+
42
+ # @return [String] Exchange type
43
+ attr_reader :type
44
+
45
+ # @return [Hash] Creation options
46
+ attr_reader :opts
47
+
48
+ # @return [Boolean] If the exchange was declared as durable
49
+ attr_reader :durable
50
+ alias durable? durable
51
+
52
+ # @return [Boolean] If the exchange was declared with auto deletion
53
+ attr_reader :auto_delete
54
+ alias auto_delete? auto_delete
55
+
56
+ # @return [Boolean] If the exchange was declared as internal
57
+ attr_reader :internal
58
+ alias internal? internal
59
+
60
+ # @return [Hash] Any additional declaration arguments
61
+ attr_reader :arguments
62
+
63
+ # @private
64
+ # @return [Boolean] If exchange has been deleted
65
+ attr_reader :deleted
66
+
67
+ # @private
68
+ def initialize(channel, name, type, opts)
69
+
70
+ # store creation information
71
+ @channel = channel
72
+ @name = name
73
+ @opts = opts
74
+ @type = type
75
+
76
+ # get options
77
+ @durable = @opts[:durable]
78
+ @auto_delete = @opts[:auto_delete]
79
+ @internal = @opts[:internal]
80
+ @arguments = @opts[:arguments]
81
+
82
+ # create binding storage
83
+ @routes = {}
84
+ end
85
+
86
+ # @group Bunny API
87
+
88
+ ##
89
+ # Publish a message
90
+ #
91
+ # @param [Object] payload Message payload
92
+ # @param [Hash] opts Message properties
93
+ #
94
+ # @option opts [String] :routing_key Routing key
95
+ # @option opts [Boolean] :persistent Should the message be persisted to disk?
96
+ # @option opts [Boolean] :mandatory Should the message be returned if it cannot be routed to any queue?
97
+ # @option opts [Integer] :timestamp A timestamp associated with this message
98
+ # @option opts [Integer] :expiration Expiration time after which the message will be deleted
99
+ # @option opts [String] :type Message type, e.g. what type of event or command this message represents. Can be any string
100
+ # @option opts [String] :reply_to Queue name other apps should send the response to
101
+ # @option opts [String] :content_type Message content type (e.g. application/json)
102
+ # @option opts [String] :content_encoding Message content encoding (e.g. gzip)
103
+ # @option opts [String] :correlation_id Message correlated to this one, e.g. what request this message is a reply for
104
+ # @option opts [Integer] :priority Message priority, 0 to 9. Not used by RabbitMQ, only applications
105
+ # @option opts [String] :message_id Any message identifier
106
+ # @option opts [String] :user_id Optional user ID. Verified by RabbitMQ against the actual connection username
107
+ # @option opts [String] :app_id Optional application ID
108
+ #
109
+ # @return [BunnyMock::Exchange] self
110
+ # @see {BunnyMock::Exchanges::Direct#deliver}
111
+ # @see {BunnyMock::Exchanges::Topic#deliver}
112
+ # @see {BunnyMock::Exchanges::Fanout#deliver}
113
+ # @see {BunnyMock::Exchanges::Headers#deliver}
114
+ # @api public
115
+ #
116
+ def publish(payload, opts = {})
117
+
118
+ # handle message sending, varies by type
119
+ deliver payload, opts, opts.fetch(:routing_key, '')
120
+
121
+ self
122
+ end
123
+
124
+ ##
125
+ # Delete this exchange
126
+ #
127
+ # @api public
128
+ #
129
+ def delete(*)
130
+
131
+ @channel.deregister_exchange self
132
+
133
+ @deleted = true
134
+ end
135
+
136
+ ##
137
+ # Bind this exchange to another exchange
138
+ #
139
+ # @param [BunnyMock::Exchange,String] exchange Exchange to bind to
140
+ # @param [Hash] opts Binding properties
141
+ #
142
+ # @option opts [String] :routing_key Custom routing key
143
+ #
144
+ # @return [BunnyMock::Exchange] self
145
+ # @api public
146
+ #
147
+ def bind(exchange, opts = {})
148
+
149
+ if exchange.respond_to?(:add_route)
150
+
151
+ # we can do the binding ourselves
152
+ exchange.add_route opts.fetch(:routing_key, @name), self
153
+
154
+ else
155
+
156
+ # we need the channel to look up the exchange
157
+ @channel.xchg_bind self, opts.fetch(:routing_key, @name), exchange
158
+ end
159
+
160
+ self
161
+ end
162
+
163
+ ##
164
+ # Unbind this exchange from another exchange
165
+ #
166
+ # @param [BunnyMock::Exchange,String] exchange Exchange to unbind from
167
+ # @param [Hash] opts Binding properties
168
+ #
169
+ # @option opts [String] :routing_key Custom routing key
170
+ #
171
+ # @api public
172
+ #
173
+ def unbind(exchange, opts = {})
174
+
175
+ if exchange.respond_to?(:remove_route)
176
+
177
+ # we can do the unbinding ourselves
178
+ exchange.remove_route opts.fetch(:routing_key, @name)
179
+
180
+ else
181
+
182
+ # we need the channel to look up the exchange
183
+ @channel.xchg_unbind opts.fetch(:routing_key, @name), exchange
184
+ end
185
+ end
186
+
187
+ # @endgroup
188
+
189
+ ##
190
+ # Check if this exchange is bound to another exchange
191
+ #
192
+ # @param [BunnyMock::Exchange,String] exchange Exchange to check
193
+ # @param [Hash] opts Binding properties
194
+ #
195
+ # @option opts [String] :routing_key Routing key from binding
196
+ #
197
+ # @return [Boolean] true if this exchange is bound to the given exchange, false otherwise
198
+ # @api public
199
+ #
200
+ def bound_to?(exchange, opts = {})
201
+
202
+ if exchange.respond_to?(:routes_to?)
203
+
204
+ # we can find out on the exchange object
205
+ exchange.routes_to? self, opts
206
+
207
+ else
208
+
209
+ # we need the channel to look up the exchange
210
+ @channel.xchg_bound_to? self, opts.fetch(:routing_key, @name), exchange
211
+ end
212
+ end
213
+
214
+ ##
215
+ # Check if a queue is bound to this exchange
216
+ #
217
+ # @param [BunnyMock::Queue,String] exchange_or_queue Exchange or queue to check
218
+ # @param [Hash] opts Binding properties
219
+ #
220
+ # @option opts [String] :routing_key Custom routing key
221
+ #
222
+ # @return [Boolean] true if the given queue or exchange matching options is bound to this exchange, false otherwise
223
+ # @api public
224
+ #
225
+ def routes_to?(exchange_or_queue, opts = {})
226
+
227
+ route = exchange_or_queue.respond_to?(:name) ? exchange_or_queue.name : exchange_or_queue
228
+
229
+ @routes.key? opts.fetch(:routing_key, route)
230
+ end
231
+ alias has_binding? routes_to?
232
+
233
+ ##
234
+ # Deliver a message to routes
235
+ #
236
+ # @see {BunnyMock::Exchanges::Direct#deliver}
237
+ # @see {BunnyMock::Exchanges::Topic#deliver}
238
+ # @see {BunnyMock::Exchanges::Fanout#deliver}
239
+ # @see {BunnyMock::Exchanges::Headers#deliver}
240
+ # @api public
241
+ #
242
+ def deliver(payload, opts, key)
243
+ # noOp
244
+ end
245
+
246
+ #
247
+ # Implementation
248
+ #
249
+
250
+ # @private
251
+ def add_route(key, xchg_or_queue)
252
+ @routes[key] = xchg_or_queue
253
+ end
254
+
255
+ # @private
256
+ def remove_route(key)
257
+ @routes.delete key
258
+ end
259
+ end
269
260
  end