propono 1.7.0 → 2.0.0.rc1

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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +2 -9
  4. data/CHANGELOG.md +9 -0
  5. data/Gemfile +0 -2
  6. data/README.md +35 -91
  7. data/lib/propono.rb +4 -144
  8. data/lib/propono/components/aws_client.rb +78 -0
  9. data/lib/propono/components/aws_config.rb +4 -9
  10. data/lib/propono/components/client.rb +93 -0
  11. data/lib/propono/components/queue.rb +4 -6
  12. data/lib/propono/components/queue_subscription.rb +32 -22
  13. data/lib/propono/components/sqs_message.rb +3 -6
  14. data/lib/propono/components/topic.rb +6 -5
  15. data/lib/propono/configuration.rb +0 -2
  16. data/lib/propono/services/publisher.rb +21 -44
  17. data/lib/propono/services/queue_listener.rb +54 -57
  18. data/lib/propono/version.rb +1 -1
  19. data/propono.gemspec +3 -2
  20. data/test/components/aws_config_test.rb +4 -4
  21. data/test/components/client_test.rb +68 -0
  22. data/test/components/queue_subscription_test.rb +68 -70
  23. data/test/components/queue_test.rb +6 -3
  24. data/test/components/topic_test.rb +4 -2
  25. data/test/configuration_test.rb +27 -55
  26. data/test/integration/integration_test.rb +4 -7
  27. data/test/integration/slow_queue_test.rb +11 -8
  28. data/test/integration/sns_to_sqs_test.rb +17 -17
  29. data/test/services/publisher_test.rb +59 -156
  30. data/test/services/queue_listener_test.rb +96 -103
  31. data/test/test_helper.rb +21 -48
  32. metadata +26 -39
  33. data/lib/propono/components/post_subscription.rb +0 -19
  34. data/lib/propono/components/sns.rb +0 -11
  35. data/lib/propono/components/sqs.rb +0 -12
  36. data/lib/propono/services/queue_creator.rb +0 -29
  37. data/lib/propono/services/subscriber.rb +0 -12
  38. data/lib/propono/services/tcp_listener.rb +0 -48
  39. data/lib/propono/services/topic_creator.rb +0 -23
  40. data/lib/propono/services/udp_listener.rb +0 -52
  41. data/test/components/post_subscription_test.rb +0 -29
  42. data/test/components/sns_test.rb +0 -25
  43. data/test/components/sqs_test.rb +0 -26
  44. data/test/integration/tcp_to_sqs_test.rb +0 -53
  45. data/test/integration/udp_proxy_test.rb +0 -50
  46. data/test/integration/udp_to_sqs_test.rb +0 -53
  47. data/test/propono_test.rb +0 -83
  48. data/test/services/queue_creator_test.rb +0 -61
  49. data/test/services/subscriber_test.rb +0 -21
  50. data/test/services/tcp_listener_test.rb +0 -76
  51. data/test/services/topic_creator_test.rb +0 -40
  52. data/test/services/udp_listener_test.rb +0 -73
