surfliner-metadata_consumer 0.1.0.pre.alpha.2 → 0.1.0.pre.alpha.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 22ceb6aaafb75d24e2cf646c3ac55eaca9c0fc92183a448f3ad3a09e9920eaea
4
- data.tar.gz: 52c43074990eade7d93c32fa471329e845d2776f9229246f57bec81e75fa558d
3
+ metadata.gz: 832b89f48813e1a03fa41326e48e32030ecdd20f1f1719705b9fb87b6883b17e
4
+ data.tar.gz: 406fc690ac6d2a771737953d53babf83f52406b9870b5837653e02357083bb1b
5
5
  SHA512:
6
- metadata.gz: f19622750625a84977122fa344b8635bac1d6f80de562237505be22f82aa3acbc532d53f768f0f3b9b7dbda84724d1979b9396e785dca25d30216b71b8746c65
7
- data.tar.gz: 47621bc83433c05a36cd0d15a3b3a526eb981b0bd1085014c5179ea7c1dce0ad0a12722895873d629bfc1a510cb3648d1a5b2695d1b797d9960befcbb90e517e
6
+ metadata.gz: 5f6fda0ab5aa1cc54053bd688ef353d3d303adb27a3820aef8506c90357860592fae98b201622b82513ba501b111dc35c52379b434ed6082a1b73edb4acef88b
7
+ data.tar.gz: 8106c7d167c2bcd1046c403d9a171f9b8c1c2d72651d002f08a828326f993cce7f45863e3e7db32928eeb295bdf58ee947303a502eb69366522a30ed14262dad
data/CHANGES.md CHANGED
@@ -1,3 +1,18 @@
1
+ # 0.1.0.pre.alpha.4 (2025-03-17)
2
+
3
+ - lower required Ruby version to 3.2
4
+
5
+ # 0.1.0.pre.alpha.3 (2025-03-07)
6
+
7
+ - improve topic/queue option override API
8
+ - clean up binscripts
9
+
10
+ # 0.1.0.pre.alpha.2 (2025-03-07)
11
+
12
+ - use METADATA_API_URL_BASE cf. surfliner apps
13
+ - allow overriding topic and queue options
14
+ - don't close channel if already closed
15
+
1
16
  # 0.1.0.pre.alpha.1 (2025-02-12)
2
17
 
3
18
  - CI pipeline gem release test
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- surfliner-metadata_consumer (0.1.0.pre.alpha.2)
4
+ surfliner-metadata_consumer (0.1.0.pre.alpha.4)
5
5
  bunny (~> 2.23)
6
6
  opentelemetry-exporter-otlp (~> 0.26.3)
7
7
  opentelemetry-instrumentation-all (~> 0.60.0)
@@ -52,7 +52,7 @@ GEM
52
52
  pp (>= 0.6.0)
53
53
  rdoc (>= 4.0.0)
54
54
  reline (>= 0.4.2)
55
- json (2.10.1)
55
+ json (2.10.2)
56
56
  language_server-protocol (3.17.0.4)
57
57
  lint_roller (1.1.0)
58
58
  logger (1.6.6)
@@ -291,9 +291,10 @@ GEM
291
291
  diff-lcs (>= 1.2.0, < 2.0)
292
292
  rspec-support (~> 3.13.0)
293
293
  rspec-support (3.13.2)
294
- rubocop (1.71.2)
294
+ rubocop (1.73.2)
295
295
  json (~> 2.3)
296
- language_server-protocol (>= 3.17.0)
296
+ language_server-protocol (~> 3.17.0.2)
297
+ lint_roller (~> 1.1.0)
297
298
  parallel (~> 1.10)
298
299
  parser (>= 3.3.0.2)
299
300
  rainbow (>= 2.2.2, < 4.0)
@@ -301,11 +302,12 @@ GEM
301
302
  rubocop-ast (>= 1.38.0, < 2.0)
302
303
  ruby-progressbar (~> 1.7)
303
304
  unicode-display_width (>= 2.4.0, < 4.0)
304
- rubocop-ast (1.38.1)
305
+ rubocop-ast (1.39.0)
305
306
  parser (>= 3.3.1.0)
306
- rubocop-performance (1.23.1)
307
- rubocop (>= 1.48.1, < 2.0)
308
- rubocop-ast (>= 1.31.1, < 2.0)
307
+ rubocop-performance (1.24.0)
308
+ lint_roller (~> 1.1)
309
+ rubocop (>= 1.72.1, < 2.0)
310
+ rubocop-ast (>= 1.38.0, < 2.0)
309
311
  ruby-progressbar (1.13.0)
310
312
  set (1.1.1)
