propono 0.8.2 → 0.9.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: a38b1949af11e63f303a09478759c077f484d95d
4
- data.tar.gz: 7d937ce9d0e24a3e764705ed5d9f21203d094d28
3
+ metadata.gz: b1a85c42b5fc2bc691203ab82f348535476bdf35
4
+ data.tar.gz: af8fc9263c84a713779bee0e019258220102549f
5
5
  SHA512:
6
- metadata.gz: 21de4b1f7ea789868a848ae044ef43ec01dacf8869a3a89a1a33d9aab04a5ab3d6ce4a17aacf4c701262fa2a6b8bb605327c82d4294bd76ee2c7410165165e32
7
- data.tar.gz: c39b68a06d648db435b3811cba44a81811702f0aea2a87d8fa4f48d8864a047d400b34540fe7510105d7e7939313698fcd2db42f0ee5b84918f66b2402ee79cf
6
+ metadata.gz: b80edaee162402a479bff3a14cf05b56fd3e37bd5838faf7fbc040194028aa7451e12bf6b9bf551ca25fa1903a104a68083c5514b6afd6e9e137e955bcedeeb4
7
+ data.tar.gz: 994bdbb18b1cde05e45415d90ef435545a5e5647c1d8d466eee912e2b62a318677c1a0af658b1a718caee78fbcb6ffa1b46ac64707922cbc3c37f017d4ab811c
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ # 0.9.0 / Unreleased
2
+
3
+ * [FEATURE] Add message ids that track throughout Propono
4
+
1
5
  # 0.8.2 / 2013-11-01
2
6
 
3
7
  * [BUGFIX] Replace thread library with standard ruby threads to fix Unicorn problems.
data/README.md CHANGED
@@ -104,6 +104,7 @@ You then simply pass the `:udp` protocol into `publish`:
104
104
 
105
105
  ```ruby
106
106
  Propono.publish('some-topic', message, protocol: :udp)
107
+ ```
107
108
 
108
109
  As per the `listen_to_tcp` method explained above, you now listen to udp or use the proxy method:
109
110
 
data/Rakefile CHANGED
@@ -11,7 +11,7 @@ end
11
11
 
12
12
  namespace :test do
13
13
  Rake::TestTask.new(:local) do |t|
14
- t.pattern = "test/{components/,services/,}*_test.rb"
14
+ t.pattern = "test/{components/,services/,helpers/,}*_test.rb"
15
15
  end
16
16
  end
17
17
 
data/lib/propono.rb CHANGED
@@ -1,12 +1,13 @@
1
1
  # Propono
2
2
  #
3
3
  # Propono is a pub/sub gem built on top of Amazon Web Services (AWS). It uses Simple Notification Service (SNS) and Simple Queue Service (SQS) to seamlessly pass messages throughout your infrastructure.
4
-
5
4
  require "propono/version"
6
5
  require 'propono/propono_error'
7
6
  require 'propono/logger'
8
7
  require 'propono/configuration'
9
8
 
9
+ require "propono/helpers/hash"
10
+
10
11
  require 'propono/components/sns'
11
12
  require 'propono/components/sqs'
12
13
  require "propono/components/queue"
@@ -130,8 +131,8 @@ module Propono
130
131
  # This method uses #listen_to_udp and #publish to proxy
131
132
  # messages from UDP onto the queue.
132
133
  def self.proxy_udp
133
- Propono.listen_to_udp do |topic, message|
134
- Propono.publish(topic, message)
134
+ Propono.listen_to_udp do |topic, message, options = {}|
135
+ Propono.publish(topic, message, options)
135
136
  end
136
137
  end
137
138
 
@@ -140,8 +141,8 @@ module Propono
140
141
  # This method uses #listen_to_tcp and #publish to proxy
141
142
  # messages from TCP onto the queue.
142
143
  def self.proxy_tcp
143
- Propono.listen_to_tcp do |topic, message|
144
- Propono.publish(topic, message)
144
+ Propono.listen_to_tcp do |topic, message, options = {}|
145
+ Propono.publish(topic, message, options)
145
146
  end
146
147
  end
147
148
  end
@@ -0,0 +1,10 @@
1
+ class Hash
2
+ def symbolize_keys
3
+ inject({}) do |result, (key, value)|
4
+ new_key = key.is_a?(String) ? key.to_sym : key
5
+ new_value = value.is_a?(Hash) ? value.symbolize_keys : value
6
+ result[new_key] = new_value
7
+ result
8
+ end
9
+ end
10
+ end
@@ -11,19 +11,23 @@ module Propono
11
11
  new(topic_id, message, options).publish
