kelredd-resourceful 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -1
- data/features/{resource_models.feature → models.feature} +4 -8
- data/features/{get_resource.feature → rest_client.feature} +27 -0
- data/features/step_definitions/{resource_models_steps.rb → model_steps.rb} +0 -0
- data/features/step_definitions/rest_client_steps.rb +84 -0
- data/features/step_definitions/support/env.rb +4 -1
- data/features/step_definitions/support/models.rb +8 -0
- data/lib/resourceful/agent/base.rb +34 -0
- data/lib/resourceful/agent/rest_client.rb +61 -0
- data/lib/resourceful/agent.rb +3 -0
- data/lib/resourceful/model/base.rb +7 -8
- data/lib/resourceful/model/json.rb +7 -8
- data/lib/resourceful/model/xml.rb +6 -5
- data/lib/resourceful/resource/cache.rb +16 -30
- data/lib/resourceful/resource.rb +0 -22
- data/lib/resourceful/version.rb +1 -1
- data/lib/resourceful.rb +2 -2
- metadata +9 -9
- data/features/config_resource.feature +0 -29
- data/features/step_definitions/resource_config_steps.rb +0 -23
- data/features/step_definitions/resource_get_steps.rb +0 -37
- data/features/step_definitions/support/resources.rb +0 -20
- data/lib/resourceful/resource/base.rb +0 -84
data/Rakefile
CHANGED
@@ -37,7 +37,7 @@ Rake::TestTask.new do |t|
|
|
37
37
|
end
|
38
38
|
|
39
39
|
desc 'Generate the gemspec to serve this Gem from Github'
|
40
|
-
task :
|
40
|
+
task :gemspec do
|
41
41
|
file = File.dirname(__FILE__) + "/#{spec.name}.gemspec"
|
42
42
|
File.open(file, 'w') {|f| f << spec.to_ruby }
|
43
43
|
puts "Created gemspec: #{file}"
|
@@ -1,26 +1,22 @@
|
|
1
|
-
Feature:
|
1
|
+
Feature: Models
|
2
2
|
In order to consume rest based resources
|
3
3
|
As an object
|
4
|
-
I want to define and initialize a model class from
|
4
|
+
I want to define and initialize a model class from resource data
|
5
5
|
|
6
6
|
Scenario: Get JSON user
|
7
|
-
Given I
|
8
|
-
And I am user with the screen_name "kelredd"
|
7
|
+
Given I am user with the screen_name "kelredd"
|
9
8
|
When I load my "Json" user model
|
10
9
|
Then the result should be a valid User model
|
11
10
|
|
12
11
|
Scenario: Get XML user
|
13
|
-
Given I
|
14
|
-
And I am user with the screen_name "kelredd"
|
12
|
+
Given I am user with the screen_name "kelredd"
|
15
13
|
When I load my "Xml" user model
|
16
14
|
Then the result should be a valid User model
|
17
15
|
|
18
16
|
Scenario: Get JSON status collection
|
19
|
-
Given I have a configured resource host
|
20
17
|
When I load the "Json" status "public_timeline"
|
21
18
|
Then the result should be a collection of valid Status models
|
22
19
|
|
23
20
|
Scenario: Get XML status collection
|
24
|
-
Given I have a configured resource host
|
25
21
|
When I load the "Xml" status "public_timeline"
|
26
22
|
Then the result should be a collection of valid Status models
|
@@ -3,6 +3,33 @@ Feature: Get Resource
|
|
3
3
|
As an object
|
4
4
|
I want to get data from a web resource as a formatted object
|
5
5
|
|
6
|
+
Scenario: JSON Format definition
|
7
|
+
Given I want to use the json resource format
|
8
|
+
Then the format should be .json
|
9
|
+
|
10
|
+
Scenario: XML Format definition
|
11
|
+
Given I want to use the xml resource format
|
12
|
+
Then the format should be .xml
|
13
|
+
|
14
|
+
Scenario: Host not configured
|
15
|
+
Given I have no host server configured
|
16
|
+
Then resourceful should complain about a configuration error
|
17
|
+
|
18
|
+
Scenario: Host configured
|
19
|
+
Given I have a configured resource host
|
20
|
+
Then the host should be set
|
21
|
+
|
22
|
+
Scenario: Resource logger
|
23
|
+
Given I have a configured resource host set to log
|
24
|
+
Then verify the log settings
|
25
|
+
|
26
|
+
Scenario: Resource logging
|
27
|
+
Given I have a configured resource host set to log
|
28
|
+
When I get a json formatted resource
|
29
|
+
Then the set log file should exist
|
30
|
+
|
31
|
+
|
32
|
+
|
6
33
|
Scenario: Get JSON resource
|
7
34
|
Given I have a configured resource host
|
8
35
|
When I get a json formatted resource
|
File without changes
|
@@ -0,0 +1,84 @@
|
|
1
|
+
Given /^I want to use the (.+) resource format$/ do |format|
|
2
|
+
@format = Resourceful::Resource::Format.get(format)
|
3
|
+
end
|
4
|
+
|
5
|
+
Given /^I have no host server configured$/ do
|
6
|
+
@agent = Resourceful::Agent::RestClient.new
|
7
|
+
end
|
8
|
+
|
9
|
+
Given /^I have a configured resource host$/ do
|
10
|
+
@agent = Resourceful::Agent::RestClient.new(:host => RESOURCE_CONFIG[:host])
|
11
|
+
end
|
12
|
+
|
13
|
+
Given /^I have a configured resource host set to log$/ do
|
14
|
+
log_file = File.expand_path(RESOURCE_CONFIG[:log])
|
15
|
+
FileUtils.rm(log_file) if File.exists?(log_file)
|
16
|
+
@agent = Resourceful::Agent::RestClient.new(:host => RESOURCE_CONFIG[:host]) {
|
17
|
+
RESOURCE_CONFIG[:log]
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
Then /^the format should be \.(.+)$/ do |format|
|
22
|
+
assert_equal @format.to_s, format
|
23
|
+
end
|
24
|
+
|
25
|
+
Then /^the host should be set$/ do
|
26
|
+
assert_equal @agent.host, RESOURCE_CONFIG[:host]
|
27
|
+
end
|
28
|
+
|
29
|
+
Then /^resourceful should complain about a configuration error$/ do
|
30
|
+
assert_raise Resourceful::Exceptions::ConfigurationError do
|
31
|
+
@agent.get RESOURCE_CONFIG[:resource], :format => 'json', :params => RESOURCE_CONFIG[:params]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
Then /^verify the log settings$/ do
|
36
|
+
assert_equal @agent.logger.outputters.detect{|out| out.respond_to?('filename')}.filename, RESOURCE_CONFIG[:log]
|
37
|
+
end
|
38
|
+
|
39
|
+
Then /^the set log file should exist$/ do
|
40
|
+
log_file = File.expand_path(RESOURCE_CONFIG[:log])
|
41
|
+
assert File.exists?(log_file)
|
42
|
+
FileUtils.rm(log_file) if File.exists?(log_file)
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
|
48
|
+
When /^I get a[n]* (.+) formatted resource$/ do |format|
|
49
|
+
@result = ResourcefulFeature::Helpers.safe_run_get do
|
50
|
+
@agent.get RESOURCE_CONFIG[:resource], :format => format, :params => RESOURCE_CONFIG[:params]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
When /^I get a[n]* (.+) formatted implicitly resource$/ do |format|
|
55
|
+
@result = ResourcefulFeature::Helpers.safe_run_get do
|
56
|
+
@agent.get RESOURCE_CONFIG[:resource]+".#{format}", :params => RESOURCE_CONFIG[:params]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
When /^I get a resource that does not exist$/ do
|
61
|
+
@result = ResourcefulFeature::Helpers.safe_run_get do
|
62
|
+
@agent.get '/unknown', :format => 'xml', :params => RESOURCE_CONFIG[:params]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
Then /^the result should be a hash object$/ do
|
67
|
+
assert_kind_of Hash, @result.first
|
68
|
+
end
|
69
|
+
|
70
|
+
Then /^the result should be an xml object$/ do
|
71
|
+
assert_kind_of Nokogiri::XML::Document, @result
|
72
|
+
end
|
73
|
+
|
74
|
+
Then /^resourceful should complain about a format error$/ do
|
75
|
+
assert @result
|
76
|
+
assert_kind_of Resourceful::Exceptions::FormatError, @result
|
77
|
+
assert @result.message.length > 0
|
78
|
+
end
|
79
|
+
|
80
|
+
Then /^resourceful should complain about the resource not being found$/ do
|
81
|
+
assert @result
|
82
|
+
assert_kind_of RestClient::ResourceNotFound, @result
|
83
|
+
assert @result.message.length > 0
|
84
|
+
end
|
@@ -2,10 +2,13 @@ require 'test/unit/assertions'
|
|
2
2
|
World(Test::Unit::Assertions)
|
3
3
|
|
4
4
|
RESOURCE_CONFIG = {
|
5
|
-
:host => 'twitter.com',
|
5
|
+
:host => 'http://twitter.com',
|
6
6
|
:resource => '/statuses/public_timeline',
|
7
7
|
:params => {},
|
8
8
|
:log => "./test.log"
|
9
9
|
}
|
10
10
|
|
11
11
|
require File.dirname(__FILE__) + '/../../../lib/resourceful'
|
12
|
+
|
13
|
+
REST_CLIENT_TWITTER = Resourceful::Agent::RestClient.new(:host => RESOURCE_CONFIG[:host])
|
14
|
+
|
@@ -1,5 +1,7 @@
|
|
1
1
|
class UserXml < Resourceful::Model::Xml
|
2
2
|
|
3
|
+
agent REST_CLIENT_TWITTER
|
4
|
+
|
3
5
|
def self.find(screen_name, force=false)
|
4
6
|
get("/users/#{screen_name}", {}, "//user")
|
5
7
|
end
|
@@ -22,6 +24,8 @@ end
|
|
22
24
|
|
23
25
|
class UserJson < Resourceful::Model::Json
|
24
26
|
|
27
|
+
agent REST_CLIENT_TWITTER
|
28
|
+
|
25
29
|
def self.find(screen_name, force=false)
|
26
30
|
get("/users/#{screen_name}", {})
|
27
31
|
end
|
@@ -44,6 +48,8 @@ end
|
|
44
48
|
|
45
49
|
class StatusXml < Resourceful::Model::Xml
|
46
50
|
|
51
|
+
agent REST_CLIENT_TWITTER
|
52
|
+
|
47
53
|
def self.find(collection, force=false)
|
48
54
|
get_collection("/statuses/#{collection}", {}, "//statuses/status")
|
49
55
|
end
|
@@ -67,6 +73,8 @@ end
|
|
67
73
|
|
68
74
|
class StatusJson < Resourceful::Model::Json
|
69
75
|
|
76
|
+
agent REST_CLIENT_TWITTER
|
77
|
+
|
70
78
|
def self.find(collection, force=false)
|
71
79
|
get_collection("/statuses/#{collection}", {})
|
72
80
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'log4r'
|
2
|
+
require File.join(File.dirname(__FILE__), '..', 'resource', 'cache.rb')
|
3
|
+
|
4
|
+
module Resourceful
|
5
|
+
module Agent
|
6
|
+
class Base
|
7
|
+
|
8
|
+
attr_reader :logger, :cache
|
9
|
+
|
10
|
+
def initialize(args={})
|
11
|
+
@cache = Resourceful::Resource::Cache.new
|
12
|
+
@logger = Log4r::Logger.new('Resourceful Base')
|
13
|
+
@logger.add(Log4r::StdoutOutputter.new('console'))
|
14
|
+
end
|
15
|
+
|
16
|
+
protected
|
17
|
+
|
18
|
+
def log(msg, level = :info) # :nodoc:
|
19
|
+
if(msg)
|
20
|
+
if @logger && @logger.respond_to?(level)
|
21
|
+
@logger.send(level.to_s, msg)
|
22
|
+
else
|
23
|
+
puts "** [#{level.to_s.upcase}]: #{msg}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def log=(file)
|
29
|
+
@logger.add(Log4r::FileOutputter.new('fileOutputter', :filename => file, :trunc => false, :formatter => Log4r::PatternFormatter.new(:pattern => "[%l] %d :: %m"))) rescue nil
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'rest_client'
|
2
|
+
require File.join(File.dirname(__FILE__), '..', 'resource', 'format.rb')
|
3
|
+
require File.join(File.dirname(__FILE__), 'base.rb')
|
4
|
+
|
5
|
+
module Resourceful
|
6
|
+
module Agent
|
7
|
+
class RestClient < Resourceful::Agent::Base
|
8
|
+
|
9
|
+
ATTRS = [:host, :user, :password]
|
10
|
+
ATTRS.each { |a| attr_reader a }
|
11
|
+
|
12
|
+
def initialize(args={})
|
13
|
+
ATTRS.each { |a| instance_variable_set("@#{a.to_s}", args.delete(a)) }
|
14
|
+
super(args)
|
15
|
+
self.log = ::RestClient.log = yield if block_given?
|
16
|
+
@agent = ::RestClient::Resource.new(@host, :user => @user, :password => @password)
|
17
|
+
end
|
18
|
+
|
19
|
+
def get(path, opts={})
|
20
|
+
path, opts = check_config(path, opts)
|
21
|
+
format = Resourceful::Resource::Format.get(opts[:format])
|
22
|
+
|
23
|
+
full_resource_path = self.class.resource_path(path, format, opts[:params])
|
24
|
+
resource_summary = summary('get', full_resource_path)
|
25
|
+
cache_key = Resourceful::Resource::Cache.key(@host, 'get', full_resource_path)
|
26
|
+
|
27
|
+
if opts[:force] || (resp = cache.read(cache_key)).nil?
|
28
|
+
log "Resource call: #{resource_summary}"
|
29
|
+
resp = cache.write(cache_key, @agent[full_resource_path].get)
|
30
|
+
else
|
31
|
+
log "Resource call: [CACHE] #{resource_summary}"
|
32
|
+
end
|
33
|
+
format.build(resp)
|
34
|
+
end
|
35
|
+
|
36
|
+
protected
|
37
|
+
|
38
|
+
def check_config(path, opts)
|
39
|
+
raise Resourceful::Exceptions::ConfigurationError, "invalid RestClient agent" unless @agent && @agent.url
|
40
|
+
opts ||= {}
|
41
|
+
opts[:force] ||= false
|
42
|
+
if path =~ /^(.+)\.(.+)$/
|
43
|
+
path = $1
|
44
|
+
opts[:format] ||= $2
|
45
|
+
end
|
46
|
+
opts[:format] ||= Resourceful::Resource::Json.to_s
|
47
|
+
opts[:params] ||= {}
|
48
|
+
[path, opts]
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.resource_path(path, format, params) # :nodoc:
|
52
|
+
"#{path}.#{format}#{params.to_http_query_str unless params.empty?}"
|
53
|
+
end
|
54
|
+
|
55
|
+
def summary(verb, full_resource_path) # :nodoc:
|
56
|
+
"#{verb.upcase} #{@agent.url}#{full_resource_path}"
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -3,17 +3,16 @@ module Resourceful
|
|
3
3
|
|
4
4
|
class Base
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
Resourceful::Resource
|
6
|
+
@@agent = nil
|
7
|
+
def self.agent(a)
|
8
|
+
@@agent = a
|
10
9
|
end
|
11
10
|
|
12
|
-
def self.get(path, opts={}
|
13
|
-
|
11
|
+
def self.get(path, opts={})
|
12
|
+
@@agent.get(path, opts)
|
14
13
|
end
|
15
|
-
def self.get_collection(path, opts={}
|
16
|
-
(yield
|
14
|
+
def self.get_collection(path, opts={})
|
15
|
+
(yield @@agent.get(path, opts)).collect{|data| new(data)}
|
17
16
|
end
|
18
17
|
|
19
18
|
def initialize(data)
|
@@ -8,16 +8,18 @@ module Resourceful
|
|
8
8
|
def self.get(path, params, force=false)
|
9
9
|
opts = {
|
10
10
|
:format => 'json',
|
11
|
-
:params => params || {}
|
11
|
+
:params => params || {},
|
12
|
+
:force => force
|
12
13
|
}
|
13
|
-
new(super(path, opts
|
14
|
+
new(super(path, opts))
|
14
15
|
end
|
15
16
|
def self.get_collection(path, params, force=false)
|
16
17
|
opts = {
|
17
18
|
:format => 'json',
|
18
|
-
:params => params || {}
|
19
|
+
:params => params || {},
|
20
|
+
:force => force
|
19
21
|
}
|
20
|
-
super(path, opts
|
22
|
+
super(path, opts) do |data|
|
21
23
|
data
|
22
24
|
end
|
23
25
|
end
|
@@ -35,10 +37,7 @@ module Resourceful
|
|
35
37
|
|
36
38
|
def attribute(config)
|
37
39
|
paths = config[:path].to_s.split('/')
|
38
|
-
paths.inject(@json)
|
39
|
-
#raise Resourceful::Exceptions::AttributeError, "no matching attribute data for'#{config[:path]}'" if val.nil?
|
40
|
-
val.fetch(path, nil) rescue nil
|
41
|
-
end
|
40
|
+
paths.inject(@json) { |val,path| val.fetch(path, nil) rescue nil }
|
42
41
|
end
|
43
42
|
|
44
43
|
|
@@ -8,16 +8,18 @@ module Resourceful
|
|
8
8
|
def self.get(path, params, xpath, force=false)
|
9
9
|
opts = {
|
10
10
|
:format => 'xml',
|
11
|
-
:params => params || {}
|
11
|
+
:params => params || {},
|
12
|
+
:force => force
|
12
13
|
}
|
13
|
-
new(super(path, opts
|
14
|
+
new(super(path, opts).xpath(xpath))
|
14
15
|
end
|
15
16
|
def self.get_collection(path, params, xpath, force=false)
|
16
17
|
opts = {
|
17
18
|
:format => 'xml',
|
18
|
-
:params => params || {}
|
19
|
+
:params => params || {},
|
20
|
+
:force => force
|
19
21
|
}
|
20
|
-
super(path, opts
|
22
|
+
super(path, opts) do |data|
|
21
23
|
data.xpath(xpath)
|
22
24
|
end
|
23
25
|
end
|
@@ -35,7 +37,6 @@ module Resourceful
|
|
35
37
|
|
36
38
|
def attribute(config)
|
37
39
|
node = get_node("./#{config[:path]}")
|
38
|
-
#raise Resourceful::Exceptions::AttributeError, "no matching attribute data for'#{config[:path]}'" unless node
|
39
40
|
node.content rescue nil
|
40
41
|
end
|
41
42
|
|
@@ -2,44 +2,30 @@ module Resourceful
|
|
2
2
|
module Resource
|
3
3
|
class Cache
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
def self.clear(key=nil)
|
8
|
-
if key
|
9
|
-
@@cache[key] = nil
|
10
|
-
else
|
11
|
-
@@cache = {}
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
def self.read(key)
|
16
|
-
@@cache[key]
|
17
|
-
end
|
5
|
+
attr_reader :store
|
18
6
|
|
19
|
-
def self.
|
20
|
-
|
7
|
+
def self.key(host, verb, resource)
|
8
|
+
"#{host}_#{verb}_#{resource}"
|
21
9
|
end
|
22
10
|
|
23
|
-
def
|
24
|
-
|
11
|
+
def initialize
|
12
|
+
@store = {}
|
25
13
|
end
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
def read
|
34
|
-
self.class.read(@key)
|
14
|
+
|
15
|
+
def clear(key=nil)
|
16
|
+
if key
|
17
|
+
@store[key] = nil
|
18
|
+
else
|
19
|
+
@store = {}
|
20
|
+
end
|
35
21
|
end
|
36
22
|
|
37
|
-
def
|
38
|
-
|
23
|
+
def read(key)
|
24
|
+
@store[key]
|
39
25
|
end
|
40
26
|
|
41
|
-
def
|
42
|
-
|
27
|
+
def write(key, value)
|
28
|
+
@store[key] = value
|
43
29
|
end
|
44
30
|
|
45
31
|
end
|
data/lib/resourceful/resource.rb
CHANGED
@@ -1,25 +1,3 @@
|
|
1
1
|
Dir[File.join(File.dirname(__FILE__), "resource" ,"*.rb")].each do |file|
|
2
2
|
require file
|
3
3
|
end
|
4
|
-
|
5
|
-
module Resourceful
|
6
|
-
module Resource
|
7
|
-
|
8
|
-
def self.configure(opts={}, &block)
|
9
|
-
Resourceful::Resource::Base.configure(opts, &block)
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.get(resource, opts={}, force=false)
|
13
|
-
Resourceful::Resource::Base.get(resource, opts, force)
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.host
|
17
|
-
Resourceful::Resource::Base.host
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.logger
|
21
|
-
Resourceful::Resource::Base.logger
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
end
|
data/lib/resourceful/version.rb
CHANGED
data/lib/resourceful.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
%w(rubygems nokogiri json
|
1
|
+
%w(rubygems nokogiri json log4r).each do |lib|
|
2
2
|
require lib
|
3
3
|
end
|
4
4
|
|
5
|
-
%w(exceptions extensions resource model).each do |file|
|
5
|
+
%w(exceptions extensions resource agent model).each do |file|
|
6
6
|
require File.join(File.dirname(__FILE__), 'resourceful', "#{file}.rb")
|
7
7
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kelredd-resourceful
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kelly Redding
|
@@ -73,19 +73,20 @@ extra_rdoc_files:
|
|
73
73
|
files:
|
74
74
|
- README.rdoc
|
75
75
|
- Rakefile
|
76
|
-
- features/
|
77
|
-
- features/
|
78
|
-
- features/resource_models.feature
|
76
|
+
- features/models.feature
|
77
|
+
- features/rest_client.feature
|
79
78
|
- features/step_definitions
|
80
|
-
- features/step_definitions/
|
81
|
-
- features/step_definitions/
|
82
|
-
- features/step_definitions/resource_models_steps.rb
|
79
|
+
- features/step_definitions/model_steps.rb
|
80
|
+
- features/step_definitions/rest_client_steps.rb
|
83
81
|
- features/step_definitions/support
|
84
82
|
- features/step_definitions/support/env.rb
|
85
83
|
- features/step_definitions/support/helpers.rb
|
86
84
|
- features/step_definitions/support/models.rb
|
87
|
-
- features/step_definitions/support/resources.rb
|
88
85
|
- lib/resourceful
|
86
|
+
- lib/resourceful/agent
|
87
|
+
- lib/resourceful/agent/base.rb
|
88
|
+
- lib/resourceful/agent/rest_client.rb
|
89
|
+
- lib/resourceful/agent.rb
|
89
90
|
- lib/resourceful/exceptions.rb
|
90
91
|
- lib/resourceful/extensions.rb
|
91
92
|
- lib/resourceful/model
|
@@ -94,7 +95,6 @@ files:
|
|
94
95
|
- lib/resourceful/model/xml.rb
|
95
96
|
- lib/resourceful/model.rb
|
96
97
|
- lib/resourceful/resource
|
97
|
-
- lib/resourceful/resource/base.rb
|
98
98
|
- lib/resourceful/resource/cache.rb
|
99
99
|
- lib/resourceful/resource/format.rb
|
100
100
|
- lib/resourceful/resource.rb
|
@@ -1,29 +0,0 @@
|
|
1
|
-
Feature: Config Resource
|
2
|
-
In order to consume rest based resources
|
3
|
-
As an user
|
4
|
-
I want to configure Resourceful for a particular resource format and host
|
5
|
-
|
6
|
-
Scenario: JSON Format definition
|
7
|
-
Given I want to use the json resource format
|
8
|
-
Then the format should be .json
|
9
|
-
|
10
|
-
Scenario: XML Format definition
|
11
|
-
Given I want to use the xml resource format
|
12
|
-
Then the format should be .xml
|
13
|
-
|
14
|
-
Scenario: Host not configured
|
15
|
-
Given I have no host server configured
|
16
|
-
Then resourceful should complain about a configuration error
|
17
|
-
|
18
|
-
Scenario: Host configured
|
19
|
-
Given I have a configured resource host
|
20
|
-
Then the host should be set
|
21
|
-
|
22
|
-
Scenario: Resource logger
|
23
|
-
Given I have a configured resource host set to log
|
24
|
-
Then verify the log settings
|
25
|
-
|
26
|
-
Scenario: Resource logging
|
27
|
-
Given I have a configured resource host set to log
|
28
|
-
When I get a json formatted resource
|
29
|
-
Then the set log file should exist
|
@@ -1,23 +0,0 @@
|
|
1
|
-
Then /^the format should be \.(.+)$/ do |format|
|
2
|
-
assert_equal @format.to_s, format
|
3
|
-
end
|
4
|
-
|
5
|
-
Then /^the host should be set$/ do
|
6
|
-
assert_equal Resourceful::Resource.host, RESOURCE_CONFIG[:host]
|
7
|
-
end
|
8
|
-
|
9
|
-
Then /^resourceful should complain about a configuration error$/ do
|
10
|
-
assert_raise Resourceful::Exceptions::ConfigurationError do
|
11
|
-
Resourceful::Resource::Base.get RESOURCE_CONFIG[:resource], :format => 'json', :params => RESOURCE_CONFIG[:params]
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
Then /^verify the log settings$/ do
|
16
|
-
assert_equal Resourceful::Resource.logger.outputters.detect{|out| out.respond_to?('filename')}.filename, RESOURCE_CONFIG[:log]
|
17
|
-
end
|
18
|
-
|
19
|
-
Then /^the set log file should exist$/ do
|
20
|
-
log_file = File.expand_path(RESOURCE_CONFIG[:log])
|
21
|
-
assert File.exists?(log_file)
|
22
|
-
FileUtils.rm(log_file) if File.exists?(log_file)
|
23
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
When /^I get a[n]* (.+) formatted resource$/ do |format|
|
2
|
-
@result = ResourcefulFeature::Helpers.safe_run_get do
|
3
|
-
Resourceful::Resource::Base.get RESOURCE_CONFIG[:resource], :format => format, :params => RESOURCE_CONFIG[:params]
|
4
|
-
end
|
5
|
-
end
|
6
|
-
|
7
|
-
When /^I get a[n]* (.+) formatted implicitly resource$/ do |format|
|
8
|
-
@result = ResourcefulFeature::Helpers.safe_run_get do
|
9
|
-
Resourceful::Resource::Base.get RESOURCE_CONFIG[:resource]+".#{format}", :params => RESOURCE_CONFIG[:params]
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
When /^I get a resource that does not exist$/ do
|
14
|
-
@result = ResourcefulFeature::Helpers.safe_run_get do
|
15
|
-
Resourceful::Resource::Base.get '/unknown', :format => 'xml', :params => RESOURCE_CONFIG[:params]
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
Then /^the result should be a hash object$/ do
|
20
|
-
assert_kind_of Hash, @result.first
|
21
|
-
end
|
22
|
-
|
23
|
-
Then /^the result should be an xml object$/ do
|
24
|
-
assert_kind_of Nokogiri::XML::Document, @result
|
25
|
-
end
|
26
|
-
|
27
|
-
Then /^resourceful should complain about a format error$/ do
|
28
|
-
assert @result
|
29
|
-
assert_kind_of Resourceful::Exceptions::FormatError, @result
|
30
|
-
assert @result.message.length > 0
|
31
|
-
end
|
32
|
-
|
33
|
-
Then /^resourceful should complain about the resource not being found$/ do
|
34
|
-
assert @result
|
35
|
-
assert_kind_of RestClient::ResourceNotFound, @result
|
36
|
-
assert @result.message.length > 0
|
37
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
Given /^I want to use the (.+) resource format$/ do |format|
|
2
|
-
@format = Resourceful::Resource::Format.get(format)
|
3
|
-
end
|
4
|
-
|
5
|
-
Given /^I have no host server configured$/ do
|
6
|
-
Resourceful::Resource::Base.configure
|
7
|
-
end
|
8
|
-
|
9
|
-
Given /^I have a configured resource host$/ do
|
10
|
-
Resourceful::Resource::Base.configure(:host => RESOURCE_CONFIG[:host])
|
11
|
-
end
|
12
|
-
|
13
|
-
Given /^I have a configured resource host set to log$/ do
|
14
|
-
log_file = File.expand_path(RESOURCE_CONFIG[:log])
|
15
|
-
FileUtils.rm(log_file) if File.exists?(log_file)
|
16
|
-
Resourceful::Resource::Base.configure(:host => RESOURCE_CONFIG[:host]) {
|
17
|
-
RESOURCE_CONFIG[:log]
|
18
|
-
}
|
19
|
-
end
|
20
|
-
|
@@ -1,84 +0,0 @@
|
|
1
|
-
require 'rest_client'
|
2
|
-
require 'log4r'
|
3
|
-
require File.join(File.dirname(__FILE__), 'cache.rb')
|
4
|
-
require File.join(File.dirname(__FILE__), 'format.rb')
|
5
|
-
require File.join(File.dirname(__FILE__), '..', 'exceptions.rb')
|
6
|
-
|
7
|
-
module Resourceful
|
8
|
-
module Resource
|
9
|
-
class Base
|
10
|
-
|
11
|
-
@@host = nil
|
12
|
-
@@logger = nil
|
13
|
-
|
14
|
-
def self.configure(opts={})
|
15
|
-
Resourceful::Resource::Cache.clear
|
16
|
-
@@logger = Log4r::Logger.new('Resourceful Base')
|
17
|
-
@@logger.add(Log4r::StdoutOutputter.new('console'))
|
18
|
-
if block_given?
|
19
|
-
log_file = yield
|
20
|
-
@@logger.add(Log4r::FileOutputter.new('fileOutputter', :filename => log_file, :trunc => false, :formatter => Log4r::PatternFormatter.new(:pattern => "[%l] %d :: %m"))) rescue nil
|
21
|
-
RestClient.log = log_file
|
22
|
-
end
|
23
|
-
@@host = opts[:host]
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.host
|
27
|
-
@@host
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.logger
|
31
|
-
@@logger
|
32
|
-
end
|
33
|
-
|
34
|
-
# KDR: returns the resource specified in hash form
|
35
|
-
def self.get(path, opts={}, force=false)
|
36
|
-
path, opts = check_config(path, opts)
|
37
|
-
@@rest_client ||= ::RestClient::Resource.new("http://#{@@host}")
|
38
|
-
format = Resourceful::Resource::Format.get(opts[:format])
|
39
|
-
request_summary = summary('get', path, format, opts[:params])
|
40
|
-
cache = Resourceful::Resource::Cache.new(@@host, 'get', path, format, opts[:params])
|
41
|
-
|
42
|
-
if force || (resp = cache.read).nil?
|
43
|
-
log "Resource call: #{request_summary}"
|
44
|
-
resp = cache.write(@@rest_client[rest_path(path, format, opts[:params])].get)
|
45
|
-
else
|
46
|
-
log "Resource call: [CACHE] #{request_summary}"
|
47
|
-
end
|
48
|
-
format.build(resp)
|
49
|
-
end
|
50
|
-
|
51
|
-
private
|
52
|
-
|
53
|
-
def self.summary(verb, path, format, params) # :nodoc:
|
54
|
-
"#{verb.upcase} #{@@rest_client.url}#{rest_path(path, format, params)}"
|
55
|
-
end
|
56
|
-
|
57
|
-
def self.rest_path(path, format, params) # :nodoc:
|
58
|
-
"#{path}.#{format}#{params.to_http_query_str unless params.empty?}"
|
59
|
-
end
|
60
|
-
|
61
|
-
def self.check_config(path, opts)
|
62
|
-
raise Resourceful::Exceptions::ConfigurationError, "please configure a host for Resourceful resources" unless @@host
|
63
|
-
if path =~ /^(.+)\.(.+)$/
|
64
|
-
path = $1
|
65
|
-
opts[:format] ||= $2
|
66
|
-
end
|
67
|
-
opts[:format] ||= Resourceful::Resource::Json.to_s
|
68
|
-
opts[:params] ||= {}
|
69
|
-
[path, opts]
|
70
|
-
end
|
71
|
-
|
72
|
-
def self.log(msg, level = :info) # :nodoc:
|
73
|
-
if(msg)
|
74
|
-
if @@logger && @@logger.respond_to?(level)
|
75
|
-
@@logger.send(level.to_s, msg)
|
76
|
-
else
|
77
|
-
puts "** [#{level.to_s.upcase}]: #{msg}"
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|