torquebox-backstage 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 (65) hide show
  1. data/Gemfile +18 -0
  2. data/Gemfile.lock +69 -0
  3. data/README.md +164 -0
  4. data/Rakefile +32 -0
  5. data/TODO +9 -0
  6. data/TORQUEBOX_VERSION +1 -0
  7. data/VERSION +1 -0
  8. data/backstage.rb +84 -0
  9. data/bin/backstage +78 -0
  10. data/config.ru +3 -0
  11. data/config/torquebox.yml +14 -0
  12. data/lib/apps.rb +18 -0
  13. data/lib/apps/models/app.rb +33 -0
  14. data/lib/apps/routes.rb +18 -0
  15. data/lib/authentication.rb +64 -0
  16. data/lib/destinations.rb +21 -0
  17. data/lib/destinations/models/destination.rb +80 -0
  18. data/lib/destinations/models/message.rb +67 -0
  19. data/lib/destinations/models/queue.rb +33 -0
  20. data/lib/destinations/models/topic.rb +59 -0
  21. data/lib/destinations/routes.rb +44 -0
  22. data/lib/has_mbean.rb +59 -0
  23. data/lib/helpers.rb +142 -0
  24. data/lib/jobs.rb +19 -0
  25. data/lib/jobs/models/job.rb +35 -0
  26. data/lib/jobs/routes.rb +18 -0
  27. data/lib/message_processors.rb +18 -0
  28. data/lib/message_processors/models/message_processor.rb +40 -0
  29. data/lib/message_processors/routes.rb +18 -0
  30. data/lib/pools.rb +18 -0
  31. data/lib/pools/models/pool.rb +51 -0
  32. data/lib/pools/routes.rb +41 -0
  33. data/lib/resource.rb +53 -0
  34. data/lib/resource_helpers.rb +63 -0
  35. data/lib/runtimes.rb +19 -0
  36. data/lib/runtimes/models/job.rb +35 -0
  37. data/lib/runtimes/routes.rb +18 -0
  38. data/lib/services.rb +18 -0
  39. data/lib/services/models/service.rb +35 -0
  40. data/lib/services/routes.rb +17 -0
  41. data/lib/torquebox_managed.rb +36 -0
  42. data/lib/util.rb +33 -0
  43. data/spec/api_spec.rb +136 -0
  44. data/spec/auth_spec.rb +70 -0
  45. data/spec/spec_helper.rb +39 -0
  46. data/views/apps/index.haml +15 -0
  47. data/views/apps/show.haml +12 -0
  48. data/views/css/_mixins.sass +51 -0
  49. data/views/css/html5reset.sass +82 -0
  50. data/views/css/style.sass +152 -0
  51. data/views/destinations/index.haml +37 -0
  52. data/views/destinations/show.haml +18 -0
  53. data/views/jobs/index.haml +23 -0
  54. data/views/jobs/show.haml +13 -0
  55. data/views/layout.haml +31 -0
  56. data/views/message_processors/index.haml +28 -0
  57. data/views/message_processors/show.haml +12 -0
  58. data/views/messages/index.haml +20 -0
  59. data/views/messages/properties.haml +3 -0
  60. data/views/messages/show.haml +19 -0
  61. data/views/pools/index.haml +32 -0
  62. data/views/pools/show.haml +44 -0
  63. data/views/services/index.haml +21 -0
  64. data/views/services/show.haml +13 -0
  65. metadata +289 -0