12
12
  end
13
13
 
14
- attr_reader :topic_id, :message, :protocol
14
+ attr_reader :topic_id, :message, :protocol, :id
15
15
 
16
16
  def initialize(topic_id, message, options = {})
17
17
  raise PublisherError.new("Topic is nil") if topic_id.nil?
18
18
  raise PublisherError.new("Message is nil") if message.nil?
19
19
 
20
+ options = options.symbolize_keys
21
+
20
22
  @topic_id = topic_id
21
23
  @message = message
22
24
  @protocol = options.fetch(:protocol, :sns).to_sym
25
+ @id = SecureRandom.hex(3)
26
+ @id = "#{options[:id]}-#{@id}" if options[:id]
23
27
  end
24
28
 
25
29
  def publish
26
- Propono.config.logger.info "Propono: Publishing #{message} to #{topic_id} via #{protocol}"
30
+ Propono.config.logger.info "Propono [#{id}]: Publishing #{message} to #{topic_id} via #{protocol}"
27
31
  send("publish_via_#{protocol}")
28
32
  end
29
33
 
@@ -31,31 +35,37 @@ module Propono
31
35
 
32
36
  def publish_via_sns
33
37
  topic = TopicCreator.find_or_create(topic_id)
34
- msg = message.is_a?(String) ? message : message.to_json
35
38
  Thread.new do
36
39
  begin
37
- sns.publish(topic.arn, msg)
40
+ sns.publish(topic.arn, body.to_json)
38
41
  rescue => e
39
- Propono.config.logger.error "Propono failed to send via sns : #{e}"
42
+ Propono.config.logger.error "Propono [#{id}]: Failed to send via sns : #{e}"
40
43
  end
41
44
  end
42
45
  end
43
46
 
44
47
  def publish_via_udp
45
- payload = {topic: topic_id, message: message}.to_json
48
+ payload = body.merge(topic: topic_id).to_json
46
49
  UDPSocket.new.send(payload, 0, Propono.config.udp_host, Propono.config.udp_port)
47
50
  rescue => e
48
- Propono.config.logger.error "Propono failed to send : #{e}"
51
+ Propono.config.logger.error "Propono [#{id}]: Failed to send : #{e}"
49
52
  end
50
53
 
51
54
  def publish_via_tcp
52
- payload = {topic: topic_id, message: message}.to_json
55
+ payload = body.merge(topic: topic_id).to_json
53
56
 
54
57
  socket = TCPSocket.new(Propono.config.tcp_host, Propono.config.tcp_port)
55
58
  socket.write payload
56
59
  socket.close
57
60
  rescue => e
58
- Propono.config.logger.error "Propono failed to send : #{e}"
61
+ Propono.config.logger.error "Propono [#{id}]: Failed to send : #{e}"
62
+ end
63
+
64
+ def body
65
+ {
66
+ id: id,
67
+ message: message
68
+ }
59
69
  end
60
70
  end
61
71
  end
@@ -36,8 +36,20 @@ module Propono
36
36
  end
37
37
 
38
38
  def process_sqs_message(sqs_message)
39
- message = JSON.parse(sqs_message["Body"])["Message"]
40
- @message_processor.call(message)
39
+ body = JSON.parse(sqs_message["Body"])["Message"]
40
+
41
+ # Legacy syntax is covered in the rescue statement
42
+ # This begin/rescue dance and the rescue block will be removed in v1.
43
+ begin
44
+ body = JSON.parse(body)
45
+ context = body.symbolize_keys
46
+ message = context.delete(:message)
47
+ Propono.config.logger.info "Propono [#{context[:id]}]: Received from sqs."
48
+ @message_processor.call(message, context)
49
+ rescue
50
+ Propono.config.logger.info("Sending and recieving messags without ids is deprecated")
51
+ @message_processor.call(body)
52
+ end
41
53
  sqs.delete_message(queue_url, sqs_message['ReceiptHandle'])
42
54
  end
43
55
 
@@ -29,8 +29,16 @@ module Propono
29
29
  end
30
30
 
31
31
  def process_tcp_data(tcp_data)
