liebre 0.1.3

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 (38) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +51 -0
  3. data/Gemfile +4 -0
  4. data/Gemfile.lock +47 -0
  5. data/LICENSE +22 -0
  6. data/README.md +268 -0
  7. data/lib/liebre.rb +24 -0
  8. data/lib/liebre/common.rb +7 -0
  9. data/lib/liebre/common/utils.rb +24 -0
  10. data/lib/liebre/config.rb +48 -0
  11. data/lib/liebre/connection_manager.rb +64 -0
  12. data/lib/liebre/publisher.rb +88 -0
  13. data/lib/liebre/runner.rb +59 -0
  14. data/lib/liebre/runner/consumers.rb +36 -0
  15. data/lib/liebre/runner/starter.rb +40 -0
  16. data/lib/liebre/runner/starter/consumer.rb +91 -0
  17. data/lib/liebre/runner/starter/consumer/handler.rb +35 -0
  18. data/lib/liebre/runner/starter/resources.rb +39 -0
  19. data/lib/liebre/runner/starter/resources/queue_builder.rb +58 -0
  20. data/lib/liebre/runner/starter/rpc.rb +45 -0
  21. data/lib/liebre/tasks.rb +12 -0
  22. data/lib/liebre/version.rb +5 -0
  23. data/liebre.gemspec +26 -0
  24. data/spec/config/liebre.yml +47 -0
  25. data/spec/config/rabbitmq.yml +35 -0
  26. data/spec/integration_spec.rb +73 -0
  27. data/spec/liebre/config_spec.rb +62 -0
  28. data/spec/liebre/connection_manager_spec.rb +40 -0
  29. data/spec/liebre/publisher_spec.rb +86 -0
  30. data/spec/liebre/runner/consumers_spec.rb +59 -0
  31. data/spec/liebre/runner/starter/consumer_spec.rb +140 -0
  32. data/spec/liebre/runner/starter/resources/queue_builder_spec.rb +69 -0
  33. data/spec/liebre/runner/starter/resources_spec.rb +36 -0
  34. data/spec/liebre/runner/starter/rpc_spec.rb +92 -0
  35. data/spec/liebre/runner/starter_spec.rb +59 -0
  36. data/spec/liebre/runner_spec.rb +50 -0
  37. data/spec/spec_helper.rb +23 -0
  38. metadata +172 -0
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Liebre::Publisher do
4
+
5
+ let :exchange_config do
6
+ {
7
+ 'name' => "test_exchange",
8
+ 'type' => "direct",
9
+ 'opts' => {
10
+ 'durable' => false
11
+ }
12
+ }
13
+ end
14
+
15
+ let :publishers_config do
16
+ {
17
+ 'test_publisher' => {
18
+ 'exchange' =>
19
+ exchange_config
20
+ }
21
+ }
22
+ end
23
+
24
+ let(:channel) { double 'channel' }
25
+ let(:bunny_connection) { double 'bunny_conection', :create_channel => channel }
26
+ let(:connection_manager) { double 'connection_manager', :get => bunny_connection }
27
+ let(:exchange) { double 'exchange' }
28
+
29
+ before do
30
+ allow_any_instance_of(Liebre::Config).to receive(:publishers).and_return publishers_config
31
+ allow_any_instance_of(Liebre::Config).to receive(:rpc_request_timeout).and_return 10
32
+
33
+ expect(Liebre::ConnectionManager).to receive(:new).and_return connection_manager
34
+ expect(connection_manager).to receive(:ensure_started)
35
+
36
+ expect(Liebre::Common::Utils).to receive(:create_exchange).
37
+ with(channel, exchange_config).and_return exchange
38
+
39
+ end
40
+
41
+ subject { described_class.new 'test_publisher' }
42
+
43
+ describe "#enqueue" do
44
+ it do
45
+ message = "abc"
46
+ expect(exchange).to receive(:publish).with message, {}
47
+
48
+ subject.enqueue message
49
+ end
50
+ end
51
+
52
+ describe "#enqueue_and_wait" do
53
+
54
+ let(:correlation_id) { "correlation_id" }
55
+ let(:reply_queue_name) { "test_publisher_callback_#{correlation_id}" }
56
+ let(:reply_queue) { double "reply_queue", :name => reply_queue_name }
57
+ let(:delivery_info) { double "delivery_info", :consumer_tag => "tag"}
58
+ let(:consumer) { double 'consumer' }
59
+ let(:consumers) { {"tag" => consumer} }
60
+
61
+ before do
62
+ expect(channel).to receive(:queue).with(reply_queue_name, :exclusive => true).
63
+ and_return reply_queue
64
+ end
65
+
66
+ it do
67
+ message = "question"
68
+ answer = "answer"
69
+ expect(exchange).to receive(:publish).with message,
70
+ {:correlation_id => correlation_id, :reply_to => reply_queue_name}
71
+
72
+ expect(reply_queue).to receive(:subscribe).with(:block => true) do |&block|
73
+ expect(channel).to receive(:consumers).and_return consumers
74
+ expect(consumer).to receive(:cancel)
75
+
76
+ block.call(delivery_info, {:correlation_id => correlation_id}, answer)
77
+ end
78
+
79
+ expect(reply_queue).to receive(:delete)
80
+
81
+ result = subject.enqueue_and_wait message, :correlation_id => correlation_id
82
+ expect(result).to eq answer
83
+ end
84
+ end
85
+
86
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Liebre::Runner::Consumers do
4
+
5
+ let(:conn) { double 'conn' }
6
+
7
+ let(:first_expected_config) do
8
+ {
9
+ "class_name" => "MyConsumer",
10
+ "num_threads" => 3,
11
+ "rpc" => false
12
+ }
13
+ end
14
+
15
+ let(:second_expected_config) do
16
+ {
17
+ "class_name" => "MyRPC",
18
+ "rpc" => true
19
+ }
20
+ end
21
+
22
+ let(:consumers_config) do
23
+ {
24
+ "some_consumer" => first_expected_config,
25
+ "some_rpc" => second_expected_config
26
+ }
27
+ end
28
+
29
+ before do
30
+ allow(subject).to receive(:consumers).and_return consumers_config
31
+ end
32
+
33
+ subject { described_class.new(conn) }
34
+
35
+ describe "#consumer_names" do
36
+ it "returns all names" do
37
+ expect(subject.consumer_names).to eq ["some_consumer", "some_rpc"]
38
+ end
39
+ end
40
+
41
+ describe "#start_all" do
42
+ let(:first_starter) { double 'first_starter' }
43
+ let(:second_starter) { double 'second_starter' }
44
+
45
+ it "starts the given consumers" do
46
+ expect(Liebre::Runner::Starter).to receive(:new).exactly(3).times.
47
+ with(conn, first_expected_config).and_return(first_starter)
48
+
49
+ expect(Liebre::Runner::Starter).to receive(:new).
50
+ with(conn, second_expected_config).and_return(second_starter)
51
+
52
+ expect(first_starter ).to receive(:call).exactly(3).times
53
+ expect(second_starter).to receive(:call)
54
+
55
+ subject.start_all
56
+ end
57
+ end
58
+
59
+ end
@@ -0,0 +1,140 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Liebre::Runner::Starter::Consumer do
4
+
5
+ let(:connection) { double 'connection' }
6
+
7
+ let(:class_name) { "MyConsumer" }
8
+ let(:pool_size) { 4 }
9
+
10
+ let :config do
11
+ {
12
+ "class_name" => class_name,
13
+ "pool_size" => pool_size,
14
+ "rpc" => false,
15
+ "exchange" => {
16
+ "name" => "test_exchange",
17
+ "type" => "direct",
18
+ "opts" => {
19
+ "durable" => true
20
+ }
21
+ },
22
+ "queue" => {
23
+ "name" => "test_queue",
24
+ "opts" => {
25
+ "durable" => true
26
+ }
27
+ }
28
+ }
29
+ end
30
+
31
+ let :error_config do
32
+ {
33
+ "class_name" => class_name,
34
+ "pool_size" => pool_size,
35
+ "rpc" => false,
36
+ "exchange" => {
37
+ "name" => "test_exchange-error",
38
+ "type" => "direct",
39
+ "opts" => {
40
+ "durable" => true
41
+ }
42
+ },
43
+ "queue" => {
44
+ "name" => "test_queue-error",
45
+ "opts" => {
46
+ "durable" => true,
47
+ "exclusive" => true
48
+ }
49
+ }
50
+ }
51
+ end
52
+
53
+ let :parsed_config do
54
+ {
55
+ "class_name" => class_name,
56
+ "pool_size" => pool_size,
57
+ "rpc" => false,
58
+ "exchange" => {
59
+ "name" => "test_exchange",
60
+ "type" => "direct",
61
+ "opts" => {
62
+ "durable" => true
63
+ }
64
+ },
65
+ "queue" => {
66
+ "name" => "test_queue",
67
+ "opts" => {
68
+ "durable" => true,
69
+ "arguments" => {
70
+ 'x-dead-letter-exchange' => "test_exchange-error"
71
+ }
72
+ }
73
+ }
74
+ }
75
+ end
76
+
77
+ let(:exchange) { double 'exchange' }
78
+ let(:queue) { double 'queue' }
79
+ let(:error_queue) { double 'error_queue' }
80
+ let(:channel) { double 'channel' }
81
+ let(:payload) { "the_payload" }
82
+
83
+ subject { described_class.new(connection, config) }
84
+
85
+ let :resources do
86
+ double 'resources', :exchange => exchange, :queue => queue, :channel => channel
87
+ end
88
+
89
+ let :error_resources do
90
+ double 'resources', :queue => error_queue
91
+ end
92
+
93
+ let(:class_name) { "MyConsumer" }
94
+
95
+ let(:consumer_class) { double 'consumer_class', :name => 'consumer_class' }
96
+ let(:consumer_instance) { double 'consumer_instance' }
97
+
98
+ let :meta do
99
+ double 'meta'
100
+ end
101
+
102
+ let(:handler) { double 'handler' }
103
+
104
+ let(:deliver_info) { double 'deliver_info' }
105
+ let(:ack) { :ack }
106
+
107
+ before do
108
+ expect(Liebre::Runner::Starter::Resources).to receive(:new).
109
+ with(connection, error_config).and_return(error_resources)
110
+
111
+ expect(Liebre::Runner::Starter::Resources).to receive(:new).
112
+ with(connection, parsed_config).and_return(resources)
113
+
114
+ stub_const(class_name, consumer_class)
115
+
116
+ expect(described_class::Handler).to receive(:new).
117
+ with(channel).and_return handler
118
+ end
119
+
120
+ it 'creates error queue and creates and subscribes to standard queue' do
121
+
122
+ expect(queue).to receive :subscribe do |&block|
123
+ block.call(deliver_info, meta, payload)
124
+ end
125
+
126
+ expect(consumer_class).to receive :new do |given_payload, given_meta|
127
+ expect(given_payload).to eq payload
128
+ expect(given_meta ).to eq meta
129
+
130
+ consumer_instance
131
+ end
132
+
133
+ expect(consumer_instance).to receive(:call).and_return ack
134
+
135
+ expect(handler).to receive(:respond).with ack, deliver_info
136
+
137
+ subject.call
138
+ end
139
+
140
+ end
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Liebre::Runner::Starter::Resources::QueueBuilder do
4
+
5
+ let(:channel) { double 'channel' }
6
+ let(:routing_key) { "foo" }
7
+
8
+ let :config do
9
+ {
10
+ "queue" => {
11
+ "name" => "my_queue",
12
+ "opts" => {"some" => "option"}
13
+ },
14
+ "exchange" => {
15
+ "name" => "my_exchange",
16
+ "type" => "direct",
17
+ "opts" => {"an" => "option"}
18
+ },
19
+ "bind" => {"routing_key" => routing_key}
20
+ }
21
+ end
22
+
23
+ let(:exchange) { double 'exchange' }
24
+ let(:queue) { double 'queue' }
25
+
26
+ subject { described_class.new(channel, config) }
27
+
28
+ describe '#call' do
29
+
30
+ it 'builds and binds the queue properly' do
31
+ expect(channel).to receive(:exchange).
32
+ with("my_exchange", :type => "direct", :an => "option").
33
+ and_return(exchange)
34
+
35
+ expect(channel).to receive(:queue).
36
+ with("my_queue", :some => "option").
37
+ and_return(queue)
38
+
39
+ expect(queue).to receive(:bind).
40
+ with(exchange, :routing_key => "foo")
41
+
42
+ expect(subject.queue).to eq queue
43
+ end
44
+ end
45
+
46
+ describe "with multiple routing_keys" do
47
+ let(:routing_key) { %W{a b c} }
48
+
49
+ it 'builds and binds the queue properly' do
50
+ allow(channel).to receive(:exchange).
51
+ with("my_exchange", :type => "direct", :an => "option").
52
+ and_return(exchange)
53
+
54
+ expect(channel).to receive(:queue).
55
+ with("my_queue", :some => "option").
56
+ and_return(queue)
57
+
58
+ expect(queue).to receive(:bind).
59
+ with(exchange, :routing_key => "a")
60
+ expect(queue).to receive(:bind).
61
+ with(exchange, :routing_key => "b")
62
+ expect(queue).to receive(:bind).
63
+ with(exchange, :routing_key => "c")
64
+
65
+ expect(subject.queue).to eq queue
66
+ end
67
+ end
68
+
69
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Liebre::Runner::Starter::Resources do
4
+
5
+ let(:connection) { double 'connection' }
6
+
7
+ let(:pool_size) { 4 }
8
+ let(:config) { {"pool_size" => pool_size} }
9
+
10
+ subject { described_class.new(connection, config) }
11
+
12
+ describe '#exchange and #queue' do
13
+ let(:channel) { double 'channel' }
14
+ let(:exchange) { double 'exchange' }
15
+
16
+ let(:queue) { double 'queue' }
17
+ let(:queue_builder) { double 'queue_builder', :queue => queue, :exchange => exchange }
18
+
19
+ before do
20
+ allow(connection).to receive(:create_channel).
21
+ with(nil, pool_size).and_return(channel)
22
+
23
+ allow(channel).to receive(:default_exchange).
24
+ and_return(exchange)
25
+
26
+ allow(described_class::QueueBuilder).to receive(:new).
27
+ with(channel, config).and_return(queue_builder)
28
+ end
29
+
30
+ it 'builds exchange and queue properly' do
31
+ expect(subject.exchange).to eq exchange
32
+ expect(subject.queue ).to eq queue
33
+ end
34
+ end
35
+
36
+ end
@@ -0,0 +1,92 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Liebre::Runner::Starter::RPC do
4
+
5
+ let(:connection) { double 'connection' }
6
+
7
+ let(:class_name) { "MyRPC" }
8
+ let(:pool_size) { 4 }
9
+
10
+ let :config do
11
+ {
12
+ "class_name" => class_name,
13
+ "pool_size" => pool_size,
14
+ "rpc" => true,
15
+ "exchange" => {
16
+ "name" => "test_exchange",
17
+ "type" => "direct",
18
+ "opts" => {
19
+ "durable" => false
20
+ }
21
+ },
22
+ "queue" => {
23
+ "name" => "test_queue",
24
+ "opts" => {
25
+ "durable" => false
26
+ }
27
+ }
28
+ }
29
+ end
30
+
31
+ let(:exchange) { double 'exchange' }
32
+ let(:queue) { double 'queue' }
33
+ let(:channel) { double 'channel', :default_exchange => exchange }
34
+ let(:payload) { "the_payload" }
35
+ let(:response) { "the_response" }
36
+
37
+ subject { described_class.new(connection, config) }
38
+
39
+ let :resources do
40
+ double 'resources', :exchange => exchange, :queue => queue, :channel => channel
41
+ end
42
+
43
+ let(:class_name) { "MyConsumer" }
44
+
45
+ let(:rpc_class) { double 'rpc_class', :name => 'rpc_class' }
46
+ let(:rpc_instance) { double 'rpc_instance' }
47
+
48
+ let(:reply_to) { "queue_to_reply_to" }
49
+ let(:correlation_id) { 123 }
50
+ let :meta do
51
+ double 'meta',
52
+ :reply_to => reply_to,
53
+ :correlation_id => correlation_id
54
+ end
55
+
56
+ let :opts do
57
+ {:routing_key => reply_to, :correlation_id => correlation_id}
58
+ end
59
+
60
+ let(:handler) { double 'handler' }
61
+
62
+ let(:deliver_info) { double 'deliver_info' }
63
+
64
+ before do
65
+ allow(Liebre::Runner::Starter::Resources).to receive(:new).
66
+ with(connection, config).and_return(resources)
67
+
68
+ stub_const(class_name, rpc_class)
69
+ end
70
+
71
+ it 'creates error queue and creates and subscribes to standard queue' do
72
+
73
+ expect(exchange).to receive(:publish).with(response, opts)
74
+
75
+ expect(queue).to receive :subscribe do |&block|
76
+ block.call(deliver_info, meta, payload)
77
+ end
78
+
79
+ expect(rpc_class).to receive :new do |given_payload, given_meta, callback|
80
+ expect(given_payload).to eq payload
81
+ expect(given_meta ).to eq meta
82
+ callback.call(response)
83
+
84
+ rpc_instance
85
+ end
86
+
87
+ expect(rpc_instance).to receive(:call)
88
+
89
+ subject.call
90
+ end
91
+
92
+ end