restrack-balancer 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specifying gem's dependencies in restrack.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Chris St. John
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,19 @@
1
+ = restrack-balancer
2
+
3
+ Description goes here.
4
+
5
+ == Contributing to restrack-balancer
6
+
7
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
8
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
9
+ * Fork the project
10
+ * Start a feature/bugfix branch
11
+ * Commit and push until you are happy with your contribution
12
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
13
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2011 Chris St. John. See LICENSE.txt for
18
+ further details.
19
+
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+
4
+ require 'bundler'
5
+ Bundler::GemHelper.install_tasks
6
+
7
+ task :default => [:test]
8
+
9
+ desc 'Run tests.'
10
+ Rake::TestTask.new('test') { |t|
11
+ t.pattern = 'test/test_*.rb'
12
+ }
@@ -0,0 +1,3 @@
1
+ module RESTRackBalancer
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,61 @@
1
+ require 'rubygems'
2
+ require 'restrack-client'
3
+
4
+ module RESTRack
5
+ class Balancer
6
+
7
+ attr_reader :last_client, :clients
8
+
9
+ def initialize(uri_list, format=:JSON)
10
+ raise 'You must supply an array as the list of URI to RESTRack::Balancer#initialize.' unless uri_list.is_a? Array
11
+ @clients = uri_list.collect do |uri|
12
+ RESTRack::Client.new(uri, format)
13
+ end
14
+ @path = ''
15
+ @uri = uri_list
16
+ @last_client = nil
17
+ @next_client_i = rand(@clients.length)
18
+ end
19
+
20
+ def method_missing(resource_name, *args)
21
+ @clients[@next_client_i].__send__(resource_name.to_sym, *args)
22
+ self
23
+ end
24
+
25
+ def get
26
+ response = @clients[@next_client_i].get
27
+ get_next_client
28
+ response
29
+ end
30
+
31
+ def delete
32
+ response = @clients[@next_client_i].delete
33
+ get_next_client
34
+ response
35
+ end
36
+
37
+ def post(data=nil)
38
+ response = @clients[@next_client_i].post(data)
39
+ get_next_client
40
+ response
41
+ end
42
+
43
+ def put(data=nil)
44
+ response = @clients[@next_client_i].put(data)
45
+ get_next_client
46
+ response
47
+ end
48
+
49
+ private
50
+ def get_next_client
51
+ @last_client = @uri[@next_client_i]
52
+ if @next_client_i < @clients.length - 1
53
+ @next_client_i += 1
54
+ else
55
+ @next_client_i = 0
56
+ end
57
+ @next_client = @uri[@next_client_i]
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "restrack-balancer/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "restrack-balancer"
7
+ s.version = RESTRackBalancer::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ['Chris St. John']
10
+ s.email = ['chris@stjohnstudios.com']
11
+ s.homepage = 'http://github.com/stjohncj/RESTRack-Splitter'
12
+ s.summary = %q{A library for interacting with RESTful web services. Use this to communicate with RESTRack based services.}
13
+ s.description = %q{A library for interacting with RESTful web services. Use this to communicate with RESTRack based services.}
14
+ s.rubyforge_project = "restrack-splitter"
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ s.require_paths = ["lib"]
19
+
20
+ s.add_development_dependency 'shoulda'
21
+ s.add_runtime_dependency 'restrack-client'
22
+
23
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+ require 'shoulda'
12
+
13
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
15
+ require 'restrack-balancer'
16
+
17
+ class Test::Unit::TestCase
18
+ end
@@ -0,0 +1,24 @@
1
+ #GENERATOR-CONST# -DO NOT REMOVE OR CHANGE THIS LINE- Application-Namespace => test_app
2
+ #
3
+ # = constants.yaml
4
+ # This is where RESTRack applications define the constants relevant to their particular
5
+ # application that are used by the RESTRack base classes.
6
+
7
+ # Application log path definition
8
+ :LOG: '/var/log/test_app/test_app.log'
9
+ # Request log path definition
10
+ :REQUEST_LOG: '/var/log/test_app/test_app.request.log'
11
+
12
+ # Logger object levels
13
+ :LOG_LEVEL: :DEBUG
14
+ :REQUEST_LOG_LEVEL: :DEBUG
15
+
16
+ # Supported formats are :JSON, :XML, :YAML, :BIN, :TEXT
17
+ :DEFAULT_FORMAT: :JSON
18
+ # The resource which will handle root level requests where the name is not specified. Best for users of this not to implement method_missing in their default controller, unless they are checking for bad URI.
19
+ :DEFAULT_RESOURCE: nil
20
+
21
+ # These are the resources which can be accessed from the root of your web service. If left empty, all resources are available at the root.
22
+ :ROOT_RESOURCE_ACCEPT: []
23
+ # These are the resources which cannot be accessed from the root of your web service. Use either this or ROOT_RESOURCE_ACCEPT as a blacklist or whitelist to establish routing (relationships defined in resource controllers define further routing).
24
+ :ROOT_RESOURCE_DENY: []
@@ -0,0 +1,3 @@
1
+ # Rails.root/config.ru
2
+ require 'loader'
3
+ run TestApp::WebService.new
@@ -0,0 +1,39 @@
1
+ class TestApp::ParentController < RESTRack::ResourceController
2
+
3
+ has_relationship_to :responses do |id|
4
+ id
5
+ end
6
+
7
+ def index
8
+
9
+ end
10
+
11
+ def create
12
+
13
+ end
14
+
15
+ def replace
16
+
17
+ end
18
+
19
+ def destroy
20
+
21
+ end
22
+
23
+ def show(id)
24
+
25
+ end
26
+
27
+ def update(id)
28
+
29
+ end
30
+
31
+ def delete(id)
32
+
33
+ end
34
+
35
+ def add(id)
36
+
37
+ end
38
+
39
+ end
@@ -0,0 +1,66 @@
1
+ class TestApp::ResponsesController < RESTRack::ResourceController
2
+
3
+ def method_missing(method_name, *args)
4
+ {
5
+ :method_called => method_name.to_s,
6
+ :args => args.join(':')
7
+ }
8
+ end
9
+
10
+ def index
11
+ {
12
+ :action => :index
13
+ }
14
+ end
15
+
16
+ def create
17
+ {
18
+ :action => :create,
19
+ :data => @input
20
+ }
21
+ end
22
+
23
+ def replace
24
+ {
25
+ :action => :replace,
26
+ :data => @input
27
+ }
28
+ end
29
+
30
+ def drop
31
+ {
32
+ :action => :destroy
33
+ }
34
+ end
35
+
36
+ def show(id)
37
+ {
38
+ :action => :show,
39
+ :id => id
40
+ }
41
+ end
42
+
43
+ def update(id)
44
+ {
45
+ :action => :update,
46
+ :id => id,
47
+ :data => @input
48
+ }
49
+ end
50
+
51
+ def destroy(id)
52
+ {
53
+ :action => :delete,
54
+ :id => id
55
+ }
56
+ end
57
+
58
+ def add(id)
59
+ {
60
+ :action => :add,
61
+ :id => id,
62
+ :data => @input
63
+ }
64
+ end
65
+
66
+ end
@@ -0,0 +1,21 @@
1
+ require 'restrack'
2
+
3
+ module TestApp; end
4
+ class TestApp::WebService < RESTRack::WebService; end
5
+
6
+ RESTRack::CONFIG = RESTRack::load_config(File.join(File.dirname(__FILE__), 'config/constants.yaml'))
7
+ RESTRack::CONFIG[:ROOT] = File.dirname(__FILE__)
8
+
9
+ # Dynamically load all controllers
10
+ Find.find( File.join(File.dirname(__FILE__), 'controllers') ) do |file|
11
+ next if File.extname(file) != '.rb'
12
+ require file
13
+ end
14
+
15
+ if File.directory?( File.join(File.dirname(__FILE__), 'models') )
16
+ # Dynamically load all models
17
+ Find.find( File.join(File.dirname(__FILE__), 'models') ) do |file|
18
+ next if File.extname(file) != '.rb'
19
+ require file
20
+ end
21
+ end
@@ -0,0 +1,170 @@
1
+ require File.join( File.dirname(__FILE__ ), 'helper' )
2
+
3
+ class TestRESTRackBalancer < Test::Unit::TestCase
4
+
5
+ context 'instantiation' do
6
+ should 'accept a String URI' do
7
+ assert_nothing_raised { client_1 = RESTRack::Balancer.new(['http://localhost:9292', 'http://localhost:9293']) }
8
+ end
9
+ should 'accept a URI object' do
10
+ uri_1 = URI.parse('http://localhost:9292')
11
+ uri_2 = URI.parse('http://localhost:9293')
12
+ uri = [uri_1, uri_2]
13
+ assert_nothing_raised { client_2 = RESTRack::Balancer.new(uri) }
14
+ end
15
+ end
16
+
17
+ should 'get a resource' do
18
+ client = RESTRack::Balancer.new(['http://localhost:9292', 'http://localhost:9293'])
19
+ get_response = nil
20
+ assert_nothing_raised do
21
+ get_response = client.responses(1).get
22
+ end
23
+ expected_response = { 'action' => 'show', 'id' => '1' }
24
+ assert_equal expected_response, get_response
25
+ end
26
+ should 'get a collection' do
27
+ client = RESTRack::Balancer.new(['http://localhost:9292', 'http://localhost:9293'])
28
+ get_response = nil
29
+ assert_nothing_raised do
30
+ get_response = client.responses.get
31
+ end
32
+ expected_response = { 'action' => 'index' }
33
+ assert_equal expected_response, get_response
34
+ end
35
+
36
+ should 'delete a resource' do
37
+ client = RESTRack::Balancer.new(['http://localhost:9292', 'http://localhost:9293'])
38
+ delete_response = nil
39
+ assert_nothing_raised do
40
+ delete_response = client.responses(1).delete
41
+ end
42
+ expected_response = { 'action' => 'delete', 'id' => '1' }
43
+ assert_equal expected_response, delete_response
44
+ end
45
+ should 'delete a collection' do
46
+ client = RESTRack::Balancer.new(['http://localhost:9292', 'http://localhost:9293'])
47
+ delete_response = nil
48
+ assert_nothing_raised do
49
+ delete_response = client.responses.delete
50
+ end
51
+ expected_response = { 'action' => 'destroy' }
52
+ assert_equal expected_response, delete_response
53
+ end
54
+
55
+ should 'post a resource' do
56
+ client = RESTRack::Balancer.new(['http://localhost:9292', 'http://localhost:9293'])
57
+ post_response = nil
58
+ data = {
59
+ 'test' => 'data'
60
+ }
61
+ assert_nothing_raised do
62
+ post_response = client.responses(1).post(data)
63
+ end
64
+ expected_response = { 'action' => 'add', 'id' => '1', 'data' => data }
65
+ assert_equal expected_response, post_response
66
+ end
67
+ should 'post a collection' do
68
+ client = RESTRack::Balancer.new(['http://localhost:9292', 'http://localhost:9293'])
69
+ post_response = nil
70
+ data = {
71
+ 'test' => 'data'
72
+ }
73
+ assert_nothing_raised do
74
+ post_response = client.responses.post(data)
75
+ end
76
+ expected_response = { 'action' => 'create', 'data' => data }
77
+ assert_equal expected_response, post_response
78
+ end
79
+
80
+ should 'put a resource' do
81
+ client = RESTRack::Balancer.new(['http://localhost:9292', 'http://localhost:9293'])
82
+ put_response = nil
83
+ data = {
84
+ 'test' => 'data'
85
+ }
86
+ assert_nothing_raised do
87
+ put_response = client.responses(1).put(data)
88
+ end
89
+ expected_response = { 'action' => 'update', 'id' => '1', 'data' => data }
90
+ assert_equal expected_response, put_response
91
+ end
92
+ should 'put a collection' do
93
+ client = RESTRack::Balancer.new(['http://localhost:9292', 'http://localhost:9293'])
94
+ put_response = nil
95
+ data = {
96
+ 'test' => 'data'
97
+ }
98
+ assert_nothing_raised do
99
+ put_response = client.responses.put(data)
100
+ end
101
+ expected_response = { 'action' => 'replace', 'data' => data }
102
+ assert_equal expected_response, put_response
103
+ end
104
+
105
+ should 'send and parse response json data' do
106
+ client = RESTRack::Balancer.new(['http://localhost:9292', 'http://localhost:9293'], :JSON)
107
+ post_response = nil
108
+ data = {
109
+ 'test' => 'data'
110
+ }
111
+ assert_nothing_raised do
112
+ post_response = client.responses(1).post(data)
113
+ end
114
+ expected_response = { 'action' => 'add', 'id' => '1', 'data' => data }
115
+ assert_equal expected_response, post_response
116
+ end
117
+ should 'send and parse response xml data' do
118
+ client = RESTRack::Balancer.new(['http://localhost:9292', 'http://localhost:9293'], :XML)
119
+ post_response = nil
120
+ data = {
121
+ 'test' => 'data'
122
+ }
123
+ assert_nothing_raised do
124
+ post_response = client.responses(1).post(data)
125
+ end
126
+ expected_response = { 'action' => 'add', 'id' => '1', 'data' => data }
127
+ assert_equal expected_response, post_response
128
+ end
129
+ #should 'send and parse response yaml data' do
130
+ # client = RESTRack::Balancer.new(['http://localhost:9292', 'http://localhost:9293'], :YAML)
131
+ # post_response = nil
132
+ # data = {
133
+ # 'test' => 'data'
134
+ # }
135
+ # assert_nothing_raised do
136
+ # post_response = client.responses(1).post(data)
137
+ # end
138
+ # expected_response = { 'action' => 'add', 'id' => '1', 'data' => data }
139
+ # assert_equal expected_response, post_response
140
+ #end
141
+ should 'allow building of request path prior to request' do
142
+ client = RESTRack::Balancer.new(['http://localhost:9292', 'http://localhost:9293'])
143
+ object = client.responses(1)
144
+ assert object.class.to_s, 'RESTRack::Balancer'
145
+ assert object.const_get(:path), '/responses/1'
146
+ end
147
+ should 'pivot' do
148
+ client = RESTRack::Balancer.new(['http://localhost:9292', 'http://localhost:9293'])
149
+ object = client.responses(1)
150
+ get_response = nil
151
+ assert_nothing_raised do
152
+ get_response = object.get
153
+ end
154
+ expected_response = { 'action' => 'show', 'id' => '1' }
155
+ assert_equal expected_response, get_response
156
+ end
157
+ should 'walk a relation path to a child resource' do
158
+ client = RESTRack::Balancer.new(['http://localhost:9292', 'http://localhost:9293'])
159
+ post_response = nil
160
+ data = {
161
+ 'test' => 'data'
162
+ }
163
+ assert_nothing_raised do
164
+ post_response = client.parent(1).responses.post(data)
165
+ end
166
+ expected_response = { 'action' => 'add', 'id' => '1', 'data' => data }
167
+ assert_equal expected_response, post_response
168
+ end
169
+
170
+ end
@@ -0,0 +1,62 @@
1
+ require File.join( File.dirname(__FILE__ ), 'helper' )
2
+
3
+ class TestRESTRackBalancer < Test::Unit::TestCase
4
+
5
+ should 'iterate over servers' do
6
+ used_servers = []
7
+
8
+ balancer = RESTRack::Balancer.new(['http://localhost:9292', 'http://localhost:9293', 'http://localhost:9294'])
9
+ get_response = nil
10
+ assert_nothing_raised do
11
+ get_response = balancer.responses(1).get
12
+ end
13
+ expected_response = { 'action' => 'show', 'id' => '1' }
14
+ assert_equal expected_response, get_response
15
+ used_servers << balancer.last_client
16
+ first = balancer.last_client
17
+
18
+ get_response = nil
19
+ assert_nothing_raised do
20
+ get_response = balancer.responses(1).get
21
+ end
22
+ expected_response = { 'action' => 'show', 'id' => '1' }
23
+ assert_equal expected_response, get_response
24
+ assert !used_servers.include?(balancer.last_client)
25
+ used_servers << balancer.last_client
26
+ second = balancer.last_client
27
+
28
+ get_response = nil
29
+ assert_nothing_raised do
30
+ get_response = balancer.responses(1).get
31
+ end
32
+ expected_response = { 'action' => 'show', 'id' => '1' }
33
+ assert_equal expected_response, get_response
34
+ assert !used_servers.include?(balancer.last_client)
35
+ third = balancer.last_client
36
+
37
+ get_response = nil
38
+ assert_nothing_raised do
39
+ get_response = balancer.responses(1).get
40
+ end
41
+ expected_response = { 'action' => 'show', 'id' => '1' }
42
+ assert_equal expected_response, get_response
43
+ assert_equal first, balancer.last_client
44
+
45
+ get_response = nil
46
+ assert_nothing_raised do
47
+ get_response = balancer.responses(1).get
48
+ end
49
+ expected_response = { 'action' => 'show', 'id' => '1' }
50
+ assert_equal expected_response, get_response
51
+ assert_equal second, balancer.last_client
52
+
53
+ get_response = nil
54
+ assert_nothing_raised do
55
+ get_response = balancer.responses(1).get
56
+ end
57
+ expected_response = { 'action' => 'show', 'id' => '1' }
58
+ assert_equal expected_response, get_response
59
+ assert_equal third, balancer.last_client
60
+ end
61
+
62
+ end
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: restrack-balancer
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 1.0.0
6
+ platform: ruby
7
+ authors:
8
+ - Chris St. John
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-05-18 00:00:00 -04:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: shoulda
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "0"
25
+ type: :development
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: restrack-client
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: "0"
36
+ type: :runtime
37
+ version_requirements: *id002
38
+ description: A library for interacting with RESTful web services. Use this to communicate with RESTRack based services.
39
+ email:
40
+ - chris@stjohnstudios.com
41
+ executables: []
42
+
43
+ extensions: []
44
+
45
+ extra_rdoc_files: []
46
+
47
+ files:
48
+ - .document
49
+ - Gemfile
50
+ - LICENSE.txt
51
+ - README.rdoc
52
+ - Rakefile
53
+ - lib/restrack-balancer.rb
54
+ - lib/restrack-balancer/version.rb
55
+ - restrack-balancer.gemspec
56
+ - test/helper.rb
57
+ - test/test_app/config.ru
58
+ - test/test_app/config/constants.yaml
59
+ - test/test_app/controllers/parent_controller.rb
60
+ - test/test_app/controllers/responses_controller.rb
61
+ - test/test_app/loader.rb
62
+ - test/test_restrack-balancer.rb
63
+ - test/test_restrack-balancer_requests.rb
64
+ has_rdoc: true
65
+ homepage: http://github.com/stjohncj/RESTRack-Splitter
66
+ licenses: []
67
+
68
+ post_install_message:
69
+ rdoc_options: []
70
+
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: "0"
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ none: false
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: "0"
85
+ requirements: []
86
+
87
+ rubyforge_project: restrack-splitter
88
+ rubygems_version: 1.5.2
89
+ signing_key:
90
+ specification_version: 3
91
+ summary: A library for interacting with RESTful web services. Use this to communicate with RESTRack based services.
92
+ test_files:
93
+ - test/helper.rb
94
+ - test/test_app/config.ru
95
+ - test/test_app/config/constants.yaml
96
+ - test/test_app/controllers/parent_controller.rb
97
+ - test/test_app/controllers/responses_controller.rb
98
+ - test/test_app/loader.rb
99
+ - test/test_restrack-balancer.rb
100
+ - test/test_restrack-balancer_requests.rb