32
- json = JSON.parse(tcp_data)
33
- @processor.call(json['topic'], json['message'])
32
+ json = JSON.parse(tcp_data).symbolize_keys
33
+
34
+ # Legacy syntax is covered in the else statement
35
+ # This conditional and the else block will be removed in v1.
36
+ if json[:id]
37
+ @processor.call(json[:topic], json[:message], id: json[:id])
38
+ else
39
+ Propono.config.logger.info("Sending and recieving messags without ids is deprecated")
40
+ @processor.call(json[:topic], json[:message])
41
+ end
34
42
  end
35
43
 
36
44
  def server
@@ -27,8 +27,16 @@ module Propono
27
27
  end
28
28
 
29
29
  def process_udp_data(udp_data)
30
- json = JSON.parse(udp_data)
31
- @processor.call(json['topic'], json['message'])
30
+ json = JSON.parse(udp_data).symbolize_keys
31
+
32
+ # Legacy syntax is covered in the else statement
33
+ # This conditional and the else block will be removed in v1.
34
+ if json[:id]
35
+ @processor.call(json[:topic], json[:message], id: json[:id])
36
+ else
37
+ Propono.config.logger.info("Sending and recieving messags without ids is deprecated")
38
+ @processor.call(json[:topic], json[:message])
39
+ end
32
40
  end
33
41
 
34
42
  def socket
@@ -1,3 +1,3 @@
1
1
  module Propono
2
- VERSION = "0.8.2"
2
+ VERSION = "0.9.0"
3
3
  end
@@ -0,0 +1,30 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ module Propono
4
+ class HashTest < Minitest::Test
5
+ def test_symbolize_keys_works
6
+ input = {
7
+ "foo" => "bar",
8
+ cat: 1,
9
+ "nest" => {
10
+ "dog" => [
11
+ {"mouse" => true}
12
+ ]
13
+ }
14
+ }
15
+ expected = {
16
+ foo: 'bar',
17
+ cat: 1,
18
+ nest: {
19
+ dog: [
20
+ {"mouse" => true}
21
+ ]
22
+ }
23
+ }
24
+
25
+ assert_equal expected, input.symbolize_keys
26
+ end
27
+ end
28
+ end
29
+
30
+
@@ -5,20 +5,29 @@ module Propono
5
5
  def test_the_message_gets_there
6
6
  topic = "test-topic"
7
7
  text = "This is my message"
8
+ flunks = []
8
9
 
9
10
  Propono.subscribe_by_queue(topic)
10
11
 
11
12
  thread = Thread.new do
12
- Propono.listen_to_queue(topic) do |message|
13
- assert_equal text, message
14
- break
13
+ begin
14
+ Propono.listen_to_queue(topic) do |message, context|
15
+ flunks << "Wrong message" unless message == text
16
+ flunks << "Wrong id" unless context[:id] =~ Regexp.new("[a-z0-9]{6}")
17
+ break
18
+ end
19
+ rescue => e
20
+ flunks << e.message
21
+ ensure
22
+ thread.terminate
15
23
  end
16
24
  end
17
25
 
18
26
  sleep(2) # Make sure the listener has started
19
27
 
20
28
  Propono.publish(topic, text)
21
- flunk("Test Timeout") unless wait_for_thread(thread)
29
+ flunks << "Test Timeout" unless wait_for_thread(thread)
30
+ flunk(flunks.join("\n")) unless flunks.empty?
22
31
  ensure
23
32
  thread.terminate
24
33
  end
@@ -5,14 +5,22 @@ module Propono
5
5
  def test_the_message_gets_there
6
6
  topic = "test-topic"
7
7
  message = "This is my message"
8
+ flunks = []
9
+
8
10
  Propono.config.tcp_host = "localhost"
9
11
  Propono.config.tcp_port = 20009
10
12
 
11
13
  Propono.subscribe_by_queue(topic)
12
14
 
13
15
  sqs_thread = Thread.new do
14
- Propono.listen_to_queue(topic) do |sqs_message|
15
- assert_equal message, sqs_message
16
+ begin
17
+ Propono.listen_to_queue(topic) do |sqs_message|
18
+ flunks << "Wrong message" unless message == sqs_message
19
+ sqs_thread.terminate
20
+ end
21
+ rescue => e
22
+ flunks << e.message
23
+ ensure
16
24
  sqs_thread.terminate
17
25
  end
18
26
  end
@@ -26,7 +34,8 @@ module Propono
26
34
  sleep(2) # Make sure the listener has started
27
35
 
28
36
  Propono.publish(topic, message, protocol: :tcp)
