diff --git a/lib/neography/config.rb b/lib/neography/config.rb index 481599e..e0e64f2 100644 --- a/lib/neography/config.rb +++ b/lib/neography/config.rb @@ -7,7 +7,7 @@ class Config :max_threads, :authentication, :username, :password, :parser, :max_execution_time, - :proxy + :proxy, :http_send_timeout, :http_receive_timeout def initialize set_defaults @@ -15,45 +15,49 @@ def initialize def to_hash { - :protocol => @protocol, - :server => @server, - :port => @port, - :directory => @directory, - :cypher_path => @cypher_path, - :gremlin_path => @gremlin_path, - :log_file => @log_file, - :log_enabled => @log_enabled, - :logger => @logger, - :slow_log_threshold => @slow_log_threshold, - :max_threads => @max_threads, - :authentication => @authentication, - :username => @username, - :password => @password, - :parser => @parser, - :max_execution_time => @max_execution_time, - :proxy => @proxy + :protocol => @protocol, + :server => @server, + :port => @port, + :directory => @directory, + :cypher_path => @cypher_path, + :gremlin_path => @gremlin_path, + :log_file => @log_file, + :log_enabled => @log_enabled, + :logger => @logger, + :slow_log_threshold => @slow_log_threshold, + :max_threads => @max_threads, + :authentication => @authentication, + :username => @username, + :password => @password, + :parser => @parser, + :max_execution_time => @max_execution_time, + :proxy => @proxy, + :http_send_timeout => @http_send_timeout, + :http_receive_timeout => @http_receive_timeout } end private def set_defaults - @protocol = "http://" - @server = "localhost" - @port = 7474 - @directory = "" - @cypher_path = "/cypher" - @gremlin_path = "/ext/GremlinPlugin/graphdb/execute_script" - @log_file = "neography.log" - @log_enabled = false - @slow_log_threshold = 0 - @max_threads = 20 - @authentication = nil - @username = nil - @password = nil - @parser = MultiJsonParser - @max_execution_time = 6000 - @proxy = nil + @protocol = "http://" + @server = "localhost" + @port = 7474 + @directory = "" + @cypher_path = "/cypher" + @gremlin_path = "/ext/GremlinPlugin/graphdb/execute_script" + @log_file = "neography.log" + @log_enabled = false + @slow_log_threshold = 0 + @max_threads = 20 + @authentication = nil + @username = nil + @password = nil + @parser = MultiJsonParser + @max_execution_time = 6000 + @proxy = nil + @http_send_timeout = 1200 + @http_receive_timeout = 1200 end end diff --git a/lib/neography/connection.rb b/lib/neography/connection.rb index b3256e1..282b7d3 100644 --- a/lib/neography/connection.rb +++ b/lib/neography/connection.rb @@ -4,21 +4,21 @@ module WasCreated class Connection USER_AGENT = "Neography/#{Neography::VERSION}" ACTIONS = ["get", "post", "put", "delete"] - + attr_accessor :protocol, :server, :port, :directory, :cypher_path, :gremlin_path, :log_file, :log_enabled, :logger, :slow_log_threshold, :max_threads, :authentication, :username, :password, :parser, :client, - :proxy + :proxy, :http_send_timeout, :http_receive_timeout def initialize(options = ENV['NEO4J_URL'] || {}) config = merge_configuration(options) save_local_configuration(config) @client ||= HTTPClient.new(config[:proxy]) - @client.send_timeout = 1200 # 10 minutes - @client.receive_timeout = 1200 + @client.send_timeout = config[:http_send_timeout] + @client.receive_timeout = config[:http_receive_timeout] authenticate end @@ -42,16 +42,16 @@ def merge_options(options) end ACTIONS.each do |action| - define_method(action) do |path, options = {}| + define_method(action) do |path, options = {}| # This ugly hack is required because internal Batch paths do not start with "/db/data" # if somebody has a cleaner solution... pull request please! path = "/db/data" + path if ["node", "relationship", "transaction", "cypher", "propertykeys", "schema", "label", "labels", "batch", "index", "ext"].include?(path.split("/")[1].split("?").first) query_path = configuration + path - query_body = merge_options(options)[:body] + query_body = merge_options(options)[:body] log path, query_body do - evaluate_response(@client.send(action.to_sym, query_path, query_body, merge_options(options)[:headers]), path, query_body) + evaluate_response(@client.send(action.to_sym, query_path, query_body, merge_options(options)[:headers]), path, query_body) end - end + end end def log(path, body) @@ -80,7 +80,7 @@ def authenticate(path = nil) @client.www_auth.basic_auth.challenge(configuration) if auth_type == 'basic_auth' end end - + private def merge_configuration(options) @@ -143,13 +143,13 @@ def handle_batch(response) body = @parser.json(response.body.force_encoding("UTF-8")) body.each do |result| if result["status"] >= 400 - code = result["status"] + code = result["status"] break end end return code, body, true end - + def return_result(response, code, body, parsed, path, query_body) case code when 200 @@ -166,7 +166,7 @@ def return_result(response, code, body, parsed, path, query_body) when 400..500 handle_4xx_500_response(response, code, body, path, query_body) nil - end + end end def handle_4xx_500_response(response, code, body, path, query_body) @@ -184,7 +184,7 @@ def handle_4xx_500_response(response, code, body, path, query_body) parsed_body = result["body"] || result break end - end + end else parsed_body = @parser.json(body) end @@ -195,7 +195,7 @@ def handle_4xx_500_response(response, code, body, path, query_body) @logger.error "#{response.dump} error: #{body}" if @log_enabled raise_errors(code, parsed_body["exception"], message, stacktrace, request, index) end - + def raise_errors(code, exception, message, stacktrace, request, index) error = nil case code @@ -215,12 +215,12 @@ def raise_errors(code, exception, message, stacktrace, request, index) when /RelationshipNotFoundException/ ; RelationshipNotFoundException when /NotFoundException/ ; NotFoundException when /UniquePathNotUniqueException/ ; UniquePathNotUniqueException - when /DeadlockDetectedException/ ; DeadlockDetectedException + when /DeadlockDetectedException/ ; DeadlockDetectedException else NeographyError end - - raise error.new(message, code, stacktrace, request, index) + + raise error.new(message, code, stacktrace, request, index) end def parse_string_options(options) diff --git a/spec/unit/config_spec.rb b/spec/unit/config_spec.rb index a1bb5e6..a464558 100644 --- a/spec/unit/config_spec.rb +++ b/spec/unit/config_spec.rb @@ -7,44 +7,49 @@ module Neography context "defaults" do - its(:protocol) { should == 'http://' } - its(:server) { should == 'localhost' } - its(:port) { should == 7474 } - its(:directory) { should == '' } - its(:cypher_path) { should == '/cypher' } - its(:gremlin_path) { should == '/ext/GremlinPlugin/graphdb/execute_script' } - its(:log_file) { should == 'neography.log' } - its(:log_enabled) { should == false } - its(:logger) { should == nil } - its(:slow_log_threshold) { should == 0 } - its(:max_threads) { should == 20 } - its(:authentication) { should == nil } - its(:username) { should == nil } - its(:password) { should == nil } - its(:parser) { should == MultiJsonParser} - its(:max_execution_time) { should == 6000 } - its(:proxy) { should == nil } + its(:protocol) { should == 'http://' } + its(:server) { should == 'localhost' } + its(:port) { should == 7474 } + its(:directory) { should == '' } + its(:cypher_path) { should == '/cypher' } + its(:gremlin_path) { should == '/ext/GremlinPlugin/graphdb/execute_script' } + its(:log_file) { should == 'neography.log' } + its(:log_enabled) { should == false } + its(:logger) { should == nil } + its(:slow_log_threshold) { should == 0 } + its(:max_threads) { should == 20 } + its(:authentication) { should == nil } + its(:username) { should == nil } + its(:password) { should == nil } + its(:parser) { should == MultiJsonParser} + its(:max_execution_time) { should == 6000 } + its(:proxy) { should == nil } + its(:http_send_timeout) { should == 1200 } + its(:http_receive_timeout) { should == 1200 } it "has a hash representation" do expected_hash = { - :protocol => 'http://', - :server => 'localhost', - :port => 7474, - :directory => '', - :cypher_path => '/cypher', - :gremlin_path => '/ext/GremlinPlugin/graphdb/execute_script', - :log_file => 'neography.log', - :log_enabled => false, - :logger => nil, - :slow_log_threshold => 0, - :max_threads => 20, - :authentication => nil, - :username => nil, - :password => nil, - :parser => MultiJsonParser, - :max_execution_time => 6000, - :proxy => nil + :protocol => 'http://', + :server => 'localhost', + :port => 7474, + :directory => '', + :cypher_path => '/cypher', + :gremlin_path => '/ext/GremlinPlugin/graphdb/execute_script', + :log_file => 'neography.log', + :log_enabled => false, + :logger => nil, + :slow_log_threshold => 0, + :max_threads => 20, + :authentication => nil, + :username => nil, + :password => nil, + :parser => MultiJsonParser, + :max_execution_time => 6000, + :proxy => nil, + :http_send_timeout => 1200, + :http_receive_timeout => 1200 + } config.to_hash.should == expected_hash end diff --git a/spec/unit/connection_spec.rb b/spec/unit/connection_spec.rb index 3538c15..91a2810 100644 --- a/spec/unit/connection_spec.rb +++ b/spec/unit/connection_spec.rb @@ -59,8 +59,27 @@ module Neography } } end + + context "httpclient" do + let(:httpclient) { double(:http_client) } + let(:options) do + { + :http_send_timeout => 120, + :http_receive_timeout => 120 + } + end + + it 'configures send/receive timeout' do + HTTPClient.should_receive(:new).and_return(httpclient) + httpclient.should_receive(:send_timeout=).with(120) + httpclient.should_receive(:receive_timeout=).with(120) + connection + end + end end + + context "string option" do let(:options) { "https://user:pass@somehost:8585/path" } @@ -256,4 +275,4 @@ module Neography end end -class Foo; end \ No newline at end of file +class Foo; end