dispatch-rider 1.4.0 → 1.4.2
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 +4 -4
- data/.gitignore +20 -0
- data/.hound.yml +2 -0
- data/.rubocop.yml +50 -0
- data/.travis.yml +6 -0
- data/CHANGELOG.md +363 -0
- data/Gemfile +25 -0
- data/LICENSE.txt +1 -1
- data/README.md +32 -3
- data/Rakefile +38 -0
- data/dispatch-rider.gemspec +46 -0
- data/lib/dispatch-rider/notification_services/aws_sns.rb +9 -0
- data/lib/dispatch-rider/version.rb +1 -1
- data/spec/fixtures/handlers/another_test_handler.rb +2 -0
- data/spec/fixtures/handlers/test_handler.rb +2 -0
- data/spec/lib/dispatch-rider/airbrake_error_handler_spec.rb +16 -0
- data/spec/lib/dispatch-rider/callbacks/access_spec.rb +62 -0
- data/spec/lib/dispatch-rider/callbacks/storage_spec.rb +43 -0
- data/spec/lib/dispatch-rider/configuration_spec.rb +74 -0
- data/spec/lib/dispatch-rider/default_error_handler_spec.rb +14 -0
- data/spec/lib/dispatch-rider/demultiplexer_spec.rb +117 -0
- data/spec/lib/dispatch-rider/dispatcher_spec.rb +69 -0
- data/spec/lib/dispatch-rider/handlers/base_spec.rb +81 -0
- data/spec/lib/dispatch-rider/handlers/inheritance_tracking_spec.rb +27 -0
- data/spec/lib/dispatch-rider/message_spec.rb +59 -0
- data/spec/lib/dispatch-rider/notification_services/aws_sns_spec.rb +28 -0
- data/spec/lib/dispatch-rider/notification_services/base_spec.rb +65 -0
- data/spec/lib/dispatch-rider/notification_services/file_system/channel_spec.rb +28 -0
- data/spec/lib/dispatch-rider/notification_services/file_system/notifier_spec.rb +14 -0
- data/spec/lib/dispatch-rider/notification_services/file_system_spec.rb +23 -0
- data/spec/lib/dispatch-rider/notification_services_spec.rb +4 -0
- data/spec/lib/dispatch-rider/publisher/base_spec.rb +79 -0
- data/spec/lib/dispatch-rider/publisher/configuration/destination_spec.rb +100 -0
- data/spec/lib/dispatch-rider/publisher/configuration/notification_service_spec.rb +53 -0
- data/spec/lib/dispatch-rider/publisher/configuration_reader_spec.rb +129 -0
- data/spec/lib/dispatch-rider/publisher/configuration_spec.rb +149 -0
- data/spec/lib/dispatch-rider/publisher/configuration_support_spec.rb +89 -0
- data/spec/lib/dispatch-rider/publisher_spec.rb +123 -0
- data/spec/lib/dispatch-rider/queue_services/aws_sqs_spec.rb +193 -0
- data/spec/lib/dispatch-rider/queue_services/base_spec.rb +147 -0
- data/spec/lib/dispatch-rider/queue_services/file_system_spec.rb +88 -0
- data/spec/lib/dispatch-rider/queue_services/received_message_spec.rb +23 -0
- data/spec/lib/dispatch-rider/queue_services/simple_spec.rb +63 -0
- data/spec/lib/dispatch-rider/queue_services_spec.rb +6 -0
- data/spec/lib/dispatch-rider/registrars/base_spec.rb +68 -0
- data/spec/lib/dispatch-rider/registrars/file_system_channel_spec.rb +12 -0
- data/spec/lib/dispatch-rider/registrars/handler_spec.rb +16 -0
- data/spec/lib/dispatch-rider/registrars/notification_service_spec.rb +13 -0
- data/spec/lib/dispatch-rider/registrars/publishing_destination_spec.rb +11 -0
- data/spec/lib/dispatch-rider/registrars/queue_service_spec.rb +13 -0
- data/spec/lib/dispatch-rider/registrars/sns_channel_spec.rb +14 -0
- data/spec/lib/dispatch-rider/registrars_spec.rb +4 -0
- data/spec/lib/dispatch-rider/runner_spec.rb +25 -0
- data/spec/lib/dispatch-rider/subscriber_spec.rb +140 -0
- data/spec/lib/dispatch-rider_spec.rb +27 -0
- data/spec/spec_helper.rb +21 -0
- metadata +107 -86
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rspec/its'
|
3
|
+
|
4
|
+
describe DispatchRider::Publisher::Configuration::Destination do
|
5
|
+
|
6
|
+
let(:attributes) do
|
7
|
+
{
|
8
|
+
"service" => "aws_sns",
|
9
|
+
"channel" => "employee_updates",
|
10
|
+
"options" => options
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:options) do
|
15
|
+
{
|
16
|
+
"account" => "123456789",
|
17
|
+
"region" => "us-east",
|
18
|
+
"topic" => "employee-updates"
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
subject{ described_class.new("employee", attributes) }
|
23
|
+
|
24
|
+
describe "#name" do
|
25
|
+
its(:name) { is_expected.to eq("employee") }
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#service" do
|
29
|
+
its(:service) { is_expected.to eq("aws_sns") }
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#channel" do
|
33
|
+
its(:channel) { is_expected.to eq("employee_updates") }
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "#options" do
|
37
|
+
its(:options) { is_expected.to eq(options) }
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "#==" do
|
41
|
+
let(:other){ described_class.new(name, other_attributes) }
|
42
|
+
|
43
|
+
context "when the destinations' name, service, channel and options are the same" do
|
44
|
+
let(:name){ subject.name }
|
45
|
+
let(:other_attributes){ attributes }
|
46
|
+
|
47
|
+
it{ should eq other }
|
48
|
+
end
|
49
|
+
|
50
|
+
context "when the destinations' name is different" do
|
51
|
+
let(:name){ "account" }
|
52
|
+
let(:other_attributes){ attributes }
|
53
|
+
|
54
|
+
it{ should_not eq other }
|
55
|
+
end
|
56
|
+
|
57
|
+
context "when the destinations' service is different" do
|
58
|
+
let(:name){ subject.name }
|
59
|
+
|
60
|
+
let(:other_attributes) do
|
61
|
+
{
|
62
|
+
"service" => "file_system",
|
63
|
+
"channel" => "employee_updates",
|
64
|
+
"options" => options
|
65
|
+
}
|
66
|
+
end
|
67
|
+
|
68
|
+
it{ should_not eq other }
|
69
|
+
end
|
70
|
+
|
71
|
+
context "when the destinations' channel is different" do
|
72
|
+
let(:name){ subject.name }
|
73
|
+
|
74
|
+
let(:other_attributes) do
|
75
|
+
{
|
76
|
+
"service" => "aws_sns",
|
77
|
+
"channel" => "account_updates",
|
78
|
+
"options" => options
|
79
|
+
}
|
80
|
+
end
|
81
|
+
|
82
|
+
it{ should_not eq other }
|
83
|
+
end
|
84
|
+
|
85
|
+
context "when the destinations' options are different" do
|
86
|
+
let(:name){ subject.name }
|
87
|
+
|
88
|
+
let(:other_attributes) do
|
89
|
+
{
|
90
|
+
"service" => "aws_sns",
|
91
|
+
"channel" => "employee_updates",
|
92
|
+
"options" => {}
|
93
|
+
}
|
94
|
+
end
|
95
|
+
|
96
|
+
it{ should_not eq other }
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DispatchRider::Publisher::Configuration::NotificationService do
|
4
|
+
|
5
|
+
let(:options) do
|
6
|
+
{
|
7
|
+
"default_folder" => "/tmp/dispatch_rider"
|
8
|
+
}
|
9
|
+
end
|
10
|
+
|
11
|
+
subject{ described_class.new("file_system", options) }
|
12
|
+
|
13
|
+
describe "#name" do
|
14
|
+
its(:name){ should == "file_system" }
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "#options" do
|
18
|
+
its(:options){ should == options }
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "#==" do
|
22
|
+
let(:other){ described_class.new(name, other_options) }
|
23
|
+
|
24
|
+
context "two notification services with the same name and options" do
|
25
|
+
let(:name){ subject.name }
|
26
|
+
let(:other_options){ options }
|
27
|
+
|
28
|
+
it{ should eq other }
|
29
|
+
end
|
30
|
+
|
31
|
+
context "two notification services with different names but the same options" do
|
32
|
+
let(:name){ "aws_sns" }
|
33
|
+
let(:other_options){ options }
|
34
|
+
|
35
|
+
it{ should_not eq other }
|
36
|
+
end
|
37
|
+
|
38
|
+
context "two notificaiton services with the same name but different options" do
|
39
|
+
let(:name){ subject.name }
|
40
|
+
let(:other_options){ { "topic" => "employee_updates" } }
|
41
|
+
|
42
|
+
it{ should_not eq other }
|
43
|
+
end
|
44
|
+
|
45
|
+
context "two notification services with different names and options" do
|
46
|
+
let(:name){ "aws_sns" }
|
47
|
+
let(:other_options){ { "topic" => "employee_updates" } }
|
48
|
+
|
49
|
+
it{ should_not eq other }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DispatchRider::Publisher::ConfigurationReader do
|
4
|
+
|
5
|
+
let :publisher do
|
6
|
+
double(:publisher)
|
7
|
+
end
|
8
|
+
|
9
|
+
describe ".load_config" do
|
10
|
+
|
11
|
+
subject { described_class }
|
12
|
+
|
13
|
+
it "responds to :load_config" do
|
14
|
+
subject.should respond_to :load_config
|
15
|
+
end
|
16
|
+
|
17
|
+
it "requires 2 paramaters" do
|
18
|
+
expect {
|
19
|
+
subject.load_config
|
20
|
+
}.to raise_exception(ArgumentError, /0 for 2/)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "deals with an empty configuration hash" do
|
24
|
+
expect {
|
25
|
+
subject.load_config(DispatchRider::Publisher::Configuration.new, publisher)
|
26
|
+
}.to_not raise_exception
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "notification_services parsing" do
|
30
|
+
|
31
|
+
let(:configuration){ DispatchRider::Publisher::Configuration.new(configuration_hash) }
|
32
|
+
|
33
|
+
context "when notification_services has no items in it" do
|
34
|
+
|
35
|
+
let :configuration_hash do
|
36
|
+
{
|
37
|
+
notification_services: {
|
38
|
+
}
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
it "doesn't call register_notification_service" do
|
43
|
+
publisher.should_not_receive(:register_notification_service)
|
44
|
+
subject.load_config(configuration, publisher)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "when notification_services has an item in it" do
|
49
|
+
let :configuration_hash do
|
50
|
+
{
|
51
|
+
notification_services: {
|
52
|
+
file_system: {}
|
53
|
+
}
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
it "calls register_notification_service with :file_system and {}" do
|
58
|
+
publisher.should_receive(:register_notification_service).with("file_system", {})
|
59
|
+
subject.load_config(configuration, publisher)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "when notification_services has 2 items in it" do
|
64
|
+
let :configuration_hash do
|
65
|
+
{
|
66
|
+
notification_services: {
|
67
|
+
file_system: {},
|
68
|
+
foo: {bar: "123"},
|
69
|
+
}
|
70
|
+
}
|
71
|
+
end
|
72
|
+
|
73
|
+
it "calls register_notification_service with :file_system and {}, as well as :foo, {bar: '123'}" do
|
74
|
+
publisher.should_receive(:register_notification_service).with("file_system", {})
|
75
|
+
publisher.should_receive(:register_notification_service).with("foo", {"bar" => "123"})
|
76
|
+
subject.load_config(configuration, publisher)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "destinations" do
|
83
|
+
|
84
|
+
let(:configuration){ DispatchRider::Publisher::Configuration.new(configuration_hash) }
|
85
|
+
|
86
|
+
context "when destinations has no items in it" do
|
87
|
+
|
88
|
+
let :configuration_hash do
|
89
|
+
{
|
90
|
+
destinations: {
|
91
|
+
}
|
92
|
+
}
|
93
|
+
end
|
94
|
+
|
95
|
+
it "doesn't call register_destination" do
|
96
|
+
publisher.should_not_receive(:register_destination)
|
97
|
+
subject.load_config(configuration, publisher)
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
context "when destinations has items in it" do
|
103
|
+
|
104
|
+
let :configuration_hash do
|
105
|
+
{
|
106
|
+
destinations: {
|
107
|
+
out1:{
|
108
|
+
service: :file_system,
|
109
|
+
channel: :foo,
|
110
|
+
options: {
|
111
|
+
path: "tmp/test/channel"
|
112
|
+
}
|
113
|
+
}
|
114
|
+
}
|
115
|
+
}
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should call register_destination with the right parameters" do
|
119
|
+
publisher.should_receive(:register_destination).exactly(1).times.with("out1", :file_system, :foo, "path" => "tmp/test/channel")
|
120
|
+
subject.load_config(configuration, publisher)
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
|
127
|
+
end # .load_config
|
128
|
+
|
129
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DispatchRider::Publisher::Configuration do
|
4
|
+
|
5
|
+
let(:configuration_hash) do
|
6
|
+
{
|
7
|
+
"notification_services" => {
|
8
|
+
"file_system" => {
|
9
|
+
"default_folder" => "tmp/dispatch_rider"
|
10
|
+
},
|
11
|
+
"aws_sns" => {}
|
12
|
+
},
|
13
|
+
"destinations" => {
|
14
|
+
"employee_updates" => {
|
15
|
+
"service" => "file_system",
|
16
|
+
"channel" => "employee_updates",
|
17
|
+
"options" => {
|
18
|
+
"file_prefix" => "employee_"
|
19
|
+
}
|
20
|
+
},
|
21
|
+
"account_updates" => {
|
22
|
+
"service" => "aws_sns",
|
23
|
+
"channel" => "account_updates",
|
24
|
+
"options" => {
|
25
|
+
"account" => "123456789",
|
26
|
+
"region" => "us-east",
|
27
|
+
"topic" => "account-updates"
|
28
|
+
}
|
29
|
+
}
|
30
|
+
}
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
subject{ described_class.new(configuration_hash) }
|
35
|
+
|
36
|
+
describe "#notification services" do
|
37
|
+
let(:file_system) do
|
38
|
+
DispatchRider::Publisher::Configuration::NotificationService.new(
|
39
|
+
"file_system",
|
40
|
+
{ "default_folder" => "tmp/dispatch_rider" }
|
41
|
+
)
|
42
|
+
end
|
43
|
+
|
44
|
+
let(:sns) do
|
45
|
+
DispatchRider::Publisher::Configuration::NotificationService.new("aws_sns", {})
|
46
|
+
end
|
47
|
+
|
48
|
+
it "contains both notification services" do
|
49
|
+
subject.notification_services.count.should == 2
|
50
|
+
subject.notification_services.should =~ [file_system, sns]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "#destinations" do
|
55
|
+
let(:employee_updates) do
|
56
|
+
DispatchRider::Publisher::Configuration::Destination.new(
|
57
|
+
"employee_updates",
|
58
|
+
{
|
59
|
+
"service" => "file_system",
|
60
|
+
"channel" => "employee_updates",
|
61
|
+
"options" => {
|
62
|
+
"file_prefix" => "employee_"
|
63
|
+
}
|
64
|
+
}
|
65
|
+
)
|
66
|
+
end
|
67
|
+
|
68
|
+
let(:account_updates) do
|
69
|
+
DispatchRider::Publisher::Configuration::Destination.new(
|
70
|
+
"account_updates",
|
71
|
+
{
|
72
|
+
"service" => "aws_sns",
|
73
|
+
"channel" => "account_updates",
|
74
|
+
"options" => {
|
75
|
+
"account" => "123456789",
|
76
|
+
"region" => "us-east",
|
77
|
+
"topic" => "account-updates"
|
78
|
+
}
|
79
|
+
}
|
80
|
+
)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "contains both destinations" do
|
84
|
+
subject.destinations.count.should == 2
|
85
|
+
subject.destinations.should =~ [employee_updates, account_updates]
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "#clear" do
|
90
|
+
example do
|
91
|
+
expect{
|
92
|
+
subject.clear
|
93
|
+
}.to change(subject.notification_services, :count).by(-2)
|
94
|
+
end
|
95
|
+
|
96
|
+
example do
|
97
|
+
expect{
|
98
|
+
subject.clear
|
99
|
+
}.to change(subject.destinations, :count).by(-2)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe "#parse" do
|
104
|
+
let(:new_configuration_hash) do
|
105
|
+
{
|
106
|
+
"notification_services" => {
|
107
|
+
"aws_sqs" => {}
|
108
|
+
},
|
109
|
+
"destinations" => {
|
110
|
+
"user_deletion" => {
|
111
|
+
"service" => "aws_sqs",
|
112
|
+
"channel" => "user_deletion",
|
113
|
+
"options" => {}
|
114
|
+
}
|
115
|
+
}
|
116
|
+
}
|
117
|
+
end
|
118
|
+
|
119
|
+
let(:notification_service) do
|
120
|
+
DispatchRider::Publisher::Configuration::NotificationService.new("aws_sqs", {})
|
121
|
+
end
|
122
|
+
|
123
|
+
let(:destination) do
|
124
|
+
DispatchRider::Publisher::Configuration::Destination.new(
|
125
|
+
"user_deletion",
|
126
|
+
{
|
127
|
+
"service" => "aws_sqs",
|
128
|
+
"channel" => "user_deletion",
|
129
|
+
"options" => {}
|
130
|
+
}
|
131
|
+
)
|
132
|
+
end
|
133
|
+
|
134
|
+
before :each do
|
135
|
+
subject.parse(new_configuration_hash)
|
136
|
+
end
|
137
|
+
|
138
|
+
it "replaces the current notification services with the new notification service" do
|
139
|
+
subject.notification_services.count.should == 1
|
140
|
+
subject.notification_services.should =~ [notification_service]
|
141
|
+
end
|
142
|
+
|
143
|
+
it "replaces the current destinations with the new destination" do
|
144
|
+
subject.destinations.count.should == 1
|
145
|
+
subject.destinations.should =~ [destination]
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DispatchRider::Publisher::ConfigurationSupport do
|
4
|
+
|
5
|
+
subject{ Object.new.extend(described_class) }
|
6
|
+
|
7
|
+
describe ".configuration" do
|
8
|
+
example do
|
9
|
+
subject.configuration.should be_a(DispatchRider::Publisher::Configuration)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe ".config" do
|
14
|
+
example do
|
15
|
+
subject.method(:config).should == subject.method(:configuration)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe ".configure" do
|
20
|
+
let :configuration_hash do
|
21
|
+
{
|
22
|
+
notification_services: {
|
23
|
+
file_system: {}
|
24
|
+
},
|
25
|
+
destinations: {
|
26
|
+
file_foo: {
|
27
|
+
service: :file_system,
|
28
|
+
channel: :foo,
|
29
|
+
options: {
|
30
|
+
path: "tmp/test/channel",
|
31
|
+
}
|
32
|
+
}
|
33
|
+
}
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
let(:notification_service) do
|
38
|
+
DispatchRider::Publisher::Configuration::NotificationService.new("file_system", {})
|
39
|
+
end
|
40
|
+
|
41
|
+
let(:destination) do
|
42
|
+
DispatchRider::Publisher::Configuration::Destination.new(
|
43
|
+
"file_foo",
|
44
|
+
{
|
45
|
+
service: :file_system,
|
46
|
+
channel: :foo,
|
47
|
+
options: {
|
48
|
+
path: "tmp/test/channel"
|
49
|
+
}
|
50
|
+
}
|
51
|
+
)
|
52
|
+
end
|
53
|
+
|
54
|
+
context "when configuring with a hash" do
|
55
|
+
before :each do
|
56
|
+
subject.configure(configuration_hash)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "sets the configuration's notification services correctly" do
|
60
|
+
subject.configuration.notification_services.count.should == 1
|
61
|
+
subject.configuration.notification_services.should =~ [notification_service]
|
62
|
+
end
|
63
|
+
|
64
|
+
it "sets the configuration's destinations correctly" do
|
65
|
+
subject.configuration.destinations.count.should == 1
|
66
|
+
subject.configuration.destinations.should =~ [destination]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context "when configuring with a block" do
|
71
|
+
before :each do
|
72
|
+
subject.configure do |config|
|
73
|
+
config.parse(configuration_hash)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
it "sets the configuration's notification services correctly" do
|
78
|
+
subject.configuration.notification_services.count.should == 1
|
79
|
+
subject.configuration.notification_services.should =~ [notification_service]
|
80
|
+
end
|
81
|
+
|
82
|
+
it "sets the configuration's destinations correctly" do
|
83
|
+
subject.configuration.destinations.count.should == 1
|
84
|
+
subject.configuration.destinations.should =~ [destination]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|