29
- flunk("Test Timeout") unless wait_for_thread(tcp_thread) && wait_for_thread(sqs_thread)
37
+ flunks << "Test Timeout" unless wait_for_thread(tcp_thread) && wait_for_thread(sqs_thread)
38
+ flunk(flunks.join("\n")) unless flunks.empty?
30
39
  ensure
31
40
  tcp_thread.terminate
32
41
  sqs_thread.terminate
@@ -4,14 +4,23 @@ module Propono
4
4
  class UdpProxyTest < IntegrationTest
5
5
  def test_the_message_gets_there
6
6
  topic = "test-topic"
7
- message = "This is my message"
7
+ text = "This is my message"
8
+ flunks = []
9
+
8
10
  Propono.config.udp_port = 20001
9
11
 
10
12
  Propono.subscribe_by_queue(topic)
11
13
 
12
14
  sqs_thread = Thread.new do
13
- Propono.listen_to_queue(topic) do |sqs_message|
14
- assert_equal message, sqs_message
15
+ begin
16
+ Propono.listen_to_queue(topic) do |message, context|
17
+ flunks << "Wrong message" unless text == message
18
+ flunks << "Wrong id" unless context[:id] =~ Regexp.new("[a-z0-9]{6}-[a-z0-9]{6}")
19
+ break
20
+ end
21
+ rescue => e
22
+ flunks << e.message
23
+ ensure
15
24
  sqs_thread.terminate
16
25
  end
17
26
  end
@@ -22,8 +31,9 @@ module Propono
22
31
 
23
32
  sleep(2) # Make sure the proxy has started
24
33
 
25
- Propono.publish(topic, message, protocol: :udp)
26
- flunk("Test timeout") unless wait_for_thread(sqs_thread)
34
+ Propono::Publisher.publish(topic, text, protocol: :udp)
35
+ flunks << "Test timeout" unless wait_for_thread(sqs_thread)
36
+ flunk(flunks.join("\n")) unless flunks.empty?
27
37
  ensure
28
38
  udp_thread.terminate
29
39
  sqs_thread.terminate
@@ -5,13 +5,21 @@ module Propono
5
5
  def test_the_message_gets_there
6
6
  topic = "test-topic"
7
7
  message = "This is my message"
8
+ flunks = []
9
+
8
10
  Propono.config.udp_port = 20002
9
11
 
10
12
  Propono.subscribe_by_queue(topic)
11
13
 
12
14
  sqs_thread = Thread.new do
13
- Propono.listen_to_queue(topic) do |sqs_message|
14
- assert_equal message, sqs_message
15
+ begin
16
+ Propono.listen_to_queue(topic) do |sqs_message|
17
+ assert_equal message, sqs_message
18
+ sqs_thread.terminate
19
+ end
20
+ rescue => e
21
+ flunks << e.message
22
+ ensure
15
23
  sqs_thread.terminate
16
24
  end
17
25
  end
@@ -26,7 +34,8 @@ module Propono
26
34
  sleep(2) # Make sure the listener has started
27
35
 
28
36
  Propono.publish(topic, message, protocol: :udp)
29
- flunk("Test Timeout") unless wait_for_thread(udp_thread) && wait_for_thread(sqs_thread)
37
+ flunks << "Test Timeout" unless wait_for_thread(udp_thread) && wait_for_thread(sqs_thread)
38
+ flunk(flunks.join("\n")) unless flunks.empty?
30
39
  ensure
31
40
  udp_thread.terminate
32
41
  sqs_thread.terminate
data/test/propono_test.rb CHANGED
@@ -45,8 +45,9 @@ module Propono
45
45
  def test_proxy_udp_calls_publish_in_the_block
46
46
  topic = "foobar"
47
47
  message = "message"
48
- Propono.stubs(:listen_to_udp).yields(topic, message)
49
- Publisher.expects(:publish).with(topic, message, {})
48
+ options = {id: "catdog"}
49
+ Propono.stubs(:listen_to_udp).yields(topic, message, options)
50
+ Publisher.expects(:publish).with(topic, message, options)
50
51
  Propono.proxy_udp
51
52
  end
52
53
 
@@ -58,8 +59,9 @@ module Propono
58
59
  def test_proxy_tcp_calls_publish_in_the_block
59
60
  topic = "foobar"
60
61
  message = "message"
