propono 0.8.2 → 0.9.0

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
  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