-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Paul Sadauskas
committed
Jul 31, 2008
0 parents
commit a7bef5b
Showing
7 changed files
with
339 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
Copyright (c) 2008 Absolute-Performance, Inc | ||
Copyright (c) 2008 Peter Williams | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining | ||
a copy of this software and associated documentation files (the | ||
"Software"), to deal in the Software without restriction, including | ||
without limitation the rights to use, copy, modify, merge, publish, | ||
distribute, sublicense, and/or sell copies of the Software, and to | ||
permit persons to whom the Software is furnished to do so, subject to | ||
the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be | ||
included in all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# DataMapper: Abstract ReST Adapter | ||
|
||
Copyright | ||
--------- | ||
|
||
Copyright (c) 2008 Absolute Performance, Inc, Paul Sadauskas; released under the MIT License. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
require 'rubygems' | ||
require 'rake' | ||
require 'rake/gempackagetask' | ||
require 'rake/rdoctask' | ||
require 'spec/rake/spectask' | ||
|
||
desc 'Default: run unit tests.' | ||
task :default => :spec | ||
|
||
desc "Run all tests" | ||
task :test => :spec | ||
|
||
desc "Verify Resourceful against it's specs" | ||
Spec::Rake::SpecTask.new(:spec) do |t| | ||
t.libs << 'lib' | ||
t.pattern = 'spec/**/*_spec.rb' | ||
end | ||
|
||
begin | ||
gem 'yard', '>=0.2.3' | ||
require 'yard' | ||
desc 'Generate documentation for dm-abstract_rest_adapter.' | ||
YARD::Rake::YardocTask.new do |t| | ||
t.files = ['lib/**/*.rb', 'README'] | ||
end | ||
rescue Exception | ||
# install YARD to generate documentation | ||
end | ||
|
||
desc 'Removes all temporary files' | ||
task :clean | ||
|
||
############################################################################## | ||
# Packaging & Installation | ||
############################################################################## | ||
|
||
DM_ABSTRACT_REST_ADAPTER_VERSION = "0.0.1" | ||
|
||
windows = (PLATFORM =~ /win32|cygwin/) rescue nil | ||
|
||
SUDO = windows ? "" : "sudo" | ||
|
||
task :'dm-abstract_rest_adapter' => [:clean, :rdoc, :package] | ||
|
||
spec = Gem::Specification.new do |s| | ||
s.name = "dm-abstract_rest_adapter" | ||
s.version = DM_ABSTRACT_REST_ADAPTER_VERSION | ||
s.platform = Gem::Platform::RUBY | ||
s.author = "Paul Sadauskas" | ||
s.email = "psadauskas@gmail.com" | ||
s.homepage = "https://github.com/paul/dm-abstract_rest_adapter/tree/master" | ||
s.summary = "A generic DataMapper adapter for talking to ReST-based web servers." | ||
s.description = s.summary | ||
s.rubyforge_project = 'dm-abstract_rest_adapter' | ||
s.require_path = "lib" | ||
s.files = %w( MIT-LICENSE README.markdown Rakefile ) + Dir["{spec,lib}/**/*"] | ||
|
||
# rdoc | ||
s.has_rdoc = false | ||
|
||
# Dependencies | ||
s.add_dependency "dm-abstract_rest_adapter" | ||
s.add_dependency "rspec" | ||
|
||
s.required_ruby_version = ">= 1.8.6" | ||
end | ||
|
||
Rake::GemPackageTask.new(spec) do |package| | ||
package.gem_spec = spec | ||
end | ||
|
||
desc "Run :package and install the resulting .gem" | ||
task :install => :package do | ||
sh %{#{SUDO} gem install --local pkg/dm-abstract_rest_adapter-#{DM_ABSTRACT_REST_ADAPTER_VERSION}.gem --no-rdoc --no-ri} | ||
end | ||
|
||
desc "Run :clean and uninstall the .gem" | ||
task :uninstall => :clean do | ||
sh %{#{SUDO} gem uninstall dm-abstract_rest_adapter} | ||
end | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
require 'rubygems' | ||
require 'uuidtools' | ||
|
||
module DataMapper | ||
module Types | ||
class UUID < DataMapper::Type | ||
primitive String | ||
|
||
def self.load(value, property) | ||
::UUID.parse(value) | ||
end | ||
|
||
def self.dump(value, property) | ||
return nil if value.nil? | ||
value.to_s | ||
end | ||
|
||
def self.typecast(value, property) | ||
value.kind_of?(::UUID) ? value : load(value.to_s, property) | ||
end | ||
end | ||
end | ||
end | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
module Resourceful | ||
|
||
class SSBEAuthenticator | ||
require 'httpauth' | ||
require 'addressable/uri' | ||
|
||
|
||
attr_reader :username, :password, :realm, :domain, :challenge | ||
|
||
def initialize(username, password) | ||
@username, @password = username, password | ||
@realm = 'SystemShepherd' | ||
@domain = nil | ||
end | ||
|
||
def update_credentials(challenge_response) | ||
@domain = Addressable::URI.parse(challenge_response.uri).host | ||
@challenge = HTTPAuth::Digest::Challenge.from_header(challenge_response.header['WWW-Authenticate'].first) | ||
end | ||
|
||
def valid_for?(challenge_response) | ||
return false unless challenge_header = challenge_response.header['WWW-Authenticate'] | ||
begin | ||
challenge = HTTPAuth::Digest::Challenge.from_header(challenge_header.first) | ||
rescue HTTPAuth::UnwellformedHeader | ||
return false | ||
end | ||
challenge.realm == @realm | ||
end | ||
|
||
def can_handle?(request) | ||
Addressable::URI.parse(request.uri).host == @domain | ||
end | ||
|
||
def add_credentials_to(request) | ||
request.header['Authorization'] = credentials_for(request) | ||
end | ||
|
||
def credentials_for(request) | ||
HTTPAuth::Digest::Credentials.from_challenge(@challenge, | ||
:username => @username, | ||
:password => @password, | ||
:method => request.method.to_s.upcase, | ||
:uri => Addressable::URI.parse(request.uri).path).to_header | ||
end | ||
|
||
end | ||
|
||
end | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
require 'rubygems' | ||
require 'resourceful' | ||
require 'json' | ||
gem 'dm-core', '>=0.9.3' | ||
|
||
require 'pathname' | ||
require Pathname(__FILE__).dirname + 'resourceful/ssbe_authenticator' | ||
require Pathname(__FILE__).dirname + 'dm-types/uuid' | ||
|
||
module DataMapper | ||
module Adapters | ||
|
||
class HttpAdapter < AbstractAdapter | ||
attr_reader :http | ||
|
||
def initialize(name, uri_or_options) | ||
super | ||
|
||
@http = Resourceful::HttpAccessor.new | ||
end | ||
end | ||
|
||
class SsbeAdapter < HttpAdapter | ||
|
||
def initialize(name, uri_or_options) | ||
super | ||
|
||
http.cache_manager = Resourceful::InMemoryCacheManager.new | ||
http.logger = Resourceful::StdOutLogger.new | ||
http.auth_manager.add_auth_handler Resourceful::SSBEAuthenticator.new('dev', 'dev') | ||
|
||
service_descriptor_uri = uri_or_options[:service_descriptor_uri] | ||
@service_descriptor = @http.resource(service_descriptor_uri).get.body | ||
@service_descriptor = JSON.parse(@service_descriptor) | ||
end | ||
|
||
def read_many(query) | ||
model = query.model | ||
puts "Model:", query.inspect | ||
service_type = model.service_type | ||
resource_name = model.resource_name | ||
parser = model.parser | ||
|
||
unless model.resource | ||
resource_descriptor_uri = @service_descriptor["items"].find { |i| i["service_type"] == service_type }["href"] | ||
resource_descriptor = JSON.parse(@http.resource(resource_descriptor_uri).get.body) | ||
|
||
resource_uri = resource_descriptor["resources"].find { |i| i["name"] == resource_name }["href"] | ||
model.resource = @http.resource(resource_uri, :accept => parser.mime_type) | ||
end | ||
|
||
doc = parser.deserialize(model.resource.get.body) | ||
|
||
Collection.new(query) do |collection| | ||
doc['items'].each do |item| | ||
collection.load( | ||
query.fields.map { |prop| item[prop.field.to_s] } | ||
) | ||
end | ||
end | ||
end | ||
|
||
def read_one(query) | ||
uri = query.conditions.first[2] | ||
parser = query.model.parser | ||
|
||
resource = @http.resource(uri, :accept => parser.mime_type) | ||
|
||
doc = parser.deserialize(resource.get.body) | ||
|
||
query.model.load(query.fields.map { |prop| doc[prop.field.to_s] }, query) | ||
end | ||
|
||
|
||
class Parser | ||
|
||
def self.mime_type(mime_type) | ||
@@mime_type = mime_type | ||
end | ||
|
||
def mime_type | ||
@@mime_type | ||
end | ||
|
||
end | ||
|
||
class SSJParser < Parser | ||
mime_type 'application/vnd.absolute-performance.sysshep+json' | ||
|
||
def deserialize(body) | ||
JSON.parse(body) | ||
end | ||
|
||
end | ||
|
||
end | ||
|
||
|
||
end | ||
|
||
module Model | ||
attr_reader :service_type, :resource_name, :parser | ||
attr_accessor :resource | ||
|
||
def set_service_type(uri_or_type) | ||
@service_type = case uri_or_type | ||
when String then uri_or_type | ||
when :kernel | ||
'http://systemshepherd.com/services/kernel' | ||
else | ||
raise "Unknown service type" | ||
end | ||
end | ||
|
||
def set_resource_name(name) | ||
@resource_name = name | ||
end | ||
|
||
def set_parser(parser) | ||
@parser = parser | ||
end | ||
|
||
end | ||
|
||
end | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
require 'rubygems' | ||
require 'dm-core' | ||
require 'dm-types' | ||
require 'pathname' | ||
require 'uuidtools' | ||
require Pathname(__FILE__).dirname + 'lib/ssbe_adapter' | ||
|
||
DataMapper.setup(:default, :adapter => :ssbe, :service_descriptor_uri => 'http://core.ssbe.localhost/service_descriptors') | ||
|
||
class Client | ||
include DataMapper::Resource | ||
set_service_type :kernel | ||
set_resource_name "AllClients" | ||
set_parser DataMapper::Adapters::SsbeAdapter::SSJParser.new | ||
|
||
property :name, String | ||
property :href, URI, :key => true | ||
property :id, UUID | ||
property :longname, String | ||
property :active, Boolean | ||
|
||
end | ||
|
||
clients = Client.all | ||
puts clients.inspect | ||
|
||
client = Client.get(clients.first.href) | ||
puts client.inspect | ||
|