61
- Propono.stubs(:listen_to_tcp).yields(topic, message)
62
- Publisher.expects(:publish).with(topic, message, {})
62
+ options = {id: "catdog"}
63
+ Propono.stubs(:listen_to_tcp).yields(topic, message, options)
64
+ Publisher.expects(:publish).with(topic, message, options)
63
65
  Propono.proxy_tcp
64
66
  end
65
67
  end
@@ -15,6 +15,17 @@ module Propono
15
15
  Publisher.publish(topic, message)
16
16
  end
17
17
 
18
+ def test_initializer_generates_an_id
19
+ publisher = Publisher.new('x','y')
20
+ assert publisher.instance_variable_get(:@id)
21
+ end
22
+
23
+ def test_initializer_concats_an_id
24
+ id = "q1w2e3"
25
+ publisher = Publisher.new('x','y', id: id)
26
+ assert publisher.id =~ Regexp.new("^#{id}-[a-z0-9]{6}$")
27
+ end
28
+
18
29
  def test_self_publish_calls_publish
19
30
  Publisher.any_instance.expects(:publish)
20
31
  Publisher.publish("topic", "message")
@@ -26,9 +37,10 @@ module Propono
26
37
  end
27
38
 
28
39
  def test_publish_logs
29
- client = Publisher.new("foo", "bar")
30
- Propono.config.logger.expects(:info).with() {|x| x =~ /^Propono: Publishing bar to foo via sns.*/}
31
- client.send(:publish)
40
+ publisher = Publisher.new("foo", "bar")
41
+ publisher.instance_variable_set(:@id, 'abc')
42
+ Propono.config.logger.expects(:info).with() {|x| x =~ /^Propono \[abc\]: Publishing bar to foo via sns.*/}
43
+ publisher.send(:publish)
32
44
  end
33
45
 
34
46
  def test_publish_proxies_to_sns
@@ -45,6 +57,7 @@ module Propono
45
57
 
46
58
  def test_publish_via_sns_should_call_sns_on_correct_topic_and_message
47
59
  topic = "topic123"
60
+ id = "f123"
48
61
  message = "message123"
49
62
  topic_arn = "arn123"
50
63
  topic = Topic.new(topic_arn)
@@ -52,41 +65,45 @@ module Propono
52
65
  TopicCreator.stubs(find_or_create: topic)
53
66
 
54
67
  sns = mock()
55
- sns.expects(:publish).with(topic_arn, message)
68
+ sns.expects(:publish).with(topic_arn, {id: id, message: message}.to_json)
56
69
  publisher = Publisher.new(topic, message)
57
- publisher.stubs(sns: sns)
70
+ publisher.stubs(id: id, sns: sns)
58
71
  thread = publisher.send(:publish_via_sns)
59
72
  thread.join
60
73
  end
61
74
 
62
75
  def test_publish_via_sns_should_accept_a_hash_for_message
63
76
  topic = "topic123"
77
+ id = "foobar123"
64
78
  message = {something: ['some', 123, true]}
79
+ body = {id: id, message: message}
80
+
65
81
  topic_arn = "arn123"
66
82
  topic = Topic.new(topic_arn)
67
-
68
83
  TopicCreator.stubs(find_or_create: topic)
69
84
 
70
85
  sns = mock()
71
- sns.expects(:publish).with(topic_arn, message.to_json)
86
+ sns.expects(:publish).with(topic_arn, body.to_json)
72
87
  publisher = Publisher.new(topic, message)
73
- publisher.stubs(sns: sns)
88
+ publisher.stubs(id: id, sns: sns)
74
89
  thread = publisher.send(:publish_via_sns)
75
90
  thread.join
76
91
  end
77
92
 
78
93
  def test_publish_via_sns_should_return_future_of_the_sns_response
79
94
  topic = "topic123"
95
+ id = "foobar123"
80
96
  message = "message123"
97
+ body = {id: id, message: message}
98
+
81
99
  topic_arn = "arn123"
82
100
  topic = Topic.new(topic_arn)
83
-
84
101
  TopicCreator.stubs(find_or_create: topic)
85
102
 
86
103
  sns = mock()
87
- sns.expects(:publish).with(topic_arn, message).returns(:response)
104
+ sns.expects(:publish).with(topic_arn, body.to_json).returns(:response)
88
105
  publisher = Publisher.new(topic, message)
89
- publisher.stubs(sns: sns)
106
+ publisher.stubs(id: id, sns: sns)
90
107
  assert_same :response, publisher.send(:publish_via_sns).value
91
108
  end
92
109
 