@@ -1,19 +0,0 @@
1
- module Propono
2
- class PostSubscription
3
- include Sns
4
-
5
- def self.create(topic, endpoint)
6
- new(topic, endpoint).create
7
- end
8
-
9
- def initialize(topic_id, endpoint)
10
- @topic_id = topic_id
11
- @endpoint = endpoint
12
- end
13
-
14
- def create
15
- topic_arn = TopicCreator.find_or_create(@topic_id)
16
- sns.subscribe(topic_arn, @endpoint, 'http')
17
- end
18
- end
19
- end
@@ -1,11 +0,0 @@
1
- require 'fog/aws'
2
-
3
- module Propono
4
- module Sns
5
- private
6
-
7
- def sns
8
- @sns ||= Fog::AWS::SNS.new(Propono.aws_options)
9
- end
10
- end
11
- end
@@ -1,12 +0,0 @@
1
- require 'fog/aws'
2
-
3
- module Propono
4
- module Sqs
5
- private
6
-
7
- def sqs
8
- @sqs ||= Fog::AWS::SQS.new(Propono.aws_options)
9
- end
10
- end
11
- end
12
-
@@ -1,29 +0,0 @@
1
- module Propono
2
- class QueueCreatorError < ProponoError
3
- end
4
-
5
- class QueueCreator
6
- include Sqs
7
-
8
- def self.find_or_create(name)
9
- new(name).find_or_create
10
- end
11
-
12
- def initialize(name)
13
- @name = name
14
- end
15
-
16
- def find_or_create
17
- urls = sqs.list_queues("QueueNamePrefix" => @name).body["QueueUrls"]
18
- url = urls.select{|x|x =~ /#{@name}$/}.first
19
-
20
- unless url
21
- result = sqs.create_queue(@name)
22
- body = result.body
23
- url = body.fetch('QueueUrl') { raise QueueCreatorError.new("No QueueUrl returned from SQS") }
24
- end
25
-
26
- Queue.new(url)
27
- end
28
- end
29
- end
@@ -1,12 +0,0 @@
1
- module Propono
2
-
3
- module Subscriber
4
- def self.subscribe_by_queue(topic)
5
- QueueSubscription.create(topic)
6
- end
7
-
8
- def self.subscribe_by_post(topic, endpoint)
9
- PostSubscription.create(topic, endpoint)
10
- end
11
- end
12
- end
@@ -1,48 +0,0 @@
1
- require 'json'
2
-
3
- module Propono
4
- class TcpListenerError < ProponoError
5
- end
6
-
7
- class TcpListener
8
-
9
- def self.listen(&processor)
10
- new(&processor).listen
11
- end
12
-
13
- def initialize(&processor)
14
- raise TcpListenerError.new("Please provide a block to call for each message") unless block_given?
15
- @processor = processor
16
- end
17
-
18
- def listen
19
- loop { receive_and_process }
20
- end
21
-
22
- private
23
-
24
- def receive_and_process
25
- client = server.accept
26
- tcp_data = client.recvfrom(1024)[0]
27
- client.close
28
- Thread.new { process_tcp_data(tcp_data) }
29
- end
30
-
31
- def process_tcp_data(tcp_data)
32
- json = Propono::Utils.symbolize_keys JSON.parse(tcp_data)
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 receiving messages without ids is deprecated")
40
- @processor.call(json[:topic], json[:message])
41
- end
42
- end
43
-
44
- def server
45
- @server ||= TCPServer.open(Propono.config.tcp_port)
46
- end
47
- end
48
- end
@@ -1,23 +0,0 @@
1
- module Propono
2
- class TopicCreatorError < ProponoError
3
- end
4
-
5
- class TopicCreator
6
- include Sns
7
-
8
- def self.find_or_create(topic_id)
9
- new(topic_id).find_or_create
10
- end
11
-
12
- def initialize(topic_id)
13
- @topic_id = topic_id
14
- end
15
-
16
- def find_or_create
17
- result = sns.create_topic(@topic_id)
18
- body = result.body
19
- arn = body.fetch('TopicArn') { raise TopicCreatorError.new("No TopicArn returned from SNS") }
20
- Topic.new(arn)
21
- end
22
- end
23
- end
@@ -1,52 +0,0 @@
1
- require 'json'
2
-
3
- module Propono
4
- class UdpListenerError < ProponoError
5
- end
6
-
7
- class UdpListener
8
-
9
- def self.listen(&processor)
10
- new(&processor).listen
11
- end
12
-
13
- def initialize(&processor)
14
- raise UdpListenerError.new("Please provide a block to call for each message") unless block_given?
15
- @processor = processor
16
- end
17
-
18
- def listen
19
- loop { receive_and_process }
20
- end
21
-
22
- private
23
-
24
- def receive_and_process
25
- udp_data = socket.recvfrom(1024)[0]
26
- Thread.new { process_udp_data(udp_data) }
27
- end
28
-
29
- def process_udp_data(udp_data)
30
- json = Propono::Utils.symbolize_keys JSON.parse(udp_data)
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 receiving messages without ids is deprecated")
38
- @processor.call(json[:topic], json[:message])
39
- end
40
- end
41
-
42
- def socket
43
- @socket ||= begin
44
- socket = UDPSocket.new
45
- socket.bind(Propono.config.udp_host, Propono.config.udp_port)
46
- socket
47
- end
48
- end
49
- end
50
- end
51
-
52
-
@@ -1,29 +0,0 @@
1
- require File.expand_path('../../test_helper', __FILE__)
2
-
3
- module Propono
4
- class PostSubscriptionTest < Minitest::Test
5
- def test_create_topic
6
- topic = 'foobar'
7
- TopicCreator.expects(:find_or_create).with(topic)
8
- PostSubscription.create(topic, "foobar")
9
- end
10
-
11
- def test_create_calls_create
12
- arn = "arn123"
13
- endpoint = "http://meducation.net/some_queue_name"
14
-
15
- TopicCreator.stubs(find_or_create: arn)
16
-
17
- sns = mock()
18
- sns.expects(:subscribe).with(arn, endpoint, 'http')
19
- subscription = PostSubscription.new("Some topic", endpoint)
20
- subscription.stubs(sns: sns)
21
- subscription.create
22
- end
23
-
24
- def test_it_correctly_uses_http_and_https
25
- skip
26
- end
27
- end
28
- end
29
-
@@ -1,25 +0,0 @@
1
- require File.expand_path('../../test_helper', __FILE__)
2
-
3
- module Propono
4
- class SnsTest < Minitest::Test
5
- class SnsTestClass
6
- include Sns
7
- end
8
-
9
- def setup
10
- super
11
- Propono.config.access_key = "test-access-key"
12
- Propono.config.secret_key = "test-secret-key"
13
- Propono.config.queue_region = "test-queue-region"
14
- end
15
-
16
- def test_sns
17
- Fog::AWS::SNS.expects(:new)
18
- .with(:aws_access_key_id => 'test-access-key',
19
- :aws_secret_access_key => 'test-secret-key',
20
- :region => 'test-queue-region')
21
-
22
- SnsTestClass.new.send :sns
23
- end
24
- end
25
- end
@@ -1,26 +0,0 @@
1
- require File.expand_path('../../test_helper', __FILE__)
2
-
3
- module Propono
4
- class SqsTest < Minitest::Test
5
- class SqsTestClass
6
- include Sqs
7
- end
8
-
9
- def setup
10
- super
11
- Propono.config.access_key = "test-access-key"
12
- Propono.config.secret_key = "test-secret-key"
13
- Propono.config.queue_region = "us-east-1"
14
- end
15
-
16
- def test_sqs
17
- Fog::AWS::SQS.expects(:new)
18
- .with(:aws_access_key_id => 'test-access-key',
19
- :aws_secret_access_key => 'test-secret-key',
20
- :region => 'us-east-1')
21
-
22
- SqsTestClass.new.send :sqs
23
- end
24
- end
25
- end
26
-
@@ -1,53 +0,0 @@
1
- require File.expand_path('../integration_test', __FILE__)
2
-
3
- module Propono
4
- class TcpToSqsTest < IntegrationTest
5
- def test_the_message_gets_there
6
- topic = "propono-tests-tcp-to-sqs-topic"
7
- message = "This is my message #{DateTime.now} #{rand()}"
8
- flunks = []
9
- message_received = false
10
-
11
- Propono.config.tcp_host = "localhost"
12
- Propono.config.tcp_port = 20009
13
-
14
- Propono.drain_queue(topic)
15
- Propono.subscribe_by_queue(topic)
16
-
17
- sqs_thread = Thread.new do
18
- begin
19
- Propono.listen_to_queue(topic) do |sqs_message|
20
- flunks << "Wrong message" unless message == sqs_message
21
- sqs_thread.terminate
22
- message_received = true
23
- end
24
- rescue => e
25
- flunks << e.message
26
- ensure
27
- sqs_thread.terminate
28
- end
29
- end
30
-
31
- Thread.new do
32
- sleep(1) while !message_received
33
- sleep(5) # Make sure all the message deletion clear up in the thread has happened
34
- sqs_thread.terminate
35
- end
36
-
37
- tcp_thread = Thread.new do
38
- Propono.listen_to_tcp do |tcp_topic, tcp_message|
39
- Propono.publish(tcp_topic, tcp_message, async: false)
40
- tcp_thread.terminate
41
- end
42
- end
43
- sleep(1) # Make sure the listener has started
44
-
45
- Propono.publish(topic, message, protocol: :tcp)
46
- flunks << "Test Timeout" unless wait_for_thread(tcp_thread) && wait_for_thread(sqs_thread)
47
- flunk(flunks.join("\n")) unless flunks.empty?
48
- ensure
49
- tcp_thread.terminate
50
- sqs_thread.terminate
51
- end
52
- end
53
- end
@@ -1,50 +0,0 @@
1
- require File.expand_path('../integration_test', __FILE__)
2
-
3
- module Propono
4
- class UdpProxyTest < IntegrationTest
5
- def test_the_message_gets_there
6
- topic = "propono-tests-udp-proxy-topic"
7
- text = "This is my message #{DateTime.now} #{rand()}"
8
- flunks = []
9
- message_received = false
10
-
11
- Propono.config.udp_port = 20001
12
-
13
- Propono.drain_queue(topic)
14
- Propono.subscribe_by_queue(topic)
15
-
16
- sqs_thread = Thread.new do
17
- begin
18
- Propono.listen_to_queue(topic) do |message, context|
19
- flunks << "Wrong message" unless text == message
20
- flunks << "Wrong id" unless context[:id] =~ Regexp.new("[a-z0-9]{6}-[a-z0-9]{6}")
21
- message_received = true
22
- end
23
- rescue => e
24
- flunks << e.message
25
- ensure
26
- sqs_thread.terminate
27
- end
28
- end
29
-
30
- Thread.new do
31
- sleep(1) while !message_received
32
- sleep(5) # Make sure all the message deletion clear up in the thread has happened
33
- sqs_thread.terminate
34
- end
35
-
36
- udp_thread = Thread.new do
37
- Propono.proxy_udp
38
- end
39
-
40
- sleep(1) # Make sure the proxy has started
41
-
42
- Propono::Publisher.publish(topic, text, protocol: :udp)
43
- flunks << "Test timeout" unless wait_for_thread(sqs_thread)
44
- flunk(flunks.join("\n")) unless flunks.empty?
45
- ensure
46
- udp_thread.terminate
47
- sqs_thread.terminate
48
- end
49
- end
50
- end
@@ -1,53 +0,0 @@
1
- require File.expand_path('../integration_test', __FILE__)
2
-
3
- module Propono
4
- class UdpToSqsTest < IntegrationTest
5
- def test_the_message_gets_there
6
- topic = "propono-tests-udp-to-sqs-topic"
7
- message = "This is my message #{DateTime.now} #{rand()}"
8
- flunks = []
9
- message_received = false
10
-
11
- Propono.config.udp_port = 20002
12
-
13
- Propono.drain_queue(topic)
14
- Propono.subscribe_by_queue(topic)
15
-
16
- sqs_thread = Thread.new do
17
- begin
18
- Propono.listen_to_queue(topic) do |sqs_message|
19
- assert_equal message, sqs_message
20
- sqs_thread.terminate
21
- message_received = true
22
- end
23
- rescue => e
24
- flunks << e.message
25
- ensure
26
- sqs_thread.terminate
27
- end
28
- end
29
-
30
- Thread.new do
31
- sleep(1) while !message_received
32
- sleep(5) # Make sure all the message deletion clear up in the thread has happened
33
- sqs_thread.terminate
34
- end
35
-
36
- udp_thread = Thread.new do
37
- Propono.listen_to_udp do |udp_topic, udp_message|
38
- Propono.publish(udp_topic, udp_message)
39
- udp_thread.terminate
40
- end
41
- end
42
-
43
- sleep(1) # Make sure the listener has started
44
-
45
- Propono.publish(topic, message, protocol: :udp)
46
- flunks << "Test Timeout" unless wait_for_thread(udp_thread) && wait_for_thread(sqs_thread)
47
- flunk(flunks.join("\n")) unless flunks.empty?
48
- ensure
49
- udp_thread.terminate
50
- sqs_thread.terminate
51
- end
52
- end
53
- end