@@ -0,0 +1,53 @@
1
+ #
2
+ # Copyright 2011 Red Hat, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ module Backstage
18
+ module Resource
19
+
20
+ def self.included(base)
21
+ base.extend( ClassMethods )
22
+ base.send( :attr_accessor, :parent )
23
+ end
24
+
25
+ def association_chain
26
+ chain = []
27
+ chain << parent if parent
28
+ chain << self
29
+ chain
30
+ end
31
+
32
+ def to_hash
33
+ self.class.to_hash_attributes.inject({ }) do |response, attribute|
34
+ response[attribute] = __send__( attribute )
35
+ response
36
+ end
37
+ end
38
+
39
+ def resource
40
+ self
41
+ end
42
+
43
+ def available_actions
44
+ []
45
+ end
46
+
47
+ module ClassMethods
48
+ def to_hash_attributes
49
+ [:resource]
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,63 @@
1
+ #
2
+ # Copyright 2011 Red Hat, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ module Backstage
18
+ class Application < Sinatra::Base
19
+ def self.resource(*resources)
20
+ options = resources.pop if resources.last.is_a?(Hash)
21
+ options ||= {}
22
+ resources.each do |resource|
23
+ resource = resource.to_s
24
+ klass = "backstage/#{resource}".constantize
25
+ view_path = options[:view_path] || resource.pluralize
26
+ get "/#{resource.pluralize}" do
27
+ @collection = klass.all
28
+ if html_requested?
29
+ haml :"#{view_path}/index"
30
+ else
31
+ content_type :json
32
+ collection_to_json( @collection )
33
+ end
34
+ end
35
+
36
+ get "/#{resource}/:name" do
37
+ @object = klass.find( Util.decode_name( params[:name] ) )
38
+ if html_requested?
39
+ haml :"#{view_path}/show"
40
+ else
41
+ content_type :json
42
+ object_to_json( @object )
43
+ end
44
+ end
45
+
46
+ (options[:actions] || []).each do |action|
47
+ post "/#{resource}/:name/#{action}" do
48
+ object = klass.find( Util.decode_name( params[:name] ) )
49
+ object.__send__( action )
50
+ if html_requested?
51
+ flash[:notice] = "'#{action}' called on #{simple_class_name( object ).humanize} #{object.name}"
52
+ redirect_to object_path( object )
53
+ else
54
+ content_type :json
55
+ object_to_json( object )
56
+ end
57
+ end
58
+
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,19 @@
1
+ #
2
+ # Copyright 2011 Red Hat, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'runtimes/models/runtime'
18
+ require 'runtimes/routes'
19
+
@@ -0,0 +1,35 @@
1
+ #
2
+ # Copyright 2011 Red Hat, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ module Backstage
18
+ class Job
19
+ include HasMBean
20
+ include TorqueBoxManaged
21
+ include Resource
22
+
23
+ def self.filter
24
+ "torquebox.jobs:*"
25
+ end
26
+
27
+ def self.to_hash_attributes
28
+ super + [:name, :app, :app_name, :ruby_class_name, :status, :cron_expression]
29
+ end
30
+
31
+ def available_actions
32
+ status == 'Started' ? %w{stop} : %w{start}
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,18 @@
1
+ #
2
+ # Copyright 2011 Red Hat, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ Backstage::Application.resource :job, :actions => [:start, :stop]
18
+
@@ -0,0 +1,18 @@
1
+ #
2
+ # Copyright 2011 Red Hat, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'services/models/service'
18
+ require 'services/routes'
@@ -0,0 +1,35 @@
1
+ #
2
+ # Copyright 2011 Red Hat, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ module Backstage
18
+ class Service
19
+ include HasMBean
20
+ include TorqueBoxManaged
21
+ include Resource
22
+
23
+ def self.filter
24
+ "torquebox.services:*"
25
+ end
26
+
27
+ def self.to_hash_attributes
28
+ super + [:name, :app, :app_name, :status]
29
+ end
30
+
31
+ def available_actions
32
+ status == 'Started' ? %w{ stop } : %w{ start' }
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,17 @@
1
+ #
2
+ # Copyright 2011 Red Hat, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ Backstage::Application.resource :service, :actions => [:start, :stop]
@@ -0,0 +1,36 @@
1
+ #
2
+ # Copyright 2011 Red Hat, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ module Backstage
18
+ module TorqueBoxManaged
19
+ def name
20
+ return mbean.name if mbean.respond_to?( :name )
21
+ $1 if full_name =~ /name=(.*?)(,|$)/
22
+ end
23
+
24
+ def app_name
25
+ $1 if full_name =~ /app=(.*?)(,|$)/
26
+ end
27
+
28
+ def app
29
+ App.find( "torquebox.apps:app=#{app_name}" )
30
+ end
31
+
32
+ def status
33
+ mbean.status.downcase.capitalize
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,33 @@
1
+ #
2
+ # Copyright 2011 Red Hat, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'base64'
18
+
19
+ module Backstage
20
+ module Util
21
+ class << self
22
+ def encode_name(name)
23
+ #ugh, I'd rather encode a different way, but other attempts
24
+ #seem to break sinatra?
25
+ Base64.encode64( name ).gsub("\n", '')
26
+ end
27
+
28
+ def decode_name(name)
29
+ Base64.decode64( name )
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,136 @@
1
+ #
2
+ # Copyright 2011 Red Hat, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'spec_helper'
18
+
19
+ module Backstage
20
+
21
+ describe '/api' do
22
+ before(:each) do
23
+ get '/api'
24
+ @response = JSON.parse(last_response.body, :symbolize_names => true)
25
+ end
26
+
27
+ it "should work" do
28
+ last_response.should be_ok
29
+ end
30
+
31
+
32
+ it "should be a hash" do
33
+ @response.is_a?(Hash).should be_true
34
+ end
35
+
36
+ it "should contain a hash of collection urls" do
37
+ collections = [:apps, :queues, :topics, :message_processors, :jobs, :services, :pools]
38
+ @response[:collections].keys.should =~ collections
39
+ collections.each do |collection|
40
+ @response[:collections][collection].should =~ %r{^http://example.org/#{collection}\?format=json$}
41
+ end
42
+ end
43
+
44
+ end
45
+
46
+ describe 'with authentication enabled' do
47
+ before(:each) do
48
+ ENV['REQUIRE_AUTHENTICATION'] = 'true'
49
+ @authenticator = mock(:authenticator)
50
+ TorqueBox::Authentication.stub(:default).and_return(@authenticator)
51
+ end
52
+
53
+ it "api should work with authentication" do
54
+ @authenticator.should_receive(:authenticate).with('blah', 'pw').and_return(true)
55
+ authorize 'blah', 'pw'
56
+ get '/api'
57
+ last_response.should be_ok
58
+ end
59
+
60
+ it "should 401 w/o credentials" do
61
+ get '/api'
62
+ last_response.status.should == 401
63
+ end
64
+
65
+ it "should 401 with invalid credentials" do
66
+ @authenticator.should_receive(:authenticate).with('foo', 'bar').and_return(false)
67
+ authorize 'foo', 'bar'
68
+ get '/api'
69
+ last_response.status.should == 401
70
+ end
71
+
72
+ after(:each) do
73
+ ENV['REQUIRE_AUTHENTICATION'] = nil
74
+ end
75
+ end
76
+
77
+ %w{ app queue topic job message_processor service pool }.each do |resource|
78
+ klass = "backstage/#{resource}".constantize
79
+ describe resource do
80
+ it "should have hash attributes beyond :resource" do
81
+ klass.to_hash_attributes.size.should > 1
82
+ end
83
+
84
+ describe "/#{resource.pluralize}" do
85
+ before(:each) do
86
+ klass.stub(:all).and_return([resource_with_mock_mbean(klass)])
87
+ get "/#{resource.pluralize}", :format => 'json'
88
+ @response = JSON.parse(last_response.body, :symbolize_names => true)
89
+ end
90
+
91
+ it "should work" do
92
+ last_response.should be_ok
93
+ end
94
+
95
+ it "should be an array" do
96
+ @response.is_a?(Array).should be_true
97
+ end
98
+
99
+ context "each item" do
100
+ it "should include the resource" do
101
+ @response.first[:resource].should =~ %r{/#{resource}/.*format=json$}
102
+ end
103
+
104
+ klass.to_hash_attributes.each do |attribute|
105
+ it "should include #{attribute}" do
106
+ @response.first[attribute].should_not be_nil
107
+ end
108
+ end
109
+ end
110
+ end
111
+
112
+ describe "/#{resource}" do
113
+ before(:each) do
114
+ klass.stub(:find).and_return(resource_with_mock_mbean(klass))
115
+ get "/#{resource}/somename", :format => 'json'
116
+ @response = JSON.parse(last_response.body, :symbolize_names => true)
117
+ end
118
+
119
+ it "should work" do
120
+ last_response.should be_ok
121
+ end
122
+
123
+ it "should include the resource" do
124
+ @response[:resource].should =~ %r{/#{resource}/.*format=json$}
125
+ end
126
+
127
+ klass.to_hash_attributes.each do |attribute|
128
+ it "should include #{attribute}" do
129
+ @response[attribute.to_sym].should_not be_nil
130
+ end
131
+ end
132
+ end
133
+ end
134
+
135
+ end
136
+ end