@@ -109,7 +126,6 @@ module Propono
109
126
  sns = mock()
110
127
  sns.stubs(:publish)
111
128
  publisher = Publisher.new(topic_id, "Foobar")
112
- publisher.stubs(sns: sns)
113
129
 
114
130
  publisher.send(:publish_via_sns)
115
131
  end
@@ -120,11 +136,14 @@ module Propono
120
136
  Propono.config.udp_host = host
121
137
  Propono.config.udp_port = port
122
138
  topic_id = "my-fav-topic"
123
- message = "foobar"
124
- payload = {topic: topic_id, message: message}.to_json
139
+
140
+ id = "foobar123"
141
+ message = "cat dog mouse"
142
+ payload = {id: id, message: message, topic: topic_id}.to_json
125
143
  UDPSocket.any_instance.expects(:send).with(payload, 0, host, port)
126
144
 
127
145
  publisher = Publisher.new(topic_id, message)
146
+ publisher.stubs(id: id)
128
147
  publisher.send(:publish_via_udp)
129
148
  end
130
149
 
@@ -134,9 +153,10 @@ module Propono
134
153
  Propono.config.udp_host = host
135
154
  Propono.config.udp_port = port
136
155
 
137
- client = Publisher.new("topic_id", "message")
138
- Propono.config.logger.expects(:error).with() {|x| x =~ /^Propono failed to send : getaddrinfo:.*/}
139
- client.send(:publish_via_udp)
156
+ publisher = Publisher.new("topic_id", "message")
157
+ publisher.stubs(id: '123asd')
158
+ Propono.config.logger.expects(:error).with() {|x| x =~ /^Propono \[123asd\]: Failed to send : getaddrinfo:.*/}
159
+ publisher.send(:publish_via_udp)
140
160
  end
141
161
 
142
162
  def test_publish_should_raise_exception_if_topic_is_nil
@@ -149,8 +169,9 @@ module Propono
149
169
  Propono.config.tcp_host = "http://meducation.net"
150
170
  Propono.config.tcp_port = 1234
151
171
  topic_id = "my-fav-topic"
172
+ id = "qweqw2312"
152
173
  message = "foobar"
153
- payload = {topic: topic_id, message: message}.to_json
174
+ payload = {id: id, message: message, topic: topic_id}.to_json
154
175
 
155
176
  socket = mock()
156
177
  socket.expects(:write).with(payload)
@@ -158,6 +179,7 @@ module Propono
158
179
  TCPSocket.stubs(new: socket)
159
180
 
160
181
  publisher = Publisher.new(topic_id, message)
182
+ publisher.stubs(id: id)
161
183
  publisher.send(:publish_via_tcp)
162
184
  end
163
185
 
@@ -180,9 +202,10 @@ module Propono
180
202
  Propono.config.tcp_host = host
181
203
  Propono.config.tcp_port = port
182
204
 
183
- client = Publisher.new("topic_id", "message")
184
- Propono.config.logger.expects(:error).with() {|x| x =~ /^Propono failed to send : getaddrinfo:.*/}
185
- client.send(:publish_via_tcp)
205
+ publisher = Publisher.new("topic_id", "message")
206
+ publisher.stubs(id: '123asd')
207
+ Propono.config.logger.expects(:error).with() {|x| x =~ /^Propono \[123asd\]: Failed to send : getaddrinfo:.*/}
208
+ publisher.send(:publish_via_tcp)
186
209
  end
187
210
 
188
211
  def test_publish_should_raise_exception_if_topic_is_nil
@@ -9,10 +9,14 @@ module Propono
9
9
 
10
10
  @receipt_handle1 = "test-receipt-handle1"
11
11
  @receipt_handle2 = "test-receipt-handle2"
12
- @message1 = "Foobar 123"
12
+ @message1 = {cat: "Foobar 123"}
13
13
  @message2 = "Barfoo 543"
14
- @sqs_message1 = { "ReceiptHandle" => @receipt_handle1, "Body" => {"Message" => @message1}.to_json}
15
- @sqs_message2 = { "ReceiptHandle" => @receipt_handle2, "Body" => {"Message" => @message2}.to_json}
14
+ @message1_id = "abc123"
15
+ @message1_id = "987whf"
16
+ @body1 = {id: @message1_id, message: @message1}
17
+ @body2 = {id: @message2_id, message: @message2}
18
+ @sqs_message1 = { "ReceiptHandle" => @receipt_handle1, "Body" => {"Message" => @body1.to_json}.to_json}
19
+ @sqs_message2 = { "ReceiptHandle" => @receipt_handle2, "Body" => {"Message" => @body2.to_json}.to_json}
16
20
  @messages = { "Message" => [ @sqs_message1, @sqs_message2 ] }
