railway-ipc 4.0.1 → 5.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8fa6ce7e4b6f8667fa4939cc334dd66845c39e5f357bd4887eb030b7f4edcf3a
4
- data.tar.gz: ea8f959e0cf43ed38b71276baac73c4c4e417ee8d4323d47605390a95d573c53
3
+ metadata.gz: a50920a8e02fc13ab3c9afef0761aff015d6acd1d5b252d4dd63e5398954cd87
4
+ data.tar.gz: 8f30819cb0a237b4af1761cb81387b5d0377a788355432f708bf88953a209add
5
5
  SHA512:
6
- metadata.gz: e76cd2483ea799dd04f7acc27cd5f7799a6f7bd6d6e9bc6e64c08e0a621f55ad6e9ba37fb53c685fea4dd8847b78bde3b73bb97091d9f3764d15c3ce5237c84b
7
- data.tar.gz: 62955dfb46eb250156ff8d9c1c9c1570169bc1c45742ca231dbbceadeb091f71439793645620cad63ba5e0c21e393894aa13d96444ac0da4f440c0b7179076a7
6
+ metadata.gz: 6b2981894fb61a8fd32d66a309f44164d3007f1c1c52f9c743cc18a2526d17f01e60bdd85f0787ad2ae6bca39e068650bb71eafb7ea1f2033550191fd4c103ee
7
+ data.tar.gz: e35e1ad6e26ca87816df9dd5acefb9851c65cf66eee9fa9a69d8d6cf0b3dc4c27c7770ca81e7c43cf638b081c844a8ca64e78987f4df9a5f8119cac4cc60c1aa
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.6.5
1
+ 2.7.2
data/CHANGELOG.md CHANGED
@@ -1,8 +1,7 @@
1
1
  # Changelog
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
- and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
4
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
5
 
7
6
  ## [Unreleased]
8
7
  ### Added
@@ -10,6 +9,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
10
9
  ### Removed
11
10
  ### Fixed
12
11
 
12
+ ## [5.1.1] - 2022-09-09
13
+ ### Fixed
14
+ * Made `google-protobuf` dependency explicit
15
+
16
+ ## [5.0.0] - 2021-02-17
17
+ ### Added
18
+ * Message encoders. Messages can now be encoded using either binary protobufs (the default) or JSON protobufs.
19
+ * `RailwayIpc::OutgoingMessage` abstraction that encapsulates everything about a message to be published.
20
+
21
+ ### Changed
22
+ * `Publisher#publish` now takes an optional `format` parameter that specifies how the message should be encoded. It is added to the message header when the message is published. The default format is `binary_protobuf`.
23
+ * (Breaking change) `Publisher#publish` now returns an `OutgoingMessage` instead of a `Bunny::Exchange`.
24
+ * Refactor `PublishedMessage#store_message` to take an `OutgoingMessage`.
25
+
26
+ ### Removed
27
+ * (Breaking change) Remove deprecated `SingletonPublisher`
28
+
13
29
  ## [4.0.1] - 2021-01-12
14
30
  ### Fixed
15
31
  * Fixed `undefined method fetch for Bunny::MessageProperties` error. `Bunny::MessageProperties` isn't really a Hash, it wraps one (and doesn't provide a `#fetch` method).
@@ -100,7 +116,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
100
116
  ### Added
