mimi-messaging-sqs_sns 0.4.0 → 0.6.1
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 +5 -5
- data/TODO.md +9 -0
- data/examples/query.rb +2 -2
- data/examples/responder.rb +3 -3
- data/lib/mimi/messaging/sqs_sns.rb +1 -0
- data/lib/mimi/messaging/sqs_sns/adapter.rb +75 -26
- data/lib/mimi/messaging/sqs_sns/consumer.rb +22 -7
- data/lib/mimi/messaging/sqs_sns/reply_consumer.rb +9 -10
- data/lib/mimi/messaging/sqs_sns/temporary_queue_consumer.rb +29 -0
- data/lib/mimi/messaging/sqs_sns/version.rb +1 -1
- data/mimi-messaging-sqs_sns.gemspec +1 -1
- metadata +13 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 1f7bfa555dbbe8a3d917d0133811c6f2af643016e5864628a8ae7ae79ec2a9fc
|
4
|
+
data.tar.gz: adc4769159cb678ca05e69c0d5b174b2d9a87064da8fcddf16916596ab14889e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 377f9dc7b50c0c3c4edd77afec14e2473fdebbfd4751a18d358c27b9c4281e3af2566f5f70c68fb228a75316d985a2f8f4cab4c74b5d233335e2986875fa88b0
|
7
|
+
data.tar.gz: becd20ef9d41f474ee072a8af75b8b885e40f47b8c34ddca61269cd413fb88368d4715808e4ca8a507b2c56e41b6db0aaf1381c0c9e1715dc4397aa4dcf1888b
|
data/TODO.md
ADDED
data/examples/query.rb
CHANGED
@@ -4,8 +4,8 @@ require "mimi/messaging/sqs_sns"
|
|
4
4
|
|
5
5
|
COUNT = 10
|
6
6
|
AWS_REGION = "eu-west-1"
|
7
|
-
AWS_SQS_ENDPOINT_URL = "http://localstack:
|
8
|
-
AWS_SNS_ENDPOINT_URL = "http://localstack:
|
7
|
+
AWS_SQS_ENDPOINT_URL = "http://localstack:4566"
|
8
|
+
AWS_SNS_ENDPOINT_URL = "http://localstack:4566"
|
9
9
|
AWS_ACCESS_KEY_ID = "foo"
|
10
10
|
AWS_SECRET_ACCESS_KEY = "bar"
|
11
11
|
|
data/examples/responder.rb
CHANGED
@@ -3,8 +3,8 @@
|
|
3
3
|
require "mimi/messaging/sqs_sns"
|
4
4
|
|
5
5
|
AWS_REGION = "eu-west-1"
|
6
|
-
AWS_SQS_ENDPOINT_URL = "http://localstack:
|
7
|
-
AWS_SNS_ENDPOINT_URL = "http://localstack:
|
6
|
+
AWS_SQS_ENDPOINT_URL = "http://localstack:4566"
|
7
|
+
AWS_SNS_ENDPOINT_URL = "http://localstack:4566"
|
8
8
|
AWS_ACCESS_KEY_ID = "foo"
|
9
9
|
AWS_SECRET_ACCESS_KEY = "bar"
|
10
10
|
|
@@ -22,7 +22,7 @@ end # class Processor
|
|
22
22
|
|
23
23
|
|
24
24
|
logger = Logger.new(STDOUT)
|
25
|
-
logger.level = Logger::
|
25
|
+
logger.level = Logger::DEBUG
|
26
26
|
Mimi::Messaging.use(logger: logger, serializer: Mimi::Messaging::JsonSerializer)
|
27
27
|
Mimi::Messaging.configure(
|
28
28
|
mq_adapter: "sqs_sns",
|
@@ -78,6 +78,7 @@ module Mimi
|
|
78
78
|
def start
|
79
79
|
@sqs_client = Aws::SQS::Client.new(sqs_client_config)
|
80
80
|
@sns_client = Aws::SNS::Client.new(sns_client_config)
|
81
|
+
check_availability!
|
81
82
|
end
|
82
83
|
|
83
84
|
def stop
|
@@ -189,7 +190,7 @@ module Mimi
|
|
189
190
|
response,
|
190
191
|
__request_id: message.headers[:__request_id]
|
191
192
|
)
|
192
|
-
|
193
|
+
deliver_query_respone(reply_to, response_message)
|
193
194
|
else
|
194
195
|
processor.call_command(method_name, message, {})
|
195
196
|
end
|
@@ -218,6 +219,45 @@ module Mimi
|
|
218
219
|
end
|
219
220
|
end
|
220
221
|
|
222
|
+
# Creates a new queue
|
223
|
+
#
|
224
|
+
# @param queue_name [String] name of the topic to be created
|
225
|
+
# @return [String] a new queue URL
|
226
|
+
#
|
227
|
+
def create_queue(queue_name)
|
228
|
+
fqn = sqs_sns_converted_full_name(queue_name)
|
229
|
+
Mimi::Messaging.log "Creating a queue: #{fqn}"
|
230
|
+
result = sqs_client.create_queue(queue_name: fqn)
|
231
|
+
result.queue_url
|
232
|
+
rescue StandardError => e
|
233
|
+
raise Mimi::Messaging::ConnectionError, "Failed to create queue '#{queue_name}': #{e}"
|
234
|
+
end
|
235
|
+
|
236
|
+
|
237
|
+
# Finds a queue URL for a queue with given name.
|
238
|
+
#
|
239
|
+
# If an existing queue with this name is not found,
|
240
|
+
# the method will try to create a new one.
|
241
|
+
#
|
242
|
+
# @param queue_name [String]
|
243
|
+
# @return [String] a queue URL
|
244
|
+
#
|
245
|
+
def find_or_create_queue(queue_name)
|
246
|
+
queue_registry(queue_name) || create_queue(queue_name)
|
247
|
+
end
|
248
|
+
|
249
|
+
# Deletes a queue identified by the queue URL
|
250
|
+
#
|
251
|
+
# @param queue_url [String]
|
252
|
+
#
|
253
|
+
def delete_queue(queue_url)
|
254
|
+
Mimi::Messaging.log "Deleting a queue: #{queue_url}"
|
255
|
+
sqs_client.delete_queue(queue_url: queue_url)
|
256
|
+
rescue StandardError => e
|
257
|
+
raise Mimi::Messaging::ConnectionError,
|
258
|
+
"Failed to delete queue with url '#{queue_url}': #{e}"
|
259
|
+
end
|
260
|
+
|
221
261
|
private
|
222
262
|
|
223
263
|
# Returns configuration parameters for AWS SQS client
|
@@ -248,18 +288,21 @@ module Mimi
|
|
248
288
|
params.compact
|
249
289
|
end
|
250
290
|
|
251
|
-
#
|
291
|
+
# Checks SQS and SNS clients availability
|
252
292
|
#
|
253
|
-
# @
|
254
|
-
# @return [String] a new queue URL
|
293
|
+
# @raise [Mimi::Messaging::ConnectionError]
|
255
294
|
#
|
256
|
-
def
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
295
|
+
def check_availability!
|
296
|
+
begin
|
297
|
+
queue_registry("test")
|
298
|
+
rescue StandardError => e
|
299
|
+
raise Mimi::Messaging::ConnectionError, "SQS connection is not available: #{e}"
|
300
|
+
end
|
301
|
+
begin
|
302
|
+
topic_registry("test")
|
303
|
+
rescue StandardError => e
|
304
|
+
raise Mimi::Messaging::ConnectionError, "SNS connection is not available: #{e}"
|
305
|
+
end
|
263
306
|
end
|
264
307
|
|
265
308
|
# Delivers a message to a queue with given URL.
|
@@ -272,7 +315,7 @@ module Mimi
|
|
272
315
|
unless message.is_a?(Mimi::Messaging::Message)
|
273
316
|
raise ArgumentError, "Message is expected as argument"
|
274
317
|
end
|
275
|
-
Mimi::Messaging.log "Delivering message to: #{queue_url}"
|
318
|
+
Mimi::Messaging.log "Delivering message to: #{queue_url}, headers: #{message.headers}"
|
276
319
|
sqs_client.send_message(
|
277
320
|
queue_url: queue_url,
|
278
321
|
message_body: serialize(message),
|
@@ -284,6 +327,23 @@ module Mimi
|
|
284
327
|
raise Mimi::Messaging::ConnectionError, "Failed to deliver message to '#{queue_url}': #{e}"
|
285
328
|
end
|
286
329
|
|
330
|
+
# Delivers a message as a response to a QUERY
|
331
|
+
#
|
332
|
+
# Responses are allowed to fail. There can be a number of reasons
|
333
|
+
# why responses fail: reply queue does not exist (anymore?),
|
334
|
+
# response message is too big. In any case the error is reported,
|
335
|
+
# but the QUERY message is acknowledged as a successfully processed.
|
336
|
+
#
|
337
|
+
# @param queue_url [String]
|
338
|
+
# @param message [Mimi::Messaging::Message]
|
339
|
+
#
|
340
|
+
def deliver_query_respone(queue_url, message)
|
341
|
+
deliver_message_queue(queue_url, message)
|
342
|
+
rescue Mimi::Messaging::ConnectionError => e
|
343
|
+
Mimi::Messaging.logger&.warn("Failed to deliver QRY response: #{e}")
|
344
|
+
# NOTE: error is recovered
|
345
|
+
end
|
346
|
+
|
287
347
|
# Returns URL of a queue with a given name.
|
288
348
|
#
|
289
349
|
# If the queue with given name does not exist, returns nil
|
@@ -300,6 +360,8 @@ module Mimi
|
|
300
360
|
end
|
301
361
|
rescue Aws::SQS::Errors::NonExistentQueue
|
302
362
|
nil
|
363
|
+
rescue StandardError => e
|
364
|
+
raise Mimi::Messaging::ConnectionError, "Failed to get queue url '#{queue_name}': #{e}"
|
303
365
|
end
|
304
366
|
|
305
367
|
# Converts a topic or queue name to a fully qualified (with namespace)
|
@@ -329,18 +391,6 @@ module Mimi
|
|
329
391
|
)
|
330
392
|
end
|
331
393
|
|
332
|
-
# Finds a queue URL for a queue with given name.
|
333
|
-
#
|
334
|
-
# If an existing queue with this name is not found,
|
335
|
-
# the method will try to create a new one.
|
336
|
-
#
|
337
|
-
# @param queue_name [String]
|
338
|
-
# @return [String] a queue URL
|
339
|
-
#
|
340
|
-
def find_or_create_queue(queue_name)
|
341
|
-
queue_registry(queue_name) || create_queue(queue_name)
|
342
|
-
end
|
343
|
-
|
344
394
|
# Returns the configured reply listener for this process
|
345
395
|
#
|
346
396
|
# @return [ReplyConsumer]
|
@@ -348,8 +398,7 @@ module Mimi
|
|
348
398
|
def reply_consumer
|
349
399
|
@reply_consumer ||= begin
|
350
400
|
reply_queue_name = options[:mq_reply_queue_prefix] + SecureRandom.hex(8)
|
351
|
-
|
352
|
-
Mimi::Messaging::SQS_SNS::ReplyConsumer.new(self, reply_queue_url)
|
401
|
+
Mimi::Messaging::SQS_SNS::ReplyConsumer.new(self, reply_queue_name)
|
353
402
|
end
|
354
403
|
end
|
355
404
|
|
@@ -4,20 +4,15 @@ module Mimi
|
|
4
4
|
module Messaging
|
5
5
|
module SQS_SNS
|
6
6
|
#
|
7
|
-
# Message
|
7
|
+
# Message consumer for SQS queues
|
8
8
|
#
|
9
9
|
class Consumer
|
10
10
|
def initialize(adapter, queue_url, &block)
|
11
|
-
@block = block
|
12
11
|
@stop_requested = false
|
13
12
|
Mimi::Messaging.log "Starting consumer for: #{queue_url}"
|
14
13
|
@consumer_thread = Thread.new do
|
15
14
|
while not @stop_requested do
|
16
|
-
|
17
|
-
next unless message
|
18
|
-
Mimi::Messaging.log "Read message from: #{queue_url}"
|
19
|
-
block.call(message)
|
20
|
-
ack_message(adapter, queue_url, message)
|
15
|
+
read_and_process_message(adapter, queue_url, block)
|
21
16
|
end
|
22
17
|
Mimi::Messaging.log "Stopping consumer for: #{queue_url}"
|
23
18
|
end
|
@@ -30,6 +25,26 @@ module Mimi
|
|
30
25
|
|
31
26
|
private
|
32
27
|
|
28
|
+
# A method invoked in a loop to read/wait for a message
|
29
|
+
# from the associated queue and process it
|
30
|
+
#
|
31
|
+
# @param adapter [Mimi::Messaging::SQS_SNS::Adapter]
|
32
|
+
# @param queue_url [String]
|
33
|
+
# @param block [Proc] a block to be invoked when a message is received
|
34
|
+
#
|
35
|
+
def read_and_process_message(adapter, queue_url, block)
|
36
|
+
message = read_message(adapter, queue_url)
|
37
|
+
return unless message
|
38
|
+
Mimi::Messaging.log "Read message from: #{queue_url}"
|
39
|
+
block.call(message)
|
40
|
+
ack_message(adapter, queue_url, message)
|
41
|
+
rescue StandardError => e
|
42
|
+
Mimi::Messaging.logger&.error(
|
43
|
+
"#{self.class}: failed to read and process message from: #{queue_url}," \
|
44
|
+
" error: (#{e.class}) #{e}"
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
33
48
|
def read_message(adapter, queue_url)
|
34
49
|
result = adapter.sqs_client.receive_message(
|
35
50
|
queue_url: queue_url,
|
@@ -8,25 +8,23 @@ module Mimi
|
|
8
8
|
# and passes them to registered Queues (see Ruby ::Queue class).
|
9
9
|
#
|
10
10
|
class ReplyConsumer
|
11
|
-
attr_reader :reply_queue_url
|
11
|
+
attr_reader :reply_queue_name, :reply_queue_url
|
12
12
|
|
13
|
-
def initialize(adapter,
|
13
|
+
def initialize(adapter, reply_queue_name)
|
14
14
|
@mutex = Mutex.new
|
15
15
|
@queues = {}
|
16
16
|
@adapter = adapter
|
17
|
-
@
|
18
|
-
@consumer =
|
17
|
+
@reply_queue_name = reply_queue_name
|
18
|
+
@consumer = TemporaryQueueConsumer.new(adapter, reply_queue_name) do |message|
|
19
19
|
dispatch_message(message)
|
20
20
|
end
|
21
|
+
@reply_queue_url = @consumer.queue_url
|
21
22
|
end
|
22
23
|
|
23
24
|
def stop
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
raise Mimi::Messaging::Error, "Failed to stop consumer: #{e}"
|
28
|
-
end
|
29
|
-
# TODO: adapter.sqs_client.delete_queue(reply_queue_url)
|
25
|
+
@consumer.stop
|
26
|
+
rescue StandardError => e
|
27
|
+
raise Mimi::Messaging::Error, "Failed to stop reply consumer: #{e}"
|
30
28
|
end
|
31
29
|
|
32
30
|
# Register a new request_id to listen for.
|
@@ -65,6 +63,7 @@ module Mimi
|
|
65
63
|
@mutex.synchronize do
|
66
64
|
headers = deserialize_headers(message)
|
67
65
|
request_id = headers[:__request_id]
|
66
|
+
Mimi::Messaging.log "dispatching response, headers:#{headers}"
|
68
67
|
queue = @queues.delete(request_id)
|
69
68
|
end
|
70
69
|
queue&.push(message)
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mimi
|
4
|
+
module Messaging
|
5
|
+
module SQS_SNS
|
6
|
+
#
|
7
|
+
# Temporary queue consumer creates a temporary queue
|
8
|
+
# and attaches to it. The queue will be deleted
|
9
|
+
# on consumer shutdown.
|
10
|
+
#
|
11
|
+
class TemporaryQueueConsumer
|
12
|
+
attr_reader :queue_url
|
13
|
+
|
14
|
+
def initialize(adapter, queue_name, &block)
|
15
|
+
@adapter = adapter
|
16
|
+
@queue_url = adapter.find_or_create_queue(queue_name)
|
17
|
+
@consumer = Consumer.new(adapter, @queue_url, &block)
|
18
|
+
end
|
19
|
+
|
20
|
+
def stop
|
21
|
+
@consumer.stop
|
22
|
+
@adapter.delete_queue(queue_url)
|
23
|
+
rescue StandardError => e
|
24
|
+
raise Mimi::Messaging::Error, "Failed to stop temporary queue consumer: #{e}"
|
25
|
+
end
|
26
|
+
end # class TemporaryQueueConsumer
|
27
|
+
end # module SQS_SNS
|
28
|
+
end # module Messaging
|
29
|
+
end # module Mimi
|
@@ -39,6 +39,6 @@ Gem::Specification.new do |spec|
|
|
39
39
|
|
40
40
|
spec.add_development_dependency "bundler", "~> 2.0"
|
41
41
|
spec.add_development_dependency "pry", "~> 0.12"
|
42
|
-
spec.add_development_dependency "rake", "~>
|
42
|
+
spec.add_development_dependency "rake", "~> 12.0", ">= 12.3.3"
|
43
43
|
spec.add_development_dependency "rspec", "~> 3.0"
|
44
44
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mimi-messaging-sqs_sns
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Kukushkin
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-10-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mimi-messaging
|
@@ -86,14 +86,20 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
89
|
+
version: '12.0'
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: 12.3.3
|
90
93
|
type: :development
|
91
94
|
prerelease: false
|
92
95
|
version_requirements: !ruby/object:Gem::Requirement
|
93
96
|
requirements:
|
94
97
|
- - "~>"
|
95
98
|
- !ruby/object:Gem::Version
|
96
|
-
version: '
|
99
|
+
version: '12.0'
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: 12.3.3
|
97
103
|
- !ruby/object:Gem::Dependency
|
98
104
|
name: rspec
|
99
105
|
requirement: !ruby/object:Gem::Requirement
|
@@ -123,6 +129,7 @@ files:
|
|
123
129
|
- LICENSE.txt
|
124
130
|
- README.md
|
125
131
|
- Rakefile
|
132
|
+
- TODO.md
|
126
133
|
- bin/console
|
127
134
|
- bin/setup
|
128
135
|
- examples/event.rb
|
@@ -133,6 +140,7 @@ files:
|
|
133
140
|
- lib/mimi/messaging/sqs_sns/adapter.rb
|
134
141
|
- lib/mimi/messaging/sqs_sns/consumer.rb
|
135
142
|
- lib/mimi/messaging/sqs_sns/reply_consumer.rb
|
143
|
+
- lib/mimi/messaging/sqs_sns/temporary_queue_consumer.rb
|
136
144
|
- lib/mimi/messaging/sqs_sns/version.rb
|
137
145
|
- mimi-messaging-sqs_sns.gemspec
|
138
146
|
homepage: https://github.com/kukushkin/mimi-messaging-sqs_sns
|
@@ -157,8 +165,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
157
165
|
- !ruby/object:Gem::Version
|
158
166
|
version: '0'
|
159
167
|
requirements: []
|
160
|
-
|
161
|
-
rubygems_version: 2.6.14.4
|
168
|
+
rubygems_version: 3.0.3
|
162
169
|
signing_key:
|
163
170
|
specification_version: 4
|
164
171
|
summary: AWS SQS/SNS adapter for mimi-messaging
|