kelredd-resourceful 0.2.0 → 0.3.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.
- 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
|