101
117
  - Correlation ID and message UUID are auto generated for messages for IDs are not passed in [#23](https://github.com/learn-co/railway_ipc_gem/pull/23)
102
118
 
103
- [Unreleased]: https://github.com/learn-co/railway_ipc_gem/compare/v4.0.1...HEAD
119
+ [Unreleased]: https://github.com/learn-co/railway_ipc_gem/compare/v5.1.1...HEAD
120
+ [5.1.1]: https://github.com/learn-co/railway_ipc_gem/compare/v5.1.0...v5.1.1
121
+ [5.0.0]: https://github.com/learn-co/railway_ipc_gem/compare/v4.0.1...v5.0.0
104
122
  [4.0.1]: https://github.com/learn-co/railway_ipc_gem/compare/v4.0.0...v4.0.1
105
123
  [4.0.0]: https://github.com/learn-co/railway_ipc_gem/compare/v3.0.0...v4.0.0
106
124
  [3.0.0]: https://github.com/learn-co/railway_ipc_gem/compare/v2.2.2...v3.0.0
@@ -61,7 +61,7 @@ module RailwayIpc
61
61
  # override them. -BN
62
62
  def work_with_params(payload, _delivery_info, metadata)
63
63
  headers = metadata.headers || {}
64
- message_format = headers.fetch('message_format', 'protobuf_binary')
64
+ message_format = headers.fetch('message_format', 'binary_protobuf')
65
65
 
66
66
  message = RailwayIpc::IncomingMessage.new(payload, message_format: message_format)
67
67
  RailwayIpc::ProcessIncomingMessage.call(self, message)
@@ -47,8 +47,8 @@ module RailwayIpc
47
47
 
48
48
  def get_decoder(name)
49
49
  {
50
- 'protobuf_binary' => RailwayIpc::MessageDecoders::ProtobufBinaryDecoder,
51
- 'protobuf_json' => RailwayIpc::MessageDecoders::ProtobufJsonDecoder
50
+ 'binary_protobuf' => RailwayIpc::MessageDecoders::ProtobufBinaryDecoder,
51
+ 'json_protobuf' => RailwayIpc::MessageDecoders::ProtobufJsonDecoder
52
52
  }.fetch(name, DEFAULT_DECODER)
53
53
  end
54
54
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailwayIpc
4
+ module MessageEncoders
5
+ ProtobufBinaryEncoder = lambda do |message|
6
+ {
7
+ type: message.type,
8
+ encoded_message: Base64.encode64(message.proto.class.encode(message.proto))
9
+ }.to_json
10
+ rescue NoMethodError
11
+ raise RailwayIpc::InvalidProtobuf.new("Message #{message} is not a valid protobuf")
12
+ end
13
+
14
+ ProtobufJsonEncoder = lambda do |message|
15
+ {
16
+ type: message.type,
17
+ encoded_message: message.proto.to_h
18
+ }.to_json
19
+ rescue NoMethodError
20
+ raise RailwayIpc::InvalidProtobuf.new("Message #{message} is not a valid protobuf")
21
+ end
22
+ end
23
+ end
@@ -54,8 +54,18 @@ module RailwayIpc
54
54
 
55
55
  private
56
56
 
57
+ # rails <= 5.1 uses this method to know the name of the created_at/updated_at fields
57
58
  def timestamp_attributes_for_create
58
59
  super << :inserted_at
59
60
  end
61
+
62
+ # rails >= 6.0 moved this to the class level and uses strings instead of symbols
63
+ class << self
64
+ private
65
+
66
+ def timestamp_attributes_for_create
67
+ super << 'inserted_at'
68
+ end
69
+ end
60
70
  end
61
71
  end
@@ -7,23 +7,32 @@ module RailwayIpc
7
7
 
8
8
  validates :uuid, :status, presence: true
9
9
 
10
- def self.store_message(exchange_name, message)
11
- encoded_message = RailwayIpc::Rabbitmq::Payload.encode(message)
10
+ def self.store_message(outgoing_message)
12
11
  create!(
13
- uuid: message.uuid,
14
- message_type: message.class.to_s,
15
- user_uuid: message.user_uuid,
16
- correlation_id: message.correlation_id,
17
- encoded_message: encoded_message,
12
+ uuid: outgoing_message.uuid,
13
+ message_type: outgoing_message.type,
14
+ user_uuid: outgoing_message.user_uuid,
15
+ correlation_id: outgoing_message.correlation_id,
16
+ encoded_message: outgoing_message.encoded,
18
17
  status: 'sent',
19
- exchange: exchange_name
18
+ exchange: outgoing_message.exchange
20
19
  )
21
20
  end
22
21
 
23
22
  private
24
23
 
24
+ # rails <= 5.1 uses this method to know the name of the created_at/updated_at fields
25
25
  def timestamp_attributes_for_create
26
26
  super << :inserted_at
27
27
  end
28
+
29
+ # rails >= 6.0 moved this to the class level and uses strings instead of symbols
30
+ class << self
31
+ private
32
+
33
+ def timestamp_attributes_for_create
34
+ super << 'inserted_at'
35
+ end
36
+ end
28
37
  end
29
38
  end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailwayIpc
4
+ class OutgoingMessage
5
+ extend Forwardable
6
+
7
+ attr_reader :proto, :exchange, :format
8
+
9
+ def_delegators :@proto, :uuid, :user_uuid, :correlation_id
10
+
11
+ def initialize(proto, exchange, format=nil)
12
+ proto.uuid = SecureRandom.uuid if proto.uuid.blank?
13
+ proto.correlation_id = SecureRandom.uuid if proto.correlation_id.blank?
14
+ @proto = proto
15
+ @exchange = exchange
16
+ @format = format
17
+ end
18
+
19
+ def type
20
+ proto.class.to_s
21
+ end
22
+
23
+ def encoded
24
+ @encoded ||= encoder.call(self)
25
+ end
26
+
27
+ private
28
+
29
+ DEFAULT_ENCODER = RailwayIpc::MessageEncoders::ProtobufBinaryEncoder
30
+
31
+ def encoder
32
+ {
33
+ 'binary_protobuf' => RailwayIpc::MessageEncoders::ProtobufBinaryEncoder,
34
+ 'json_protobuf' => RailwayIpc::MessageEncoders::ProtobufJsonEncoder
35
+ }.fetch(format, DEFAULT_ENCODER)
36
+ end
37
+ end
38
+ end
@@ -1,55 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module RailwayIpc
4
- class SingletonPublisher < Sneakers::Publisher
5
- include ::Singleton
6
-
7
- def self.exchange(exchange)
8
- @exchange_name = exchange
9
- end
10
-
11
- def self.exchange_name
12
- raise 'Subclass must set the exchange' unless @exchange_name
13
-
14
- @exchange_name
15
- end
16
-
17
- def initialize
18
- super(exchange: self.class.exchange_name, exchange_type: :fanout)
19
- end
20
-
21
- def publish(message, published_message_store=RailwayIpc::PublishedMessage)
22
- RailwayIpc.logger.warn('DEPRECATED: Use new PublisherInstance class', log_message_options)
23
- ensure_message_uuid(message)
24
- ensure_correlation_id(message)
25
- RailwayIpc.logger.info('Publishing message', log_message_options(message))
26
- result = super(RailwayIpc::Rabbitmq::Payload.encode(message))
27
- published_message_store.store_message(self.class.exchange_name, message)
28
- result
29
- rescue RailwayIpc::InvalidProtobuf => e
30
- RailwayIpc.logger.error('Invalid protobuf', log_message_options(message))
31
- raise e
32
- end
33
-
34
- private
35
-
36
- def ensure_message_uuid(message)
37
- message.uuid = SecureRandom.uuid if message.uuid.blank?
38
- message
39
- end
40
-
41
- def ensure_correlation_id(message)
42
- message.correlation_id = SecureRandom.uuid if message.correlation_id.blank?
43
- message
44
- end
45
-
46
- def log_message_options(message=nil)
47
- options = { feature: 'railway_ipc_publisher', exchange: self.class.exchange_name }
48
- message.nil? ? options : options.merge(protobuf: { type: message.class, data: message })
49
- end
50
- end
51
- end
52
-
53
3
  module RailwayIpc
54
4
  class Publisher
55
5
  attr_reader :exchange_name, :message_store
@@ -60,13 +10,12 @@ module RailwayIpc
60
10
  end
61
11
 
62
12
  # rubocop:disable Metrics/AbcSize
63
- def publish(message)
64
- message.uuid = SecureRandom.uuid if message.uuid.blank?
65
- message.correlation_id = SecureRandom.uuid if message.correlation_id.blank?
13
+ def publish(message, format='binary_protobuf')
14
+ outgoing_message = OutgoingMessage.new(message, exchange_name, format)
15
+ stored_message = message_store.store_message(outgoing_message)
66
16
  RailwayIpc.logger.info('Publishing message', log_message_options(message))
67
-
68
- stored_message = message_store.store_message(exchange_name, message)
69
- exchange.publish(RailwayIpc::Rabbitmq::Payload.encode(message))
17
+ exchange.publish(outgoing_message.encoded, headers: { message_format: format })
18
+ outgoing_message
70
19
  rescue RailwayIpc::InvalidProtobuf => e
71
20
  RailwayIpc.logger.error('Invalid protobuf', log_message_options(message))
72
21
  raise e
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailwayIpc
4
- VERSION = '4.0.1'
4
+ VERSION = '5.1.1'
5
5
  end
data/lib/railway_ipc.rb CHANGED
@@ -14,8 +14,10 @@ require 'railway_ipc/unknown_message.pb'
14
14
  require 'railway_ipc/rabbitmq/adapter'
15
15
  require 'railway_ipc/handler'
16
16
  require 'railway_ipc/handler_store'
17
+ require 'railway_ipc/message_encoders'
17
18
  require 'railway_ipc/message_decoders'
18
19
  require 'railway_ipc/incoming_message'
20
+ require 'railway_ipc/outgoing_message'
19
21
  require 'railway_ipc/connection_manager'
20
22
  require 'railway_ipc/publisher'
21
23
  require 'railway_ipc/responder'
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class AddRailwayIpcConsumedMessages < ActiveRecord::Migration
3
+ class AddRailwayIpcConsumedMessages < ActiveRecord::Migration[4.2]
4
4
  def change
5
5
  create_table :railway_ipc_consumed_messages do |t|
6
6
  t.uuid :uuid, null: false
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class AddRailwayIpcPublishedMessages < ActiveRecord::Migration
3
+ class AddRailwayIpcPublishedMessages < ActiveRecord::Migration[4.2]
4
4
  def change
5
5
  create_table :railway_ipc_published_messages, id: false do |t|
6
6
  t.uuid :uuid, null: false
data/railway_ipc.gemspec CHANGED
@@ -42,14 +42,15 @@ Gem::Specification.new do |spec|
42
42
  spec.add_development_dependency 'rubocop', '~> 0.86'
43
43
 
44
44
  spec.add_dependency 'bunny', '~> 2.2.0'
45
+ spec.add_dependency 'google-protobuf', '> 3.7'
45
46
  spec.add_dependency 'sneakers', '~> 2.3.5'
46
47
 
47
48
  # Setup for testing Rails type code within mock Rails app
48
49
  spec.add_development_dependency 'database_cleaner', '~> 1.7'
49
50
  spec.add_development_dependency 'listen', '~> 3.0.5'
50
- spec.add_development_dependency 'pg', '~> 0.18'
51
+ spec.add_development_dependency 'pg', '~> 1.1'
51
52
  spec.add_development_dependency 'pry', '~> 0.13'
52
- spec.add_development_dependency 'rails', '~> 5.0.7'
53
+ spec.add_development_dependency 'rails', '~> 6.0'
53
54
  spec.add_development_dependency 'rspec-rails'
54
55
  spec.add_development_dependency 'shoulda-matchers', '~> 4.2'
55
56
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: railway-ipc
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.1
4
+ version: 5.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - ''
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-01-12 00:00:00.000000000 Z
11
+ date: 2022-09-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: 2.2.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: google-protobuf
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">"
116
+ - !ruby/object:Gem::Version
117
+ version: '3.7'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">"
123
+ - !ruby/object:Gem::Version
124
+ version: '3.7'
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: sneakers
113
127
  requirement: !ruby/object:Gem::Requirement
@@ -156,14 +170,14 @@ dependencies:
156
170
  requirements:
157
171
  - - "~>"
158
172
  - !ruby/object:Gem::Version
159
- version: '0.18'
173
+ version: '1.1'
160
174
  type: :development
161
175
  prerelease: false
162
176
  version_requirements: !ruby/object:Gem::Requirement
163
177
  requirements:
164
178
  - - "~>"
165
179
  - !ruby/object:Gem::Version
166
- version: '0.18'
180
+ version: '1.1'
167
181
  - !ruby/object:Gem::Dependency
168
182
  name: pry
169
183
  requirement: !ruby/object:Gem::Requirement
@@ -184,14 +198,14 @@ dependencies:
184
198
  requirements:
185
199
  - - "~>"
186
200
  - !ruby/object:Gem::Version
187
- version: 5.0.7
201
+ version: '6.0'
188
202
  type: :development
189
203
  prerelease: false
190
204
  version_requirements: !ruby/object:Gem::Requirement
191
205
  requirements:
192
206
  - - "~>"
193
207
  - !ruby/object:Gem::Version
194
- version: 5.0.7
208
+ version: '6.0'
195
209
  - !ruby/object:Gem::Dependency
196
210
  name: rspec-rails
197
211
  requirement: !ruby/object:Gem::Requirement
@@ -249,8 +263,10 @@ files:
249
263
  - lib/railway_ipc/incoming_message.rb
250
264
  - lib/railway_ipc/logger.rb
251
265
  - lib/railway_ipc/message_decoders.rb
266
+ - lib/railway_ipc/message_encoders.rb
252
267
  - lib/railway_ipc/models/consumed_message.rb
253
268
  - lib/railway_ipc/models/published_message.rb
269
+ - lib/railway_ipc/outgoing_message.rb
254
270
  - lib/railway_ipc/publisher.rb
255
271
  - lib/railway_ipc/rabbitmq/adapter.rb
256
272
  - lib/railway_ipc/rabbitmq/payload.rb
@@ -295,7 +311,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
295
311
  - !ruby/object:Gem::Version
296
312
  version: '0'
297
313
  requirements: []
298
- rubygems_version: 3.0.3
314
+ rubygems_version: 3.0.6
299
315
  signing_key:
300
316
  specification_version: 4
301
317
  summary: IPC components for Rails