surfliner-metadata_consumer 0.1.0.pre.alpha.1 → 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 +0 -1
- data/Gemfile.lock +12 -12
- data/README.md +2 -2
- data/bin/daylight-index-listen +9 -9
- data/bin/simulate-publish-event +44 -19
- data/lib/surfliner/metadata_consumer/consumer.rb +16 -15
- data/lib/surfliner/metadata_consumer/mq_connection.rb +27 -6
- data/lib/surfliner/metadata_consumer/version.rb +1 -1
- metadata +2 -2
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
CHANGED
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.
|
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)
|
@@ -13,7 +13,7 @@ GEM
|
|
13
13
|
specs:
|
14
14
|
addressable (2.8.7)
|
15
15
|
public_suffix (>= 2.0.2, < 7.0)
|
16
|
-
amq-protocol (2.3.
|
16
|
+
amq-protocol (2.3.3)
|
17
17
|
ast (2.4.2)
|
18
18
|
bigdecimal (3.1.9)
|
19
19
|
builder (3.3.0)
|
@@ -34,7 +34,7 @@ GEM
|
|
34
34
|
debug (1.9.2)
|
35
35
|
irb (~> 1.10)
|
36
36
|
reline (>= 0.3.8)
|
37
|
-
diff-lcs (1.
|
37
|
+
diff-lcs (1.6.0)
|
38
38
|
docile (1.4.1)
|
39
39
|
dotenv (2.8.1)
|
40
40
|
faraday (2.12.2)
|
@@ -55,11 +55,11 @@ GEM
|
|
55
55
|
json (2.10.1)
|
56
56
|
language_server-protocol (3.17.0.4)
|
57
57
|
lint_roller (1.1.0)
|
58
|
-
logger (1.6.
|
58
|
+
logger (1.6.6)
|
59
59
|
net-http (0.6.0)
|
60
60
|
uri
|
61
|
-
opentelemetry-api (1.
|
62
|
-
opentelemetry-common (0.
|
61
|
+
opentelemetry-api (1.5.0)
|
62
|
+
opentelemetry-common (0.22.0)
|
63
63
|
opentelemetry-api (~> 1.0)
|
64
64
|
opentelemetry-exporter-otlp (0.26.3)
|
65
65
|
google-protobuf (~> 3.14)
|
@@ -245,14 +245,14 @@ GEM
|
|
245
245
|
opentelemetry-helpers-sql-obfuscation
|
246
246
|
opentelemetry-instrumentation-base (~> 0.22.1)
|
247
247
|
opentelemetry-semantic_conventions (>= 1.8.0)
|
248
|
-
opentelemetry-registry (0.
|
248
|
+
opentelemetry-registry (0.4.0)
|
249
249
|
opentelemetry-api (~> 1.1)
|
250
250
|
opentelemetry-sdk (1.4.1)
|
251
251
|
opentelemetry-api (~> 1.1)
|
252
252
|
opentelemetry-common (~> 0.20)
|
253
253
|
opentelemetry-registry (~> 0.2)
|
254
254
|
opentelemetry-semantic_conventions
|
255
|
-
opentelemetry-semantic_conventions (1.
|
255
|
+
opentelemetry-semantic_conventions (1.11.0)
|
256
256
|
opentelemetry-api (~> 1.0)
|
257
257
|
parallel (1.26.3)
|
258
258
|
parser (3.3.7.1)
|
@@ -274,7 +274,7 @@ GEM
|
|
274
274
|
regexp_parser (2.10.0)
|
275
275
|
reline (0.6.0)
|
276
276
|
io-console (~> 0.5)
|
277
|
-
rexml (3.4.
|
277
|
+
rexml (3.4.1)
|
278
278
|
rsolr (2.6.0)
|
279
279
|
builder (>= 2.1.2)
|
280
280
|
faraday (>= 0.9, < 3, != 2.0.0)
|
@@ -301,7 +301,7 @@ GEM
|
|
301
301
|
rubocop-ast (>= 1.38.0, < 2.0)
|
302
302
|
ruby-progressbar (~> 1.7)
|
303
303
|
unicode-display_width (>= 2.4.0, < 4.0)
|
304
|
-
rubocop-ast (1.38.
|
304
|
+
rubocop-ast (1.38.1)
|
305
305
|
parser (>= 3.3.1.0)
|
306
306
|
rubocop-performance (1.23.1)
|
307
307
|
rubocop (>= 1.48.1, < 2.0)
|
@@ -332,11 +332,11 @@ GEM
|
|
332
332
|
standard-performance (1.6.0)
|
333
333
|
lint_roller (~> 1.1)
|
334
334
|
rubocop-performance (~> 1.23.0)
|
335
|
-
stringio (3.1.
|
335
|
+
stringio (3.1.5)
|
336
336
|
unicode-display_width (3.1.4)
|
337
337
|
unicode-emoji (~> 4.0, >= 4.0.4)
|
338
338
|
unicode-emoji (4.0.4)
|
339
|
-
uri (1.0.
|
339
|
+
uri (1.0.3)
|
340
340
|
webmock (3.25.0)
|
341
341
|
addressable (>= 2.8.0)
|
342
342
|
crack (>= 0.3.2)
|
data/README.md
CHANGED
@@ -61,11 +61,11 @@ a configured `SOLR_URL`, e.g.:
|
|
61
61
|
SOLR_URL=http://admin:admin@solr:8983/solr/daylight-dev
|
62
62
|
```
|
63
63
|
|
64
|
-
The `bin/simulate-publish-event` script expects an `
|
64
|
+
The `bin/simulate-publish-event` script expects an `METADATA_API_URL_BASE`, used to generate resource URLs
|
65
65
|
for provided IDs:
|
66
66
|
|
67
67
|
```sh
|
68
|
-
|
68
|
+
METADATA_API_URL_BASE=http://superskunk:3000/resources
|
69
69
|
```
|
70
70
|
|
71
71
|
## Solr / Daylight handler implementation
|
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,9 +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
|
-
|
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
|
22
20
|
|
23
|
-
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,31 +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
|
|
16
|
+
def initialize(logger:, topic_opts: {}, queue_opts: {})
|
17
|
+
@logger = logger
|
18
|
+
@topic_opts = topic_opts
|
19
|
+
@queue_opts = queue_opts
|
20
|
+
end
|
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:)
|
15
50
|
begin
|
16
|
-
ARGV.each do |
|
17
|
-
|
18
|
-
{resourceUrl: "#{api_base}/resources/#{id}",
|
19
|
-
status: :published,
|
20
|
-
time_stamp: DateTime.now}.to_json
|
21
|
-
|
22
|
-
logger.info "Publishing to #{connection.routing_key} with #{payload}"
|
23
|
-
connection.exchange.publish(payload, routing_key: connection.routing_key)
|
51
|
+
ARGV.each do |resource_id|
|
52
|
+
publisher.publish(resource_id)
|
24
53
|
end
|
25
54
|
ensure
|
26
|
-
|
27
|
-
connection&.channel
|
28
|
-
ensure
|
29
|
-
connection&.close
|
30
|
-
end
|
55
|
+
publisher.connection.close
|
31
56
|
end
|
@@ -20,28 +20,29 @@ module Surfliner
|
|
20
20
|
@handler = handler
|
21
21
|
end
|
22
22
|
|
23
|
-
# Initializes and starts a new `Consumer`
|
24
|
-
# @param tracer [OpenTelemetry::Trace::Tracer] OpenTelemetry tracer
|
25
|
-
# @param logger [Logger] log message destination
|
26
|
-
# @param handler #handle an object accepting a JSON string payload
|
27
|
-
def self.run(tracer:, logger:, handler:)
|
28
|
-
new(tracer:, logger:, handler:).run
|
29
|
-
end
|
30
|
-
|
31
23
|
# Starts listening to the message queue and passing messages to the handler.
|
32
|
-
|
33
|
-
|
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|
|
34
28
|
queue.subscribe(block: true) do |_delivery_info, _properties, payload_json|
|
35
29
|
tracer.in_span("surfliner metadata consumer message") do |_span|
|
36
|
-
|
37
|
-
|
38
|
-
handler.handle(payload_json)
|
30
|
+
handle(payload_json)
|
39
31
|
end
|
40
|
-
rescue => err
|
41
|
-
logger.error(" [❌] failed to handle message: #{err}\n#{err.backtrace}")
|
42
32
|
end
|
43
33
|
end
|
44
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
|
45
46
|
end
|
46
47
|
end
|
47
48
|
end
|
@@ -32,17 +32,19 @@ module Surfliner
|
|
32
32
|
end
|
33
33
|
|
34
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)
|
35
37
|
# @return [self]
|
36
38
|
# @raise RuntimeError if already connected
|
37
|
-
def connect
|
39
|
+
def connect(topic_opts: {}, queue_opts: {})
|
38
40
|
raise "RabbitMQ connection #{connection} already open." if open?
|
39
41
|
|
40
42
|
logger.info("Rabbitmq message broker connection url: #{config.redacted_url}")
|
41
43
|
@connection = Bunny.new(config.connection_url, logger: logger)
|
42
44
|
connect_on(connection)
|
43
45
|
@channel = connection.create_channel
|
44
|
-
@exchange = channel.topic(config.topic,
|
45
|
-
@queue = channel.queue(config.queue_name,
|
46
|
+
@exchange = channel.topic(config.topic, topic_opts)
|
47
|
+
@queue = channel.queue(config.queue_name, queue_opts)
|
46
48
|
queue.bind(exchange, routing_key: config.routing_key)
|
47
49
|
|
48
50
|
self
|
@@ -58,9 +60,11 @@ module Surfliner
|
|
58
60
|
|
59
61
|
# Opens a connection, yields the queue, and closes the connection after
|
60
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)
|
61
65
|
# @yield [Bunny::Queue] the queue
|
62
|
-
def open
|
63
|
-
connect
|
66
|
+
def open(topic_opts: {}, queue_opts: {})
|
67
|
+
connect(topic_opts:, queue_opts:)
|
64
68
|
yield queue
|
65
69
|
ensure
|
66
70
|
close
|
@@ -68,8 +72,12 @@ module Surfliner
|
|
68
72
|
|
69
73
|
# Closes the connection.
|
70
74
|
def close
|
71
|
-
channel
|
75
|
+
return unless channel
|
76
|
+
return if channel.closed?
|
77
|
+
logger.info("closing channel")
|
78
|
+
channel.close
|
72
79
|
ensure
|
80
|
+
logger.info("closing connection")
|
73
81
|
connection&.close
|
74
82
|
end
|
75
83
|
|
@@ -93,6 +101,19 @@ module Surfliner
|
|
93
101
|
config.port
|
94
102
|
end
|
95
103
|
|
104
|
+
# @return [String] The routing key
|
105
|
+
def routing_key
|
106
|
+
config.routing_key
|
107
|
+
end
|
108
|
+
|
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:)
|
115
|
+
end
|
116
|
+
|
96
117
|
private
|
97
118
|
|
98
119
|
def connect_on(connection, timeout = 120)
|
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.
|
4
|
+
version: 0.1.0.pre.alpha.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Project Surfliner
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-
|
10
|
+
date: 2025-03-07 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: bunny
|