Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

major refactoring

  • Loading branch information...
commit 6ba00f3e07dae2414ab870ed5316bdfac5de8872 1 parent da0b1a7
Philipp Brüll authored
8 lib/allegro_graph/catalog.rb
View
@@ -29,14 +29,6 @@ def exists?
@server.catalogs.include? self
end
- def create!
- raise StandardError, "cannot create root catalog!" if self.root?
- @server.request :put, self.path, :expected_status_code => 201
- rescue AllegroGraph::Transport::UnexpectedStatusCodeError => error
- return false if error.status_code == 400
- raise error
- end
-
def repositories
repositories = @server.request :get, self.path + "/repositories", :expected_status_code => 200
repositories.map { |repository| Repository.new self, repository["id"] }
32 lib/allegro_graph/repository.rb
View
@@ -29,7 +29,7 @@ def exists?
def create!
@server.request :put, self.path, :expected_status_code => 204
true
- rescue AllegroGraph::Transport::UnexpectedStatusCodeError => error
+ rescue ExtendedTransport::UnexpectedStatusCodeError => error
return false if error.status_code == 400
raise error
end
@@ -41,7 +41,7 @@ def create_if_missing!
def delete!
@server.request :delete, self.path, :expected_status_code => 200
true
- rescue AllegroGraph::Transport::UnexpectedStatusCodeError => error
+ rescue ExtendedTransport::UnexpectedStatusCodeError => error
return false if error.status_code == 400
raise error
end
@@ -55,6 +55,34 @@ def size
response.to_i
end
+ def create_statement(subject, predicate, object, context = nil)
+ statement = [ subject, predicate, object ]
+ statement << context if context
+ @server.request :post, self.path + "/statements", :body => [ statement ], :expected_status_code => 204
+ true
+ end
+
+ def find_statements(options = { })
+ parameters = { }
+
+ { :subject => :subj, :predicate => :pred, :object => :obj, :context => :context }.each do |option_key, parameter_key|
+ value = options[option_key]
+ parameters.merge! value.is_a?(Array) ?
+ { :"#{parameter_key}" => value[0], :"#{parameter_key}End" => value[1] } :
+ { parameter_key => value } if value
+ end
+
+ [ :offset, :limit, :infer ].each do |key|
+ parameters.merge! key => options[key] if options.has_key?(key)
+ end
+
+ @server.request :get, self.path + "/statements", :parameters => parameters, :expected_status_code => 200
+ end
+
+ def delete_statements(options = { })
+ @server.request :delete, self.path + "/statements", :expected_status_code => 200
+ end
+
end
end
26 lib/allegro_graph/server.rb
View
@@ -26,22 +26,14 @@ def ==(other)
end
def request(http_method, path, options = { })
- type = options[:type] || :json
- case type
- when :text
- request_text http_method, path, options
- when :json
- request_json http_method, path, options
- else
- raise NotImplementedError, "the request type '#{type}' is not implemented"
- end
+ ExtendedTransport.request http_method, self.url + path, credentials.merge(options)
end
def version
{
- :version => self.request(:get, "/version", :type => :text, :expected_status_code => 200),
- :date => self.request(:get, "/version/date", :type => :text, :expected_status_code => 200),
- :revision => self.request(:get, "/version/revision", :type => :text, :expected_status_code => 200)
+ :version => self.request(:get, "/version", :expected_status_code => 200),
+ :date => self.request(:get, "/version/date", :expected_status_code => 200),
+ :revision => self.request(:get, "/version/revision", :expected_status_code => 200)
}
end
@@ -61,16 +53,8 @@ def url
private
- def request_text(http_method, path, options)
- AuthorizedTransport.request http_method, self.url + path, credentials.merge(options)
- end
-
- def request_json(http_method, path, options)
- JSONTransport.request http_method, self.url + path, credentials.merge(options)
- end
-
def credentials
- { :auth_type => :basic, :username => self.username, :password => self.password }
+ { :auth_type => :basic, :username => @username, :password => @password }
end
end
175 lib/allegro_graph/transport.rb
View
@@ -6,101 +6,146 @@
module AllegroGraph
# Common transport layer for http transfers.
- module Transport
+ class Transport
+
+ attr_reader :http_method
+ attr_reader :url
+ attr_reader :options
+ attr_reader :headers
+ attr_reader :parameters
+ attr_reader :body
+ attr_reader :response
+
+ def initialize(http_method, url, options = { })
+ @http_method = http_method
+ @uri = URI.parse url
+ @headers = options[:headers] || { }
+ @parameters = options[:parameters] || { }
+ @body = options[:body]
+ end
- # The UnexpectedStatusCodeError is raised if the :expected_status_code option is given to
- # the :request method and the responded status code is different from the expected one.
- class UnexpectedStatusCodeError < StandardError
+ def perform
+ initialize_request_class
+ initialize_request_path
+ initialize_request_object
+ perform_request
+ end
- attr_reader :status_code
+ private
- def initialize(status_code)
- @status_code = status_code
- end
+ def initialize_request_class
+ request_class_name = @http_method.capitalize
+ raise NotImplementedError, "the request method #{http_method} is not implemented" unless Net::HTTP.const_defined?(request_class_name)
+ @request_class = Net::HTTP.const_get request_class_name
+ end
- def to_s
- "#{super} received status code #{self.status_code}"
+ def initialize_request_path
+ serialize_parameters
+ @request_path = @uri.path + @serialized_parameters
+ end
+
+ def serialize_parameters
+ @serialized_parameters = if @parameters.nil? || @parameters.empty?
+ ""
+ else
+ "?" + @parameters.collect{ |key, value| "#{key}=#{URI.escape(value)}" }.reverse.join("&")
end
+ end
+
+ def initialize_request_object
+ @request = @request_class.new @request_path, @headers
+ @request.body = @body if @body
+ end
+ def perform_request
+ @response = Net::HTTP.start(@uri.host, @uri.port) do |connection|
+ connection.request @request
+ end
end
def self.request(http_method, url, options = { })
- expected_status_code = options[:expected_status_code]
-
- uri = URI.parse url
- response = perform request_object(http_method, uri, options), uri
-
- check_status_code response, expected_status_code if expected_status_code
- response.body
+ transport = new http_method, url, options
+ transport.perform
+ transport.response
end
- def self.request_object(http_method, uri, options)
- request_class_name = http_method.capitalize
- raise NotImplementedError, "the request method #{http_method} is not implemented" unless Net::HTTP.const_defined?(request_class_name)
+ end
- request_class = Net::HTTP.const_get request_class_name
- request_object = request_class.new uri.path + serialize_parameters(options[:parameters]), (options[:headers] || { })
- request_object.body = options[:body].to_json if options.has_key?(:body)
- request_object
- end
+ class ExtendedTransport < Transport
- def self.serialize_parameters(parameters)
- return "" if parameters.nil? || parameters.empty?
- "?" + parameters.collect do |key, value|
- "#{key}=#{URI.escape(serialize_parameter_value(value))}"
- end.reverse.join("&")
- end
+ # The UnexpectedStatusCodeError is raised if the :expected_status_code option is given to
+ # the :request method and the responded status code is different from the expected one.
+ class UnexpectedStatusCodeError < StandardError
- def self.serialize_parameter_value(value)
- value.to_s
- end
+ attr_reader :status_code
+ attr_reader :message
- def self.perform(request, uri)
- Net::HTTP.start(uri.host, uri.port) do |connection|
- connection.request request
+ def initialize(status_code, message = nil)
+ @status_code, @message = status_code, message
+ end
+
+ def to_s
+ "#{super} received status code #{self.status_code}" + (@message ? " [#{@message}]" : "")
end
+
end
- def self.check_status_code(response, expected_status_code)
- response_code = response.code
- raise UnexpectedStatusCodeError, response_code.to_i if expected_status_code.to_s != response_code
+ attr_reader :expected_status_code
+ attr_reader :auth_type
+ attr_reader :username
+ attr_reader :password
+
+ def initialize(http_method, url, options = { })
+ super http_method, url, options
+ @expected_status_code = options[:expected_status_code]
+ @auth_type = options[:auth_type]
+ @username = options[:username]
+ @password = options[:password]
end
- end
+ def perform
+ initialize_headers
+ super
+ check_status_code
+ parse_response
+ end
- module AuthorizedTransport
+ private
- def self.request(http_method, url, options = { })
- if options[:auth_type] == :basic
- options[:headers] ||= { }
- options[:headers]["Authorization"] = "Basic " + Base64.encode64("#{options[:username]}:#{options[:password]}")
+ def initialize_headers
+ if @auth_type == :basic
+ @headers["Authorization"] = "Basic " + Base64.encode64("#{@username}:#{@password}")
+ elsif !@auth_type.nil?
+ raise NotImplementedError, "the given auth_type [#{@auth_type}] is not implemented"
end
- Transport.request http_method, url, options
+ @headers["Accept"] = "application/json"
+ @headers["Content-Type"] = "application/json"
end
-
- end
- # Common json transport layer for http transfers.
- module JSONTransport
+ def serialize_parameters
+ @parameters.each do |key, value|
+ @parameters[key] = value.to_json if value.respond_to?(:to_json)
+ end
+ super
+ end
- def self.request(http_method, url, options = { })
- # puts http_method.to_s + " " + url
- options[:headers] ||= { }
- options[:headers]["Accept"] = "application/json"
- options[:headers]["Content-Type"] = "application/json"
- parse AuthorizedTransport.request(http_method, url, options)
+ def initialize_request_object
+ super
+ @request.body = @body.to_json if @body
end
- def self.serialize_parameter_value(value)
- value.respond_to?(:to_json) ? value.to_json : AuthorizedTransport.serialize_parameter_value(value)
+ def check_status_code
+ return unless @expected_status_code
+ response_code = @response.code
+ response_body = @response.body
+ raise UnexpectedStatusCodeError, response_code.to_i, response_body if @expected_status_code.to_s != response_code
end
- def self.parse(response)
- return nil if response.nil? || response == ""
- # puts response
- JSON.parse response
- rescue JSON::ParserError => error
- nil
+ def parse_response
+ return nil if @response.body.nil?
+ @response = JSON.parse @response.body
+ rescue JSON::ParserError
+ @response = @response.body.to_s
end
end
62 spec/fake_transport.yml
View
@@ -1,112 +1,90 @@
-
:http_method: "get"
:url: "http://localhost:10035/version"
- :headers:
- "Authorization": "Basic dGVzdDp0ZXN0\n"
:response:
:code: "200"
:body: "4.0.1a"
-
:http_method: "get"
:url: "http://localhost:10035/version/date"
- :headers:
- "Authorization": "Basic dGVzdDp0ZXN0\n"
:response:
:code: "200"
:body: "March 10, 2010 10:23:52 GMT-0800"
-
:http_method: "get"
:url: "http://localhost:10035/version/revision"
- :headers:
- "Authorization": "Basic dGVzdDp0ZXN0\n"
:response:
:code: "200"
:body: "[unknown]"
-
:http_method: "get"
:url: "http://localhost:10035/catalogs"
- :headers:
- "Authorization": "Basic dGVzdDp0ZXN0\n"
- "Content-Type": "application/json"
- "Accept": "application/json"
:response:
:code: "200"
- :body: "[{\"id\":\"/\",\"uri\":\"http://localhost:10035\"},{\"id\":\"/test_catalog\",\"uri\":\"http://localhost:10035/test_catalog\"}]"
+ :body:
+ -
+ "id": "/"
+ "uri": "http://localhost:10035"
+ -
+ "id": "/test_catalog"
+ "uri": "http://localhost:10035/test_catalog"
-
:http_method: "put"
:url: "http://localhost:10035/catalogs/test_catalog"
- :headers:
- "Authorization": "Basic dGVzdDp0ZXN0\n"
- "Content-Type": "application/json"
- "Accept": "application/json"
:response:
:code: "400"
:body: ""
-
:http_method: "put"
:url: "http://localhost:10035/catalogs/not_existing"
- :headers:
- "Authorization": "Basic dGVzdDp0ZXN0\n"
- "Content-Type": "application/json"
- "Accept": "application/json"
:response:
:code: "201"
:body: ""
-
:http_method: "get"
:url: "http://localhost:10035/catalogs/test_catalog/repositories"
- :headers:
- "Authorization": "Basic dGVzdDp0ZXN0\n"
- "Content-Type": "application/json"
- "Accept": "application/json"
:response:
:code: "200"
- :body: "[{\"uri\":\"http://localhost:10035/repositories/test_repository\",\"id\":\"test_repository\",\"title\":\"test_repository\",\"readable\":true,\"writable\":true}]"
+ :body:
+ -
+ "uri": "http://localhost:10035/repositories/test_repository"
+ "id": "test_repository"
+ "title": "test_repository"
+ "readable": true
+ "writable": true
-
:http_method: "put"
:url: "http://localhost:10035/catalogs/test_catalog/repositories/test_repository"
- :headers:
- "Authorization": "Basic dGVzdDp0ZXN0\n"
- "Content-Type": "application/json"
- "Accept": "application/json"
:response:
:code: "400"
:body: ""
-
:http_method: "delete"
:url: "http://localhost:10035/catalogs/test_catalog/repositories/test_repository"
- :headers:
- "Authorization": "Basic dGVzdDp0ZXN0\n"
- "Content-Type": "application/json"
- "Accept": "application/json"
:response:
:code: "200"
:body: ""
-
:http_method: "put"
:url: "http://localhost:10035/catalogs/test_catalog/repositories/not_existing"
- :headers:
- "Authorization": "Basic dGVzdDp0ZXN0\n"
- "Content-Type": "application/json"
- "Accept": "application/json"
:response:
:code: "204"
:body: ""
-
:http_method: "delete"
:url: "http://localhost:10035/catalogs/test_catalog/repositories/not_existing"
- :headers:
- "Authorization": "Basic dGVzdDp0ZXN0\n"
- "Content-Type": "application/json"
- "Accept": "application/json"
:response:
:code: "400"
:body: ""
-
:http_method: "get"
:url: "http://localhost:10035/catalogs/test_catalog/repositories/test_repository/size"
- :headers:
- "Authorization": "Basic dGVzdDp0ZXN0\n"
:response:
:code: "200"
:body: "3"
+-
+ :http_method: "post"
+ :url: "http://localhost:10035/catalogs/test_catalog/repositories/test_repository/statements"
+ :response:
+ :code: "204"
+ :body: "1"
2  spec/fake_transport_helper.rb
View
@@ -11,7 +11,7 @@ def self.disable!
end
def self.transport_class
- AllegroGraph::Transport
+ AllegroGraph::ExtendedTransport
end
def self.fake!
58 spec/integration/basic_spec.rb
View
@@ -5,6 +5,11 @@
use_real_transport!
+ before :each do
+ @server = AllegroGraph::Server.new :username => "test", :password => "test"
+ @repository = AllegroGraph::Repository.new @server, "test_repository"
+ end
+
describe "basic server functions" do
before :each do
@@ -13,9 +18,9 @@
it "should return the server's version" do
@server.version.should == {
- :version => "4.0.1a",
- :date => "March 10, 2010 10:23:52 GMT-0800",
- :revision => "[unknown]"
+ :version => "\"4.0.1a\"",
+ :date => "\"March 10, 2010 10:23:52 GMT-0800\"",
+ :revision => "\"[unknown]\""
}
end
@@ -24,8 +29,6 @@
describe "repository listing" do
before :each do
- @server = AllegroGraph::Server.new :username => "test", :password => "test"
- @repository = AllegroGraph::Repository.new @server, "test_repository"
@repository.create_if_missing!
end
@@ -38,8 +41,6 @@
describe "repository creation" do
before :each do
- @server = AllegroGraph::Server.new :username => "test", :password => "test"
- @repository = AllegroGraph::Repository.new @server, "test_repository"
@repository.delete_if_exists!
end
@@ -54,8 +55,6 @@
describe "repository deletion" do
before :each do
- @server = AllegroGraph::Server.new :username => "test", :password => "test"
- @repository = AllegroGraph::Repository.new @server, "test_repository"
@repository.create_if_missing!
end
@@ -67,18 +66,49 @@
end
- describe "repository size" do
+ describe "a repository" do
before :each do
- @server = AllegroGraph::Server.new :username => "test", :password => "test"
- @repository = AllegroGraph::Repository.new @server, "test_repository"
@repository.create_if_missing!
end
-
- it "should return the number of statements" do
+
+ it "should have a size of zero" do
@repository.size.should == 0
end
+ it "should take a statement" do
+ @repository.create_statement("\"test_subject\"", "\"test_predicate\"", "\"test_object\"", "\"test_context\"").should be_true
+ end
+
+ context "filled with statements" do
+
+ before :each do
+ @repository.delete_statements
+ @repository.create_statement "\"test_subject\"", "\"test_predicate\"", "\"test_object\"", "\"test_context\""
+ @repository.create_statement "\"another_subject\"", "\"test_predicate\"", "\"another_object\"", "\"test_context\""
+ end
+
+ it "should have a size of two or more" do
+ @repository.size.should >= 2
+ end
+
+ it "should find all statements" do
+ statements = @repository.find_statements
+ statements.should == [
+ [ "\"test_subject\"", "\"test_predicate\"", "\"test_object\"", "\"test_context\"" ],
+ [ "\"another_subject\"", "\"test_predicate\"", "\"another_object\"", "\"test_context\"" ]
+ ]
+ end
+
+ it "should find statements by filter options" do
+ statements = @repository.find_statements :subject => "test_subject"
+ statements.should == [
+ [ "\"test_subject\"", "\"test_predicate\"", "\"test_object\"", "\"test_context\"" ]
+ ]
+ end
+
+ end
+
end
end
25 spec/lib/allegro_graph/catalog_spec.rb
View
@@ -70,35 +70,10 @@
end
- describe "create!" do
-
- context "for a catalog that already exists" do
-
- it "should return false" do
- @catalog.create!.should be_false
- end
-
- end
-
- context "for a catalog that not exists" do
-
- before :each do
- @catalog.name = "not_existing"
- end
-
- it "should return true" do
- @catalog.create!.should be_false
- end
-
- end
-
- end
-
describe "repositories" do
before :each do
@repository = AllegroGraph::Repository.new @catalog, "test_repository"
-
end
it "should return the catalog's repositories" do
6 spec/lib/allegro_graph/repository_spec.rb
View
@@ -171,7 +171,7 @@
end
- describe "add_statement" do
+ describe "create_statement" do
before :each do
@subject = "test_subject"
@@ -179,7 +179,9 @@
@object = "test_object"
end
-
+ it "should create a statement" do
+ @repository.create_statement(@subject, @predicate, @object).should be_true
+ end
end
13 spec/lib/allegro_graph/server_spec.rb
View
@@ -24,23 +24,16 @@
describe "request" do
before :each do
- AllegroGraph::JSONTransport.stub!(:request)
+ AllegroGraph::ExtendedTransport.stub!(:request)
end
- it "should perform a authorized json request on default" do
- AllegroGraph::JSONTransport.should_receive(:request).with(
+ it "should perform an extended request" do
+ AllegroGraph::ExtendedTransport.should_receive(:request).with(
:get, "http://localhost:10035/", hash_including(:expected_status_code => 200)
).and_return("test" => "test")
@server.request(:get, "/", :expected_status_code => 200).should == { "test" => "test" }
end
- it "should perform a authorized text request if requested" do
- AllegroGraph::AuthorizedTransport.should_receive(:request).with(
- :get, "http://localhost:10035/", hash_including(:expected_status_code => 200)
- ).and_return("test" => "test")
- @server.request(:get, "/", :expected_status_code => 200, :type => :text).should == { "test" => "test" }
- end
-
end
describe "version" do
91 spec/lib/allegro_graph/transport_spec.rb
View
@@ -33,78 +33,67 @@ def do_request(options = { })
do_request
end
- it "should return the response body" do
- do_request.should == "test"
- end
-
- it "should raise UnexpectedStatusCodeError if an unexpected status id returned" do
- lambda do
- do_request :expected_status_code => 201
- end.should raise_error(AllegroGraph::Transport::UnexpectedStatusCodeError)
- end
-
- end
-
- describe "serialize_parameters" do
-
- before :each do
- @parameters = { :test => 1, :another_test => :test }
- end
-
- it "should return an empty string on empty parameter hash" do
- AllegroGraph::Transport.send(:serialize_parameters, { }).should == ""
- end
-
- it "should serialize the given parameters" do
- AllegroGraph::Transport.send(:serialize_parameters, @parameters).should == "?another_test=test&test=1"
+ it "should return the response" do
+ do_request.body.should == "test"
end
end
end
-describe AllegroGraph::AuthorizedTransport do
+describe AllegroGraph::ExtendedTransport do
+
+ use_real_transport!
describe "request" do
before :each do
- AllegroGraph::Transport.stub!(:request)
- end
+ @http_method = :get
+ @url = "http://localhost:5984/"
+ @options = {
+ :auth_type => :basic,
+ :username => "test",
+ :password => "test",
+ :expected_status_code => 200
+ }
- it "should call Transport.request with extended headers" do
- AllegroGraph::Transport.should_receive(:request).with(
- :get, "/", hash_including(:headers => { "Authorization" => "Basic dGVzdDp0ZXN0\n" })
- )
- AllegroGraph::AuthorizedTransport.request :get, "/", :auth_type => :basic, :username => "test", :password => "test"
+ @request = Net::HTTP::Get.new "/", { }
+ @response = Object.new
+ @response.stub!(:code).and_return("200")
+ @response.stub!(:body).and_return("{\"test\":\"test\"}")
+ Net::HTTP.stub!(:start).and_return(@response)
end
- end
-
-end
-
-describe AllegroGraph::JSONTransport do
+ def do_request(options = { })
+ AllegroGraph::ExtendedTransport.request @http_method, @url, @options.merge(options)
+ end
- describe "request" do
+ it "should initialize the correct request object" do
+ Net::HTTP::Get.should_receive(:new).with(
+ "/", { "Authorization" => "Basic dGVzdDp0ZXN0\n", "Accept" => "application/json", "Content-Type" => "application/json" }
+ ).and_return(@request)
+ do_request
+ end
- before :each do
- AllegroGraph::AuthorizedTransport.stub!(:request)
+ it "should perform the request" do
+ Net::HTTP.should_receive(:start).and_return(@response)
+ do_request
end
- it "should call Transport.request with extended headers" do
- AllegroGraph::AuthorizedTransport.should_receive(:request).with(
- :get, "/", hash_including(:headers => { "Accept" => "application/json", "Content-Type" => "application/json" })
- )
- AllegroGraph::JSONTransport.request :get, "/"
+ it "should return the parsed response" do
+ do_request.should == { "test" => "test" }
end
- it "should call AuthorizedTransport.request and parse the response" do
- AllegroGraph::AuthorizedTransport.should_receive(:request).and_return("{\"test\":\"test\"}")
- AllegroGraph::JSONTransport.request(:get, "/").should == { "test" => "test" }
+ it "should raise NotImplementedError if the given auth_type is wrong" do
+ lambda do
+ do_request :auth_type => :invalid
+ end.should raise_error(NotImplementedError)
end
- it "should return nil if AuthorizedTransport.request returns nothing" do
- AllegroGraph::AuthorizedTransport.should_receive(:request).and_return("")
- AllegroGraph::JSONTransport.request(:get, "/").should be_nil
+ it "should raise UnexpectedStatusCodeError if responded status code is wrong" do
+ lambda do
+ do_request :expected_status_code => 201
+ end.should raise_error(AllegroGraph::ExtendedTransport::UnexpectedStatusCodeError)
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.