pheme 1.0.0 → 1.1.0

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
  SHA1:
3
- metadata.gz: 5bb62b021efbad7c81eabfe53f32641b051ab355
4
- data.tar.gz: b45731fc261b7b7f5505e906f1d720cb99cc7259
3
+ metadata.gz: 0d342e13ae80846b1d4ac3949eb1e94d7f930ec4
4
+ data.tar.gz: 074d2404d1a56ba15250c45537aa08c3b6f295cc
5
5
  SHA512:
6
- metadata.gz: f3bbbff1509ad02bd38216a4748a7c74cf11deb751b394644aced095789e16e698768163f29d7adeab4577ddfcf1d9081d9b84b95917372dec51b6653862a6c6
7
- data.tar.gz: f1f5e2765cea3ef16e838c191a37c5f224f05d926fcb4ee18565ecc91a994857cc31e2bb6a625f2882a524ad0118cb2ebc3371c39cac859f78eecc09a4dd506b
6
+ metadata.gz: f722c25ea54c1d75906e23fa13232f8d071863f42c41c0f0b06263ead813ce4166935068d477ff399a7e1803f9b473fcf9d3228bec84f9ad1659989e8b02ad40
7
+ data.tar.gz: e5f3784d480fc108c0861e0705e74c554fb05eb6759a7549e002dc98c1fb38ff58649b7b03af70477fc8007dd6306a5b62db7653c8bca710d298cb83aa8549fe
@@ -0,0 +1,27 @@
1
+ require 'base64'
2
+ require 'zlib'
3
+
4
+ module Pheme
5
+ module Compression
6
+ def compress(body)
7
+ gz = Zlib::GzipWriter.new(StringIO.new)
8
+ gz << body
9
+ Base64.encode64(gz.close.string)
10
+ end
11
+
12
+ def decompress(body)
13
+ return Zlib::GzipReader.new(StringIO.new(Base64.decode64(body))).read if gzip?(body)
14
+ body
15
+ end
16
+
17
+ private
18
+
19
+ # https://tools.ietf.org/html/rfc1952#page-6
20
+ GZIP_MAGIC_NUMBER = "\037\213".unpack('n').freeze
21
+
22
+ def gzip?(body)
23
+ # Decode the first 4 bytes to compare with magic number
24
+ Base64.decode64(body[0..4]).unpack('n') == GZIP_MAGIC_NUMBER
25
+ end
26
+ end
27
+ end
@@ -1,5 +1,9 @@
1
+ require_relative 'compression'
2
+
1
3
  module Pheme
2
4
  class QueuePoller
5
+ include Compression
6
+
3
7
  attr_accessor :queue_url, :queue_poller, :connection_pool_block, :format, :max_messages, :poller_configuration
4
8
 
5
9
  def initialize(queue_url:, connection_pool_block: false, max_messages: nil, format: :json, poller_configuration: {}, sqs_client: nil)
@@ -84,7 +88,7 @@ module Pheme
84
88
  end
85
89
 
86
90
  def get_content(body)
87
- body['Message']
91
+ decompress(body['Message'])
88
92
  end
89
93
 
90
94
  def parse_csv(message_contents)
@@ -1,5 +1,20 @@
1
+ require_relative 'compression'
2
+
1
3
  module Pheme
2
4
  class TopicPublisher
5
+ include Compression
6
+
7
+ #
8
+ # Constant with message size limit.
9
+ # The message size also includes some metadata: 'name' and 'type'.
10
+ # We give ourselves a buffer for this metadata.
11
+ #
12
+ # Source: https://docs.aws.amazon.com/sns/latest/dg/SNSMessageAttributes.html#SNSMessageAttributesNTV
13
+ #
14
+ SNS_SIZE_LIMIT = 256.kilobytes
15
+ EXPECTED_METADATA_SIZE = 1.kilobyte
16
+ MESSAGE_SIZE_LIMIT = SNS_SIZE_LIMIT - EXPECTED_METADATA_SIZE
17
+
3
18
  attr_accessor :topic_arn
4
19
 
5
20
  def initialize(topic_arn:)
@@ -23,8 +38,11 @@ module Pheme
23
38
  end
24
39
 
25
40
  def serialize(message)
26
- return message if message.is_a? String
27
- message.to_json
41
+ message = message.to_json unless message.is_a? String
42
+
43
+ return compress(message) if message.bytesize > MESSAGE_SIZE_LIMIT
44
+
45
+ message
28
46
  end
29
47
  end
30
48
  end
@@ -1,3 +1,3 @@
1
1
  module Pheme
2
- VERSION = "1.0.0".freeze
2
+ VERSION = "1.1.0".freeze
3
3
  end
@@ -90,6 +90,17 @@ describe Pheme::QueuePoller do
90
90
  expect(subject.first.first.test).to eq('test')
91
91
  end
92
92
  end
93
+
94
+ context "with compressed body" do
95
+ let(:format) { :json }
96
+ let(:message) do
97
+ gz = Zlib::GzipWriter.new(StringIO.new)
98
+ gz << { test: 'test' }.to_json
99
+ Base64.encode64(gz.close.string)
100
+ end
101
+
102
+ its([:test]) { is_expected.to eq('test') }
103
+ end
93
104
  end
94
105
 
95
106
  describe "#poll" do
@@ -44,5 +44,29 @@ describe Pheme::TopicPublisher do
44
44
  subject.publish(message)
45
45
  end
46
46
  end
47
+
48
+ context 'with message too large' do
49
+ let(:topic_arn) { "arn:aws:sns:anything" }
50
+ let(:message) { 'x' * (described_class::MESSAGE_SIZE_LIMIT + 1) }
51
+
52
+ subject { Pheme::TopicPublisher.new(topic_arn: topic_arn).publish(message) }
53
+
54
+ let(:compressed_message) do
55
+ gz = Zlib::GzipWriter.new(StringIO.new)
56
+ gz << message
57
+ Base64.encode64(gz.close.string)
58
+ end
59
+
60
+ it "publishes gzipped, base64 encoded message" do
61
+ expect(Pheme.configuration.sns_client).to(
62
+ receive(:publish)
63
+ .with({
64
+ topic_arn: topic_arn,
65
+ message: compressed_message,
66
+ }))
67
+
68
+ subject
69
+ end
70
+ end
47
71
  end
48
72
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pheme
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Graham
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-17 00:00:00.000000000 Z
11
+ date: 2018-05-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -157,6 +157,7 @@ files:
157
157
  - README.md
158
158
  - circle.yml
159
159
  - lib/pheme.rb
160
+ - lib/pheme/compression.rb
160
161
  - lib/pheme/configuration.rb
161
162
  - lib/pheme/logger.rb
162
163
  - lib/pheme/message_handler.rb
@@ -199,7 +200,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
199
200
  version: '0'
200
201
  requirements: []
201
202
  rubyforge_project:
202
- rubygems_version: 2.5.1
203
+ rubygems_version: 2.6.13
203
204
  signing_key:
204
205
  specification_version: 4
205
206
  summary: Ruby SNS publisher + SQS poller & message handler