311
313
  simplecov (0.22.0)
@@ -320,24 +322,24 @@ GEM
320
322
  sorted_set (1.0.3)
321
323
  rbtree
322
324
  set (~> 1.0)
323
- standard (1.45.0)
325
+ standard (1.47.0)
324
326
  language_server-protocol (~> 3.17.0.2)
325
327
  lint_roller (~> 1.0)
326
- rubocop (~> 1.71.0)
328
+ rubocop (~> 1.73.0)
327
329
  standard-custom (~> 1.0.0)
328
- standard-performance (~> 1.6)
330
+ standard-performance (~> 1.7)
329
331
  standard-custom (1.0.2)
330
332
  lint_roller (~> 1.0)
331
333
  rubocop (~> 1.50)
332
- standard-performance (1.6.0)
334
+ standard-performance (1.7.0)
333
335
  lint_roller (~> 1.1)
334
- rubocop-performance (~> 1.23.0)
336
+ rubocop-performance (~> 1.24.0)
335
337
  stringio (3.1.5)
336
338
  unicode-display_width (3.1.4)
337
339
  unicode-emoji (~> 4.0, >= 4.0.4)
338
340
  unicode-emoji (4.0.4)
339
341
  uri (1.0.3)
340
- webmock (3.25.0)
342
+ webmock (3.25.1)
341
343
  addressable (>= 2.8.0)
342
344
  crack (>= 0.3.2)
343
345
  hashdiff (>= 0.4.0, < 2.0.0)
@@ -2,12 +2,8 @@
2
2
  require "bundler/setup"
3
3
  require "logger"
4
4
  require "opentelemetry/sdk"
5
- require "surfliner/metadata_consumer"
6
-
7
- $stdout.sync = true # don't buffer log output
8
5
 
9
- logger = Logger.new($stdout)
10
- logger.level = ENV.fetch("LOG_LEVEL") { Logger::INFO }
6
+ require "surfliner/metadata_consumer"
11
7
 
12
8
  unless ENV["OTEL_SDK_DISABLED"] == "true"
13
9
  OpenTelemetry::SDK.configure do |c|
@@ -15,11 +11,13 @@ unless ENV["OTEL_SDK_DISABLED"] == "true"
15
11
  c.use_all # enables auto instrumentation for Bunny, Net::HTTP, etc...
16
12
  end
17
13
  end
14
+ tracer = OpenTelemetry.tracer_provider.tracer("DaylightConsumerTracer")
18
15
 
19
- tracer = OpenTelemetry.tracer_provider.tracer("DaylightConsumerTracer")
20
-
21
- handler = Surfliner::MetadataConsumer::Solr::MessageHandler
22
-
23
- opts = { queue: { durable: false } }
16
+ $stdout.sync = true # don't buffer log output
17
+ logger = Logger.new($stdout).tap do |logger|
18
+ logger.level = ENV.fetch("LOG_LEVEL", Logger::INFO)
19
+ end
24
20
 
25
- Surfliner::MetadataConsumer::Consumer.run(logger:, tracer:, handler:, opts:)
21
+ handler = Surfliner::MetadataConsumer::Solr::MessageHandler
22
+ consumer = Surfliner::MetadataConsumer::Consumer.new(tracer:, logger:, handler:)
23
+ consumer.run
@@ -1,33 +1,56 @@
1
1
  #!/usr/bin/env ruby
2
2
  require "bundler/setup"
3
- require "date"
4
3
  require "json"
5
4
  require "logger"
6
5
 
7
- require "surfliner/metadata_consumer/mq_connection"
6
+ require "surfliner/metadata_consumer"
8
7
 
9
- api_base = ENV.fetch("METADATA_API_URL_BASE") { "http://metadata.test/resources" }
10
- logger = Logger.new($stdout)
11
- logger.level = ENV.fetch("LOG_LEVEL") { Logger::INFO }
8
+ module Surfliner
9
+ module MetadataConsumer
10
+ class Publisher
12
11
 
13
- opts = { queue: { durable: false } }
12
+ attr_reader :logger
13
+ attr_reader :topic_opts
14
+ attr_reader :queue_opts
14
15
 
15
- connection = Surfliner::MetadataConsumer::MqConnection.new(logger:, opts:).connect
16
+ def initialize(logger:, topic_opts: {}, queue_opts: {})
17
+ @logger = logger
18
+ @topic_opts = topic_opts
19
+ @queue_opts = queue_opts
20
+ end
16
21
 
