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

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: fac43306c988b19a28f9cb92449724b7cb326a787f54c7da78c9b134a61220aa
4
+ data.tar.gz: af91a86d088e4b863425a45faf97b2473cbca69cb17178d75d4bcce19d79384a
5
5
  SHA512:
6
- metadata.gz: f19622750625a84977122fa344b8635bac1d6f80de562237505be22f82aa3acbc532d53f768f0f3b9b7dbda84724d1979b9396e785dca25d30216b71b8746c65
7
- data.tar.gz: 47621bc83433c05a36cd0d15a3b3a526eb981b0bd1085014c5179ea7c1dce0ad0a12722895873d629bfc1a510cb3648d1a5b2695d1b797d9960befcbb90e517e
6
+ metadata.gz: ea1dbf415bd4339f875562a7f629ea432915e3dc1b511ba1268765069db0227031dc5eb71e2acfcb7f4b5c434a3c82ba88b4cc266dec94b94479462ae3721781
7
+ data.tar.gz: d0840fc308daec6d1ed9f22038f62e2ed4974ea450054b3bec580e1a28f8aff52c5081cfd600e46137546785cc726a420190b0bdf82a0eb7f0c2db5fa447736b
data/CHANGES.md CHANGED
@@ -1,3 +1,14 @@
1
+ # 0.1.0.pre.alpha.3 (2025-03-07)
2
+
3
+ - improve topic/queue option override API
4
+ - clean up binscripts
5
+
6
+ # 0.1.0.pre.alpha.2 (2025-03-07)
7
+
8
+ - use METADATA_API_URL_BASE cf. surfliner apps
9
+ - allow overriding topic and queue options
10
+ - don't close channel if already closed
11
+
1
12
  # 0.1.0.pre.alpha.1 (2025-02-12)
2
13
 
3
14
  - 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.3)
5
5
  bunny (~> 2.23)
6
6
  opentelemetry-exporter-otlp (~> 0.26.3)
7
7
  opentelemetry-instrumentation-all (~> 0.60.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.3"
7
7
  end
8
8
  end
metadata CHANGED
@@ -1,7 +1,7 @@
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.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Project Surfliner