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 +4 -4
- data/CHANGES.md +11 -0
- data/Gemfile.lock +1 -1
- data/bin/daylight-index-listen +9 -11
- data/bin/simulate-publish-event +43 -20
- data/lib/surfliner/metadata_consumer/consumer.rb +18 -19
- data/lib/surfliner/metadata_consumer/mq_connection.rb +17 -34
- data/lib/surfliner/metadata_consumer/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fac43306c988b19a28f9cb92449724b7cb326a787f54c7da78c9b134a61220aa
|
4
|
+
data.tar.gz: af91a86d088e4b863425a45faf97b2473cbca69cb17178d75d4bcce19d79384a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
data/bin/daylight-index-listen
CHANGED
@@ -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
|
-
|
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
|
-
|
20
|
-
|
21
|
-
|
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::
|
21
|
+
handler = Surfliner::MetadataConsumer::Solr::MessageHandler
|
22
|
+
consumer = Surfliner::MetadataConsumer::Consumer.new(tracer:, logger:, handler:)
|
23
|
+
consumer.run
|
data/bin/simulate-publish-event
CHANGED
@@ -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
|
6
|
+
require "surfliner/metadata_consumer"
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
module Surfliner
|
9
|
+
module MetadataConsumer
|
10
|
+
class Publisher
|
12
11
|
|
13
|
-
|
12
|
+
attr_reader :logger
|
13
|
+
attr_reader :topic_opts
|
14
|
+
attr_reader :queue_opts
|
14
15
|
|
15
|
-
|
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 |
|
19
|
-
|
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
|
-
|
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
|
-
|
17
|
-
|
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
|
-
|
35
|
-
|
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
|
-
|
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
|
-
|
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 [
|
115
|
-
def
|
116
|
-
|
104
|
+
# @return [String] The routing key
|
105
|
+
def routing_key
|
106
|
+
config.routing_key
|
117
107
|
end
|
118
108
|
|
119
|
-
#
|
120
|
-
|
121
|
-
|
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}"
|