17
21
  @sqs_response = mock().tap{|m|m.stubs(body: @messages)}
18
22
  @sqs = mock()
@@ -40,6 +44,11 @@ module Propono
40
44
  @listener.send(:read_messages)
41
45
  end
42
46
 
47
+ def test_log_message_from_sqs
48
+ Propono.config.logger.expects(:info).with() {|x| x == "Propono [#{@message1_id}]: Received from sqs."}
49
+ @listener.send(:read_messages)
50
+ end
51
+
43
52
  def test_read_messages_calls_process_message_for_each_msg
44
53
  @listener.expects(:process_sqs_message).with(@sqs_message1)
45
54
  @listener.expects(:process_sqs_message).with(@sqs_message2)
@@ -66,10 +75,9 @@ module Propono
66
75
  end
67
76
 
68
77
  def test_each_message_processor_is_yielded
69
- messages_yielded = [ ]
70
- @listener = QueueListener.new(@topic_id) { |m| messages_yielded.push(m) }
78
+ messages_yielded = []
79
+ @listener = QueueListener.new(@topic_id) { |m, _| messages_yielded.push(m) }
71
80
  @listener.stubs(sqs: @sqs)
72
-
73
81
  @listener.send(:read_messages)
74
82
 
75
83
  assert_equal messages_yielded.size, 2
@@ -77,6 +85,17 @@ module Propono
77
85
  assert messages_yielded.include?(@message2)
78
86
  end
79
87
 
88
+ def test_each_message_processor_context
89
+ contexts = []
90
+ @listener = QueueListener.new(@topic_id) { |_, context| contexts << context }
91
+ @listener.stubs(sqs: @sqs)
92
+ @listener.send(:read_messages)
93
+
94
+ assert_equal contexts.size, 2
95
+ assert contexts.include?({id: @message1_id})
96
+ assert contexts.include?({id: @message2_id})
97
+ end
98
+
80
99
  def test_each_message_is_deleted
81
100
  queue_url = "test-queue-url"
82
101
 
@@ -87,4 +106,43 @@ module Propono
87
106
  @listener.send(:read_messages)
88
107
  end
89
108
  end
109
+ class QueueListenerLegacySyntaxTest < Minitest::Test
110
+
111
+ def setup
112
+ super
113
+ @topic_id = "some-topic"
114
+
115
+ @receipt_handle1 = "test-receipt-handle1"
116
+ @receipt_handle2 = "test-receipt-handle2"
117
+ @message1 = {'cat' => "Foobar 123"}
118
+ @message2 = "qwertyuiop"
119
+ @sqs_message1 = { "ReceiptHandle" => @receipt_handle1, "Body" => {"Message" => @message1}.to_json}
120
+ @sqs_message2 = { "ReceiptHandle" => @receipt_handle2, "Body" => {"Message" => @message2}.to_json}
121
+ @messages = { "Message" => [ @sqs_message1, @sqs_message2 ] }
122
+ @sqs_response = mock().tap{|m|m.stubs(body: @messages)}
123
+ @sqs = mock()
124
+ @sqs.stubs(receive_message: @sqs_response)
125
+ @sqs.stubs(:delete_message)
126
+
127
+ @listener = QueueListener.new(@topic_id) {}
128
+ @listener.stubs(sqs: @sqs)
129
+ end
130
+
131
+ def test_old_syntax_has_deprecation_warning
132
+ Propono.config.logger.expects(:info).with("Sending and recieving messags without ids is deprecated")
133
+ @listener.stubs(sqs: @sqs)
134
+ @listener.send(:read_messages)
135
+ end
136
+
137
+ def test_each_message_processor_is_yielded
138
+ messages_yielded = []
139
+ @listener = QueueListener.new(@topic_id) { |m| messages_yielded.push(m) }
140
+ @listener.stubs(sqs: @sqs)
141
+ @listener.send(:read_messages)
142
+
143
+ assert_equal messages_yielded.size, 2
144
+ assert messages_yielded.include?(@message1)
145
+ assert messages_yielded.include?(@message2)
146
+ end
147
+ end
90
148
  end
@@ -45,9 +45,10 @@ module Propono
45
45
  def test_processor_is_called_correctly
