rabbitmq-definition 0.1.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.
Files changed (71) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +4 -0
  5. data/Gemfile.lock +181 -0
  6. data/README.md +57 -0
  7. data/lib/rabbitmq-definition.rb +46 -0
  8. data/lib/rabbitmq_definition/command.rb +28 -0
  9. data/lib/rabbitmq_definition/create.rb +35 -0
  10. data/lib/rabbitmq_definition/drop.rb +36 -0
  11. data/lib/rabbitmq_definition/dump.rb +41 -0
  12. data/lib/rabbitmq_definition/engine.rb +7 -0
  13. data/lib/rabbitmq_definition/file_definition.rb +54 -0
  14. data/lib/rabbitmq_definition/load.rb +14 -0
  15. data/lib/rabbitmq_definition/logger.rb +19 -0
  16. data/lib/rabbitmq_definition/rabbitmq-definition.rake +21 -0
  17. data/lib/rabbitmq_definition/version.rb +5 -0
  18. data/rabbitmq-definition.gemspec +34 -0
  19. data/spec/dummy/README.rdoc +28 -0
  20. data/spec/dummy/Rakefile +6 -0
  21. data/spec/dummy/app/assets/images/.keep +0 -0
  22. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  23. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  24. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  25. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  26. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  27. data/spec/dummy/app/mailers/.keep +0 -0
  28. data/spec/dummy/app/models/.keep +0 -0
  29. data/spec/dummy/app/models/activity.rb +2 -0
  30. data/spec/dummy/app/models/concerns/.keep +0 -0
  31. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  32. data/spec/dummy/config.ru +4 -0
  33. data/spec/dummy/config/application.rb +24 -0
  34. data/spec/dummy/config/boot.rb +5 -0
  35. data/spec/dummy/config/database.yml +20 -0
  36. data/spec/dummy/config/environment.rb +5 -0
  37. data/spec/dummy/config/environments/development.rb +26 -0
  38. data/spec/dummy/config/environments/production.rb +80 -0
  39. data/spec/dummy/config/environments/test.rb +36 -0
  40. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  41. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  42. data/spec/dummy/config/initializers/inflections.rb +16 -0
  43. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  44. data/spec/dummy/config/initializers/secret_token.rb +12 -0
  45. data/spec/dummy/config/initializers/session_store.rb +3 -0
  46. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  47. data/spec/dummy/config/locales/en.yml +23 -0
  48. data/spec/dummy/config/routes.rb +56 -0
  49. data/spec/dummy/db/migrate/20131203172849_create_activities.rb +9 -0
  50. data/spec/dummy/db/rabbitmq_definition.json +43 -0
  51. data/spec/dummy/db/schema.rb +26 -0
  52. data/spec/dummy/lib/assets/.keep +0 -0
  53. data/spec/dummy/log/.keep +0 -0
  54. data/spec/dummy/log/development.log +0 -0
  55. data/spec/dummy/public/404.html +58 -0
  56. data/spec/dummy/public/422.html +58 -0
  57. data/spec/dummy/public/500.html +57 -0
  58. data/spec/dummy/public/favicon.ico +0 -0
  59. data/spec/fixtures/create.json +18 -0
  60. data/spec/fixtures/example1.json +41 -0
  61. data/spec/helpers/listing_helper.rb +23 -0
  62. data/spec/helpers/matchers.rb +29 -0
  63. data/spec/integration/rabbitmq_definition_spec.rb +101 -0
  64. data/spec/rabbitmq_definition/command_spec.rb +23 -0
  65. data/spec/rabbitmq_definition/create_spec.rb +60 -0
  66. data/spec/rabbitmq_definition/drop_spec.rb +74 -0
  67. data/spec/rabbitmq_definition/dump_spec.rb +147 -0
  68. data/spec/rabbitmq_definition/load_spec.rb +40 -0
  69. data/spec/rabbitmq_definition_spec.rb +39 -0
  70. data/spec/spec_helper.rb +25 -0
  71. metadata +347 -0