22
+ def publish(resource_id)
23
+ payload = payload_for(resource_id)
24
+ connection.publish(payload)
25
+ end
26
+
27
+ def payload_for(id)
28
+ { resourceUrl: "#{api_base}/#{id}",
29
+ status: :published,
30
+ time_stamp: DateTime.now }.to_json
31
+ end
32
+
33
+ def connection
34
+ @connection ||= MqConnection.new(logger:).connect(topic_opts:, queue_opts:)
35
+ end
36
+
37
+ def api_base
38
+ @api_base ||= ENV.fetch("METADATA_API_URL_BASE", "http://metadata.test/resources")
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ $stdout.sync = true # don't buffer log output
45
+ logger = Logger.new($stdout).tap do |logger|
46
+ logger.level = ENV.fetch("LOG_LEVEL", Logger::INFO)
47
+ end
48
+
49
+ publisher = Surfliner::MetadataConsumer::Publisher.new(logger:)
17
50
  begin
18
- ARGV.each do |id|
19
- payload =
20
- { resourceUrl: "#{api_base}/#{id}",
21
- status: :published,
22
- time_stamp: DateTime.now }.to_json
23
-
24
- logger.info "Publishing to #{connection.routing_key} with #{payload}"
25
- connection.exchange.publish(payload, routing_key: connection.routing_key)
51
+ ARGV.each do |resource_id|
52
+ publisher.publish(resource_id)
26
53
  end
27
54
  ensure
28
- begin
29
- connection&.channel
30
- ensure
31
- connection&.close
32
- end
55
+ publisher.connection.close
33
56
  end
@@ -13,37 +13,36 @@ module Surfliner
13
13
  # @param tracer [OpenTelemetry::Trace::Tracer] OpenTelemetry tracer
14
14
  # @param logger [Logger] log message destination
15
15
  # @param handler #handle an object accepting a JSON string
16
- # @param opts [Hash] (see MqConnection#new)
17
- def initialize(tracer:, logger:, handler:, opts: nil)
18
- @connection = MqConnection.new(logger:, opts:)
16
+ def initialize(tracer:, logger:, handler:)
17
+ @connection = MqConnection.new(logger:)
19
18
  @logger = logger
20
19
  @tracer = tracer
21
20
  @handler = handler
22
21
  end
23
22
 
24
- # Initializes and starts a new `Consumer`
25
- # @param tracer [OpenTelemetry::Trace::Tracer] OpenTelemetry tracer
26
- # @param logger [Logger] log message destination
27
- # @param handler #handle an object accepting a JSON string payload
28
- # @param opts [Hash] (see MqConnection#new)
29
- def self.run(tracer:, logger:, handler:, opts: nil)
30
- new(tracer:, logger:, handler:, opts:).run
31
- end
32
-
33
23
  # Starts listening to the message queue and passing messages to the handler.
34
- def run
35
- connection.open do |queue|
24
+ # @param queue_opts [Hash] RabbitMQ queue options. (See Bunny::Channel#queue)
25
+ # @param topic_opts [Hash] RabbitMQ topic options. (See Bunny::Channel#topic)
26
+ def run(queue_opts: {}, topic_opts: {})
27
+ connection.open(queue_opts:, topic_opts:) do |queue|
36
28
  queue.subscribe(block: true) do |_delivery_info, _properties, payload_json|
37
29
  tracer.in_span("surfliner metadata consumer message") do |_span|
38
- logger.info(" [  ] message received with payload: #{payload_json}")
39
-
40
- handler.handle(payload_json)
30
+ handle(payload_json)
41
31
  end
42
- rescue => err
43
- logger.error(" [❌] failed to handle message: #{err}\n#{err.backtrace}")
44
32
  end
45
33
  end
46
34
  end
35
+
36
+ # Dispatches the specified payload to the handler.
37
+ # @param payload_json [String] JSON message payload
38
+ def handle(payload_json)
39
+ logger.info(" [→] message received with payload: #{payload_json}")
40
+
41
+ handler.handle(payload_json)
42
+ logger.info(" [✓] message handled")
43
+ rescue => err
44
+ logger.error(" [!] failed to handle message: #{err.full_message}")
45
+ end
47
46
  end
48
47
  end
49
48
  end
@@ -4,15 +4,6 @@ module Surfliner
4
4
  module MetadataConsumer
5
5
  # An object encapsulating a RabbitMQ connection.
6
6
  class MqConnection
7
- # Default RabbitMQ topic options
8
- DEFAULT_TOPIC_OPTS = {auto_delete: true}.freeze
9
-
10
- # Default RabbitMQ queue options
11
- DEFAULT_QUEUE_OPTS = {durable: true}.freeze
12
-
13
- # Default RabbitMQ topic and queue options
14
- DEFAULT_OPTS = {topic: DEFAULT_TOPIC_OPTS, queue: DEFAULT_QUEUE_OPTS}.freeze
15
-
16
7
  # @return [Logger] The logger