46
46
  topic = "my-topic"
47
47
  message = "my-message"
48
+ id = "qwe123"
48
49
  processor = Proc.new {}
49
- tcp_data = {topic: topic, message: message}.to_json
50
- processor.expects(:call).with(topic, message)
50
+ tcp_data = {topic: topic, message: message, id: id}.to_json
51
+ processor.expects(:call).with(topic, message, {id: id})
51
52
 
52
53
  listener = TcpListener.new(&processor)
53
54
  listener.send(:process_tcp_data, tcp_data)
@@ -59,5 +60,17 @@ module Propono
59
60
  listener.listen
60
61
  end
61
62
  end
62
- end
63
63
 
64
+ class TcpListenerLegacyTest < Minitest::Test
65
+ def test_processor_is_called_correctly
66
+ topic = "my-topic"
67
+ message = "my-message"
68
+ processor = Proc.new {}
69
+ tcp_data = {topic: topic, message: message}.to_json
70
+ processor.expects(:call).with(topic, message)
71
+
72
+ listener = TcpListener.new(&processor)
73
+ listener.send(:process_tcp_data, tcp_data)
74
+ end
75
+ end
76
+ end
@@ -42,9 +42,10 @@ module Propono
42
42
  def test_processor_is_called_correctly
43
43
  topic = "my-topic"
44
44
  message = "my-message"
45
+ id = "123asd"
45
46
  processor = Proc.new {}
46
- udp_data = {topic: topic, message: message}.to_json
47
- processor.expects(:call).with(topic, message)
47
+ udp_data = {topic: topic, message: message, id: id}.to_json
48
+ processor.expects(:call).with(topic, message, {id: id})
48
49
 
49
50
  server = UdpListener.new(&processor)
50
51
  server.send(:process_udp_data, udp_data)
@@ -56,4 +57,17 @@ module Propono
56
57
  listener.listen
57
58
  end
58
59
  end
60
+
61
+ class UdpListenerLegacyTest < Minitest::Test
62
+ def test_processor_is_called_correctly
63
+ topic = "my-topic"
64
+ message = "my-message"
65
+ processor = Proc.new {}
66
+ udp_data = {topic: topic, message: message}.to_json
67
+ processor.expects(:call).with(topic, message)
68
+
69
+ server = UdpListener.new(&processor)
70
+ server.send(:process_udp_data, udp_data)
71
+ end
72
+ end
59
73
  end
data/test/test_helper.rb CHANGED
@@ -22,6 +22,7 @@ class Minitest::Test
22
22
  config.application_name = "MyApp"
23
23
 
24
24
  config.logger.stubs(:debug)
25
+ config.logger.stubs(:info)
25
26
  config.logger.stubs(:error)
26
27
  end
27
28
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: propono
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.2
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - MalcyL
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-11-06 00:00:00.000000000 Z
12
+ date: 2013-11-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fog
@@ -119,6 +119,7 @@ files:
119
119
  - lib/propono/components/sqs.rb
120
120
  - lib/propono/components/topic.rb
121
121
  - lib/propono/configuration.rb
122
+ - lib/propono/helpers/hash.rb
122
123
  - lib/propono/logger.rb
123
124
  - lib/propono/propono_error.rb
124
125
  - lib/propono/services/publisher.rb
@@ -138,6 +139,7 @@ files:
138
139
  - test/components/topic_test.rb
139
140
  - test/config.yml.example
140
141
  - test/configuration_test.rb
142
+ - test/helpers/hash_test.rb
141
143
  - test/integration/integration_test.rb
142
144
  - test/integration/sns_to_sqs_test.rb
143
145
  - test/integration/tcp_to_sqs_test.rb
@@ -173,7 +175,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
173
175
  version: '0'
174
176
  requirements: []
175
177
  rubyforge_project:
176
- rubygems_version: 2.0.3
178
+ rubygems_version: 2.1.9
177
179
  signing_key:
178
180
  specification_version: 4
179
181
  summary: General purpose pub/sub library built on top of AWS SNS and SQS
@@ -186,6 +188,7 @@ test_files:
186
188
  - test/components/topic_test.rb
187
189
  - test/config.yml.example
188
190
  - test/configuration_test.rb
191
+ - test/helpers/hash_test.rb
189
192
  - test/integration/integration_test.rb
190
193
  - test/integration/sns_to_sqs_test.rb
191
194
  - test/integration/tcp_to_sqs_test.rb