File without changes
@@ -0,0 +1,18 @@
1
+ {
2
+ "rabbit_version": "3.5.0",
3
+ "version": "20091026044709",
4
+ "vhosts": [
5
+ {
6
+ "name": "/test"
7
+ }
8
+ ],
9
+ "queues": [
10
+
11
+ ],
12
+ "bindings": [
13
+
14
+ ],
15
+ "exchanges": [
16
+
17
+ ]
18
+ }
@@ -0,0 +1,41 @@
1
+ {
2
+ "rabbit_version": "3.5.0",
3
+ "version": "20091026044709",
4
+ "vhosts": [
5
+ { "name": "/test" }
6
+ ],
7
+ "queues": [
8
+ {
9
+ "name": "my-queue",
10
+ "vhost": "/test",
11
+ "durable": true,
12
+ "auto_delete": false,
13
+ "arguments": {
14
+ "x-dead-letter-exchange": "dead"
15
+ }
16
+ }
17
+ ],
18
+ "exchanges": [
19
+ {
20
+ "name": "my-exchange",
21
+ "vhost": "/test",
22
+ "type": "topic",
23
+ "durable": true,
24
+ "auto_delete": false,
25
+ "internal": false,
26
+ "arguments": {
27
+ }
28
+ }
29
+ ],
30
+ "bindings": [
31
+ {
32
+ "source": "my-exchange",
33
+ "vhost": "/test",
34
+ "destination": "my-queue",
35
+ "destination_type": "queue",
36
+ "routing_key": "my-routing-key.#",
37
+ "arguments": {
38
+ }
39
+ }
40
+ ]
41
+ }
@@ -0,0 +1,23 @@
1
+ module ListingHelper
2
+ def select_queues(client, vhost)
3
+ client.list_queues(vhost).select do |queue|
4
+ !is_default_entity?(queue.name)
5
+ end
6
+ end
7
+
8
+ def select_exchanges(client, vhost)
9
+ client.list_exchanges(vhost).select do |exchange|
10
+ !is_default_entity?(exchange.name)
11
+ end
12
+ end
13
+
14
+ def select_bindings(client, vhost)
15
+ client.list_bindings(vhost).select do |binding|
16
+ !is_default_entity?(binding.source)
17
+ end
18
+ end
19
+
20
+ def is_default_entity?(name)
21
+ name.empty? || name.start_with?("amq.")
22
+ end
23
+ end
@@ -0,0 +1,29 @@
1
+ RSpec::Matchers.define :match_definition do |expected_example|
2
+ def extract_definition_comparable_json(path)
3
+ if File.exist?(path)
4
+ content = File.read(path)
5
+ json = JSON.parse(content)
6
+ json.except('rabbit_version')
7
+ else
8
+ nil
9
+ end
10
+ end
11
+
12
+ match do |actual_path|
13
+ @actual_json = extract_definition_comparable_json(actual)
14
+ expected_path = File.expand_path("../../fixtures/" + expected_example, __FILE__)
15
+ @expected_json = extract_definition_comparable_json(expected_path)
16
+ end
17
+
18
+ failure_message do |actual_path|
19
+ if @actual_json.nil?
20
+ "'#{actual_path}' file does NOT exist"
21
+ else
22
+ "expected: \n#{@actual_json.pretty_inspect}\n\n to match definition: \n#{@expected_json.pretty_inspect}\n\n"
23
+ end
24
+ end
25
+
26
+ description do
27
+ "matches definition in '#{expected_example}'"
28
+ end
29
+ end
@@ -0,0 +1,101 @@
1
+ describe "RabbitMQ::Definition" do
2
+ include ListingHelper
3
+ let(:client) { RabbitMQ::Definition.client }
4
+ let(:vhost) { "/test" }
5
+ let(:file_path) { RabbitMQ::Definition::FileDefinition.file_path }
6
+
7
+ before do
8
+ WebMock.disable_net_connect!(:allow_localhost => true)
9
+ allow(RabbitMQ::Definition::FileDefinition).to receive(:file_path).and_call_original
10
+ client.delete_vhost('/test') rescue nil
11
+ client.create_vhost('/other-test-vhost') # existing unrelated vhost
12
+ File.delete(file_path) if File.exist?(file_path)
13
+ time = Time.iso8601("2009-10-26T04:47:09Z")
14
+ Timecop.freeze(time)
15
+ end
16
+
17
+ after do
18
+ client.delete_vhost('/other-test-vhost')
19
+ WebMock.disable_net_connect!(:allow => "codeclimate.com")
20
+ Timecop.return
21
+ end
22
+
23
+ def read_fixture(path)
24
+ path = File.join(File.dirname(__FILE__), '../fixtures/', path)
25
+ File.read(path)
26
+ end
27
+
28
+ describe ".create" do
29
+ it "creates a vhost" do
30
+ initial_count = client.list_vhosts.count
31
+ RabbitMQ::Definition.create([vhost])
32
+ expect(client.list_vhosts.count).to eq(initial_count + 1)
33
+ end
34
+
35
+ it "stores the rabbitmq_definition.json file" do
36
+ RabbitMQ::Definition.create([vhost])
37
+ expect(file_path).to match_definition('create.json')
38
+ end
39
+ end
40
+
41
+ describe ".drop" do
42
+ before do
43
+ fixture = read_fixture('example1.json')
44
+ File.write(file_path, fixture)
45
+ expect_any_instance_of(RabbitMQ::Definition::Drop).to receive(:agree).and_return(true)
46
+ client.upload_definitions(fixture)
47
+ client.update_permissions_of(vhost, 'guest', {
48
+ :configure => ".*",
49
+ :write => ".*",
50
+ :read => ".*"
51
+ })
52
+ end
53
+
54
+ it "removes virtual host" do
55
+ RabbitMQ::Definition.drop
56
+ vhost_names = client.list_vhosts.map{|v| v[:name]}
57
+ expect(vhost_names).not_to include('/test')
58
+ end
59
+
60
+ it "does NOT remove other virtual hosts" do
61
+ RabbitMQ::Definition.drop
62
+ vhost_names = client.list_vhosts.map{|v| v[:name]}
63
+ expect(vhost_names).to include('/other-test-vhost')
64
+ end
65
+ end
66
+
67
+ describe ".dump" do
68
+ before do
69
+ File.write(file_path, read_fixture('create.json'))
70
+ client.upload_definitions(read_fixture('example1.json'))
71
+ client.update_permissions_of(vhost, 'guest', {
72
+ :configure => ".*",
73
+ :write => ".*",
74
+ :read => ".*"
75
+ })
76
+ end
77
+
78
+ it "saves the definition" do
79
+ RabbitMQ::Definition.dump
80
+ expect(file_path).to match_definition('example1.json')
81
+ end
82
+ end
83
+
84
+ describe ".load" do
85
+ before do
86
+ File.write(file_path, read_fixture('example1.json'))
87
+ client.upload_definitions(read_fixture('create.json'))
88
+ client.update_permissions_of(vhost, 'guest', {
89
+ :configure => ".*",
90
+ :write => ".*",
91
+ :read => ".*"
92
+ })
93
+ end
94
+
95
+ it "loads the definition" do
96
+ RabbitMQ::Definition.load
97
+ RabbitMQ::Definition.dump
98
+ expect(file_path).to match_definition('example1.json')
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,23 @@
1
+ describe RabbitMQ::Definition::Command do
2
+
3
+ describe "#initialize" do
4
+ it "sets the client" do
5
+ client = double("client")
6
+ command = RabbitMQ::Definition::Command.new(client, false)
7
+ expect(command.client).to eq(client)
8
+ end
9
+
10
+ it "sets the verbosity" do
11
+ command = RabbitMQ::Definition::Command.new(nil, true)
12
+ expect(command.verbose).to eq(true)
13
+ end
14
+ end
15
+
16
+ describe "#execute" do
17
+ it "raises NotImplementedError" do
18
+ expect{
19
+ RabbitMQ::Definition::Command.new(nil, nil).execute
20
+ }.to raise_error(NotImplementedError)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,60 @@
1
+ describe RabbitMQ::Definition::Create do
2
+ let(:client) do
3
+ double("client",
4
+ :create_vhost => true,
5
+ :update_permissions_of => true,
6
+ :endpoint => ENV['RABBITMQ_MANAGEMENT_URL']
7
+ )
8
+ end
9
+ before { allow(RabbitMQ::Definition::Dump).to receive(:run).and_return(true) }
10
+
11
+ context "when a definition file does already exist" do
12
+ before { allow(RabbitMQ::Definition::FileDefinition).to receive(:exists?).and_return(true) }
13
+
14
+ it "notifies about error when a definition file already exists" do
15
+ expect(RabbitMQ::Definition::Logger).to receive(:error).with("Definition file already exists in ./db/rabbitmq_definition.json").once
16
+ described_class.run(client, false, ["/"])
17
+ end
18
+
19
+ it "does NOT save the schema" do
20
+ expect_any_instance_of(RabbitMQ::Definition::FileDefinition).not_to receive(:save)
21
+ described_class.run(client, false, ["/"])
22
+ end
23
+ end
24
+
25
+ context "when a definition file does NOT exist" do
26
+ before { allow(RabbitMQ::Definition::FileDefinition).to receive(:exists?).and_return(false) }
27
+
28
+ it "notifies progress on each vhost when verobse" do
29
+ expect(RabbitMQ::Definition::Logger).to receive(:progress).with("Creating vhost '/'").once
30
+ described_class.run(client, true, ["/"])
31
+ end
32
+
33
+ it "creates each vhost" do
34
+ expect(client).to receive(:create_vhost).with('/').once
35
+ described_class.run(client, false, ["/"])
36
+ end
37
+
38
+ it "adds permission for the current user to each vhost" do
39
+ expect(client).to receive(:update_permissions_of)
40
+ .with(
41
+ '/',
42
+ 'guest',
43
+ {
44
+ :configure => ".*",
45
+ :write => ".*",
46
+ :read => ".*"
47
+ }
48
+ ).once
49
+ described_class.run(client, false, ["/"])
50
+ end
51
+
52
+ it "dumps the created hosts definitions" do
53
+ expect(RabbitMQ::Definition::Dump).to receive(:run)
54
+ .with(client, false, ["/"])
55
+ described_class.run(client, false, ["/"])
56
+ end
57
+
58
+ end
59
+
60
+ end
@@ -0,0 +1,74 @@
1
+ describe RabbitMQ::Definition::Drop do
2
+ let(:client) { double("client", :delete_vhost => nil) }
3
+ let(:vhost) { '/' }
4
+ let(:definition) do
5
+ RabbitMQ::Definition::FileDefinition.new(
6
+ :vhosts => [{'name' => '/'}]
7
+ )
8
+ end
9
+ before do
10
+ allow(RabbitMQ::Definition::FileDefinition).to receive(:exists?).and_return(true)
11
+ allow(RabbitMQ::Definition::FileDefinition).to receive(:read).and_return(definition)
12
+ allow_any_instance_of(RabbitMQ::Definition::FileDefinition).to receive(:destroy).and_return(true)
13
+ end
14
+
15
+ context "when file definition does NOT exist" do
16
+ before { expect(RabbitMQ::Definition::FileDefinition).to receive(:exists?).and_return(false) }
17
+
18
+ it "notitifies the error" do
19
+ expect(RabbitMQ::Definition::Logger).to receive(:error).with("No definition with vhosts exists")
20
+ described_class.run(client, false)
21
+ end
22
+
23
+ it "does not delete any hosts" do
24
+ expect(client).not_to receive(:delete_host)
25
+ described_class.run(client, false)
26
+ end
27
+ end
28
+
29
+ context "when user does NOT want to proceed" do
30
+
31
+ before { expect_any_instance_of(described_class).to receive(:agree).and_return(false) }
32
+
33
+ it "notitifies the error" do
34
+ expect(RabbitMQ::Definition::Logger).to receive(:error).with("Aborted by user")
35
+ described_class.run(client, false)
36
+ end
37
+
38
+ it "does not delete any hosts" do
39
+ expect(client).not_to receive(:delete_host)
40
+ described_class.run(client, false)
41
+ end
42
+ end
43
+
44
+ context "when the user proceeds" do
45
+
46
+ before { expect_any_instance_of(described_class).to receive(:agree).and_return(true) }
47
+
48
+ it "notifies about progress" do
49
+ expect(RabbitMQ::Definition::Logger).to receive(:progress).with("Removing definition...").once
50
+ described_class.run(client, false)
51
+ end
52
+
53
+ it "notifies about progress deleting each host when verbose" do
54
+ expect(RabbitMQ::Definition::Logger).to receive(:progress).with("Deleting vhost '/'...").once
55
+ described_class.run(client, true)
56
+ end
57
+
58
+ it "deletes the vhosts" do
59
+ expect(client).to receive(:delete_vhost).with("/").once
60
+ described_class.run(client, false)
61
+ end
62
+
63
+ it "notifies about success" do
64
+ expect(RabbitMQ::Definition::Logger).to receive(:success).with("Done").once
65
+ described_class.run(client, false)
66
+ end
67
+
68
+ it "deletes the definition file" do
69
+ expect_any_instance_of(RabbitMQ::Definition::FileDefinition).to receive(:destroy).once
70
+ described_class.run(client, false)
71
+ end
72
+ end
73
+
74
+ end
@@ -0,0 +1,147 @@
1
+ describe RabbitMQ::Definition::Dump do
2
+ let(:list_definitions) do
3
+ {
4
+ 'rabbit_version' => "3.5.0",
5
+ 'vhosts' => [{'name' => '/'}, 'name' => '/other-vhost'],
6
+ 'queues' => [
7
+ {
8
+ "name" => "my-queue",
9
+ "vhost" => "/",
10
+ "durable" => true,
11
+ "auto_delete" => false,
12
+ "arguments" => {
13
+ "x-dead-letter-exchange" => "dead"
14
+ }
15
+ },
16
+ {
17
+ "name" => "other-vhost-queue",
18
+ "vhost" => "/other-vhost"
19
+ }
20
+ ],
21
+ 'exchanges' => [
22
+ {
23
+ "name" => "my-exchange",
24
+ "vhost" => "/",
25
+ "type" => "topic",
26
+ "durable" => true,
27
+ "auto_delete" => false,
28
+ "internal" => false,
29
+ "arguments" => {
30
+ }
31
+ },
32
+ {
33
+ "name" => "other-vhost-exchange",
34
+ "vhost" => "/other-vhost",
35
+ "type" => "topic",
36
+ "durable" => true,
37
+ "auto_delete" => false,
38
+ "internal" => false,
39
+ "arguments" => {
40
+ }
41
+ }
42
+ ],
43
+ 'bindings' => [
44
+ {
45
+ "source" => "my-exchange",
46
+ "vhost" => "/",
47
+ "destination" => "my-queue",
48
+ "destination_type" => "queue",
49
+ "routing_key" => "my-routing-key.#",
50
+ "arguments" => {
51
+ }
52
+ },
53
+ {
54
+ "source" => "other-vhost-exchange",
55
+ "vhost" => "/other-vhost",
56
+ "destination" => "other-vhost-queue",
57
+ "destination_type" => "queue",
58
+ "routing_key" => "other-routing-key.#",
59
+ "arguments" => {
60
+ }
61
+ }
62
+ ]
63
+ }
64
+ end
65
+ let(:filtered_definition_hash) do
66
+ {
67
+ 'rabbit_version' => "3.5.0",
68
+ 'vhosts' => [
69
+ { 'name' => "/" }
70
+ ],
71
+ 'queues' => [
72
+ {
73
+ "name" => "my-queue",
74
+ "vhost" => "/",
75
+ "durable" => true,
76
+ "auto_delete" => false,
77
+ "arguments" => {
78
+ "x-dead-letter-exchange" => "dead"
79
+ }
80
+ }
81
+ ],
82
+ 'exchanges' => [
83
+ {
84
+ "name" => "my-exchange",
85
+ "vhost" => "/",
86
+ "type" => "topic",
87
+ "durable" => true,
88
+ "auto_delete" => false,
89
+ "internal" => false,
90
+ "arguments" => {
91
+ }
92
+ }
93
+ ],
94
+ 'bindings' => [
95
+ {
96
+ "source" => "my-exchange",
97
+ "vhost" => "/",
98
+ "destination" => "my-queue",
99
+ "destination_type" => "queue",
100
+ "routing_key" => "my-routing-key.#",
101
+ "arguments" => {
102
+ }
103
+ }
104
+ ]
105
+ }
106
+ end
107
+ let(:client) do
108
+ double(
109
+ "client",
110
+ :list_definitions => list_definitions
111
+ )
112
+ end
113
+ before { allow_any_instance_of(RabbitMQ::Definition::FileDefinition).to receive(:save).and_return(true) }
114
+
115
+ it "notifies about progress" do
116
+ expect(RabbitMQ::Definition::Logger).to receive(:progress).with("Saving definition...").once
117
+ described_class.run(client, false, [])
118
+ end
119
+
120
+ it "notifies about definition payload when verbose" do
121
+ json = double("json")
122
+ allow_any_instance_of(RabbitMQ::Definition::FileDefinition).to receive(:to_json).and_return(json)
123
+ expect(RabbitMQ::Definition::Logger).to receive(:info).with(json).once
124
+ described_class.run(client, true, ['/'])
125
+ end
126
+
127
+ it "notifies success" do
128
+ expect(RabbitMQ::Definition::Logger).to receive(:success).with("Done").once
129
+ described_class.run(client, false, [])
130
+ end
131
+
132
+ it "generates the file definition with the filtered list definitions" do
133
+ definition = double("Definition")
134
+ expect(RabbitMQ::Definition::FileDefinition).to receive(:new).with(filtered_definition_hash).and_return(definition)
135
+ expect(definition).to receive(:save).once
136
+ described_class.run(client, false, ['/'])
137
+ end
138
+
139
+ it "generates the file definition with the filtered list definitions taking vhosts from files" do
140
+ original_definition = double(:vhosts => [{'name' => '/'}])
141
+ expect(RabbitMQ::Definition::FileDefinition).to receive(:read).and_return(original_definition)
142
+ definition = double("Definition")
143
+ expect(RabbitMQ::Definition::FileDefinition).to receive(:new).with(filtered_definition_hash).and_return(definition)
144
+ expect(definition).to receive(:save).once
145
+ described_class.run(client, false)
146
+ end
147
+ end