17
8
  attr_reader :logger
18
9
 
@@ -31,24 +22,21 @@ module Surfliner
31
22
  # @return [MqConfig] The configuration
32
23
  attr_reader :config
33
24
 
34
- # @return [Hash<Symbol, Hash>] Options to pass when connecting to RabbitMQ topic and queue. Overrides DEFAULT_OPTS.
35
- attr_reader :opts
36
-
37
25
  # Initializes a new `MqConnection`.
38
26
  #
39
27
  # @param logger [Logger] the logger
40
28
  # @param config [MqConfig] the configuration
41
- # @param opts [Hash<Symbol, Hash>] Options to pass when connecting to RabbitMQ topic and queue. Overrides DEFAULT_OPTS.
42
- def initialize(logger:, config: MqConfig.from_env, opts: nil)
29
+ def initialize(logger:, config: MqConfig.from_env)
43
30
  @logger = logger
44
31
  @config = config
45
- @opts = merge_opts(opts)
46
32
  end
47
33
 
48
34
  # Opens a connection.
35
+ # @param topic_opts [Hash] RabbitMQ topic options. (See Bunny::Channel#topic)
36
+ # @param queue_opts [Hash] RabbitMQ queue options. (See Bunny::Channel#queue)
49
37
  # @return [self]
50
38
  # @raise RuntimeError if already connected
51
- def connect
39
+ def connect(topic_opts: {}, queue_opts: {})
52
40
  raise "RabbitMQ connection #{connection} already open." if open?
53
41
 
54
42
  logger.info("Rabbitmq message broker connection url: #{config.redacted_url}")
@@ -72,9 +60,11 @@ module Surfliner
72
60
 
73
61
  # Opens a connection, yields the queue, and closes the connection after
74
62
  # the provided block completes.
63
+ # @param topic_opts [Hash] RabbitMQ topic options. (See Bunny::Channel#topic)
64
+ # @param queue_opts [Hash] RabbitMQ queue options. (See Bunny::Channel#queue)
75
65
  # @yield [Bunny::Queue] the queue
76
- def open
77
- connect
66
+ def open(topic_opts: {}, queue_opts: {})
67
+ connect(topic_opts:, queue_opts:)
78
68
  yield queue
79
69
  ensure
80
70
  close
@@ -111,28 +101,21 @@ module Surfliner
111
101
  config.port
112
102
  end
113
103
 
114
- # @return [Hash] Options passed when connecting to RabbitMQ topic
115
- def topic_opts
116
- opts[:topic]
104
+ # @return [String] The routing key
105
+ def routing_key
106
+ config.routing_key
117
107
  end
118
108
 
119
- # @return [Hash] Options passed when connecting to RabbitMQ queue
120
- def queue_opts
121
- opts[:queue]
109
+ # Publishes the specified payload
110
+ # @param payload [String] the payload to publish
111
+ # @return [Bunny::Exchange] see #exchange
112
+ def publish(payload)
113
+ logger.info "Publishing to #{routing_key} with payload: #{payload}"
114
+ exchange.publish(payload, routing_key:)
122
115
  end
123
116
 
124
117
  private
125
118
 
126
- def merge_opts(opts)
127
- DEFAULT_OPTS.to_h do |opt_type, opts_default|
128
- opts_actual = opts_default.dup
129
- if opts && (opts_provided = opts[opt_type])
130
- opts_actual.merge!(opts_provided)
131
- end
132
- [opt_type, opts_actual]
133
- end
134
- end
135
-
136
119
  def connect_on(connection, timeout = 120)
137
120
  timer = 0
138
121
  logger.info "Trying to open queue connection with timeout=#{timeout}"
@@ -3,6 +3,6 @@ module Surfliner
3
3
  # Parent module for this gem
4
4
  module MetadataConsumer
5
5
  # The gem version
6
- VERSION = "0.1.0.pre.alpha.2"
6
+ VERSION = "0.1.0.pre.alpha.4"
7
7
  end
8
8
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: surfliner-metadata_consumer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.pre.alpha.2
4
+ version: 0.1.0.pre.alpha.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Project Surfliner
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-03-07 00:00:00.000000000 Z
10
+ date: 2025-03-17 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: bunny
@@ -279,7 +279,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
279
279
  requirements:
280
280
  - - ">="
281
281
  - !ruby/object:Gem::Version
282
- version: 3.3.1
282
+ version: '3.2'
283
283
  required_rubygems_version: !ruby/object:Gem::Requirement
284
284
  requirements:
285
285
  - - ">="