Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Http driver config 6.1.x #274

Open
wants to merge 13 commits into
base: 6.1.x
Choose a base branch
from
32 changes: 19 additions & 13 deletions .rubocop_todo.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This configuration was generated by
# `rubocop --auto-gen-config`
# on 2015-09-07 09:42:54 +1200 using RuboCop version 0.34.0.
# on 2016-11-21 16:05:50 -0800 using RuboCop version 0.34.2.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
Expand Down Expand Up @@ -31,29 +31,37 @@ Lint/UnusedMethodArgument:
- 'lib/neo4j/session.rb'
- 'lib/neo4j/transaction.rb'

# Offense count: 15
# Offense count: 20
Metrics/AbcSize:
Max: 17
Max: 23

# Offense count: 8
# Offense count: 9
# Configuration parameters: CountComments.
Metrics/ClassLength:
Max: 190

# Offense count: 419
# Offense count: 1
Metrics/CyclomaticComplexity:
Max: 8

# Offense count: 517
# Configuration parameters: AllowURI, URISchemes.
Metrics/LineLength:
Max: 180

# Offense count: 17
# Offense count: 21
# Configuration parameters: CountComments.
Metrics/MethodLength:
Max: 14

# Offense count: 3
# Offense count: 1
# Configuration parameters: CountComments.
Metrics/ModuleLength:
Max: 174
Max: 133

# Offense count: 1
Metrics/PerceivedComplexity:
Max: 8

# Offense count: 8
Style/AccessorMethodName:
Expand All @@ -71,15 +79,13 @@ Style/ClassVars:
Exclude:
- 'lib/neo4j/session.rb'

# Offense count: 67
# Offense count: 81
# Configuration parameters: Exclude.
Style/Documentation:
Enabled: false

# Offense count: 4
# Offense count: 1
# Cop supports --auto-correct.
Style/RescueEnsureAlignment:
Exclude:
- 'lib/neo4j-embedded/label.rb'
- 'spec/shared_examples/label.rb'
- 'spec/shared_examples/node_with_tx.rb'

8 changes: 8 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,18 @@ group 'development' do
end

group 'test' do
gem 'term-ansicolor', '~> 1.3.0' if RUBY_VERSION.to_f < 2.0
gem 'coveralls', require: false
gem 'simplecov-html', require: false
gem 'tins', '< 1.7' if RUBY_VERSION.to_f < 2.0
gem 'rspec', '~> 3.0'
gem 'rspec-its'
gem 'dotenv'
gem 'activesupport', '>= 4.0' unless RUBY_VERSION.to_f < 2.2

gem 'em-http-request', '>= 1.1', require: 'em-http', platforms: :ruby
gem 'em-synchrony', '>= 1.0.3', require: ['em-synchrony', 'em-synchrony/em-http'], platforms: :ruby
gem 'excon', '>= 0.27.4'
gem 'patron', '>= 0.4.2', platforms: :ruby
gem 'typhoeus', '>= 0.3.3'
end
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,31 @@
A simple Ruby wrapper around the Neo4j graph database that works with the server and embedded Neo4j API. This gem can be used both from JRuby and normal MRI.
It can be used standalone without the neo4j gem.

## Basic usage

### Executing Cypher queries

To make a basic connection to Neo4j to execute Cypher queries, first choose an adaptor. Adaptors for HTTP and Embedded mode (jRuby only) are available. You can create an adaptor like:

http_adaptor = Neo4j::Core::CypherSession::Adaptors::HTTP.new('http://neo4j:pass@localhost:7474')

# or

neo4j_adaptor = Neo4j::Core::CypherSession::Adaptors::Embedded.new('/file/path/to/graph.db')

The HTTP Adaptor can also take `:faraday_options`. Currently, only :adapter is supported (defaulting to `:net_http_persistent`):

http_adaptor = Neo4j::Core::CypherSession::Adaptors::HTTP.new('http://neo4j:pass@localhost:7474', faraday_options: { adapter: :typhoeus })

Note you **must** install any required http adaptor gems yourself as per [Faraday](https://github.com/lostisland/faraday). Ex for `:typhoeus`, add to your Gemfile:

gem 'typhoeus'

Once you have an adaptor you can create a session like so:

neo4j_session = Neo4j::Core::CypherSession.new(http_adaptor)


## Documentation

### 3.0+ Documentation:
Expand Down
7 changes: 5 additions & 2 deletions lib/neo4j-server/cypher_session.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ def initialize(data_url, connection)
# @return [Faraday]
# @see https://github.com/lostisland/faraday
def self.create_connection(params, url = nil)
faraday_options = params.delete(:faraday_options) || params.delete('faraday_options') || {}
adapter = (faraday_options[:adapter] || faraday_options['adapter'] || :net_http_persistent).to_sym
require 'typhoeus/adapters/faraday' if adapter == :typhoeus

init_params = params[:initialize] && params.delete(:initialize)
conn = Faraday.new(url, init_params) do |b|
b.request :basic_auth, params[:basic_auth][:username], params[:basic_auth][:password] if params[:basic_auth]
Expand All @@ -31,8 +35,7 @@ def self.create_connection(params, url = nil)

b.response :multi_json, symbolize_keys: true, content_type: 'application/json'
# b.use Faraday::Response::RaiseError
b.use Faraday::Adapter::NetHttpPersistent
# b.adapter Faraday.default_adapter
b.adapter adapter
end
conn.headers = {'Content-Type' => 'application/json', 'User-Agent' => ::Neo4j::Session.user_agent_string}
conn
Expand Down
8 changes: 6 additions & 2 deletions lib/neo4j/core/cypher_session/adaptors/http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ class HTTP < Base
# @transaction_state valid states
# nil, :open_requested, :open, :close_requested

def initialize(url, _options = {})
def initialize(url, options = {})
@url = url
@url_components = url_components!(url)
@transaction_state = nil
@faraday_options = options[:faraday_options] || options['faraday_options'] || {}
end

def connect
Expand Down Expand Up @@ -136,12 +137,15 @@ def url_base
end

def connection
adapter = (@faraday_options[:adapter] || @faraday_options['adapter'] || :net_http_persistent).to_sym
require 'typhoeus/adapters/faraday' if adapter == :typhoeus

Faraday.new(@url) do |c|
c.request :basic_auth, user, password
c.request :multi_json

c.response :multi_json, symbolize_keys: true, content_type: 'application/json'
c.use Faraday::Adapter::NetHttpPersistent
c.adapter adapter

c.headers['Content-Type'] = 'application/json'
c.headers['User-Agent'] = user_agent_string
Expand Down
24 changes: 24 additions & 0 deletions spec/neo4j-server/e2e/cypher_session_spec.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'spec_helper'
require './spec/neo4j-server/shared_examples/cypher_session'

module Neo4j
module Server
Expand Down Expand Up @@ -37,6 +38,29 @@ def open_session
expect(connection.port).to eq 7474
expect(connection.host).to eq 'localhost'
end

describe 'faraday_options' do
describe 'the http_adaptor options' do
it 'will pass through a symbol key' do
faraday_hash = {farday_options: {adapter: :something}}
expect(Neo4j::Server::CypherSession).to receive(:open).with(anything, hash_including(faraday_hash))
create_server_session(faraday_hash)
end

it 'will pass through a string key' do
faraday_hash = {farday_options: {adapter: :something}}
expect(Neo4j::Server::CypherSession).to receive(:open).with(anything, hash_including(faraday_hash))
create_server_session(faraday_hash)
end

with_each_faraday_adaptor do |adapter_name|
describe "when set to :#{adapter_name}" do
let(:adapter) { adapter_name }
it_behaves_like 'Neo4j::Server::CypherSession'
end
end
end
end
end


Expand Down
6 changes: 6 additions & 0 deletions spec/neo4j-server/shared_examples/cypher_session.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Requires that an `http_adaptor` let variable exist with the Faraday adaptor name
RSpec.shared_examples 'Neo4j::Server::CypherSession' do
it 'should be able to connect and query' do
create_server_session(faraday_options: {adapter: adapter}).query.create('(n)').return('ID(n) AS id').first[:id]
end
end
28 changes: 26 additions & 2 deletions spec/neo4j/core/cypher_session/adaptors/http_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
require 'spec_helper'
require 'neo4j/core/cypher_session/adaptors/http'
require './spec/neo4j/core/shared_examples/adaptor'
require './spec/neo4j/core/shared_examples/http'

describe Neo4j::Core::CypherSession::Adaptors::HTTP, new_cypher_session: true do
before(:all) { setup_http_request_subscription }
Expand All @@ -16,10 +17,33 @@
expect { adaptor_class.new('https://localhost:7474/') }.not_to raise_error
expect { adaptor_class.new('https://foo:bar@localhost:7474') }.not_to raise_error
end

describe 'the http_adaptor option' do
it 'uses net_http_persistent by default' do
expect_any_instance_of(Faraday::Connection).to receive(:adapter).with(:net_http_persistent)
adaptor_class.new(server_url).connect
end

it 'will pass through a symbol key' do
expect_any_instance_of(Faraday::Connection).to receive(:adapter).with(:something)
adaptor_class.new(server_url, faraday_options: {adapter: :something}).connect
end

it 'will pass through a string key' do
expect_any_instance_of(Faraday::Connection).to receive(:adapter).with(:something)
adaptor_class.new(server_url, faraday_options: {'adapter' => :something}).connect
end

with_each_faraday_adaptor do |adapter_name|
describe "the :#{adapter_name} adaptor" do
let(:adapter) { adapter_name }
it_behaves_like 'Neo4j::Core::CypherSession::Adaptors::HTTP'
end
end
end
end

let(:url) { ENV['NEO4J_URL'] }
let(:adaptor) { adaptor_class.new(url) }
let(:adaptor) { adaptor_class.new(server_url) }

before { adaptor.connect }

Expand Down
6 changes: 6 additions & 0 deletions spec/neo4j/core/shared_examples/http.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Requires that an `http_adaptor` let variable exist with the Faraday adaptor name
RSpec.shared_examples 'Neo4j::Core::CypherSession::Adaptors::HTTP' do
it 'should connect properly' do
Neo4j::Core::CypherSession::Adaptors::HTTP.new(server_url, faraday_options: {adapter: adapter}).connect.get('/')
end
end
8 changes: 8 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,11 @@ def setup_http_request_subscription
end
}
end

def with_each_faraday_adaptor
adaptors = Faraday::Adapter.instance_variable_get(:@registered_middleware).keys - [:test, :rack]
adaptors -= [:patron, :em_synchrony, :em_http] if RUBY_PLATFORM == 'java'
adaptors.each do |adaptor_name|
yield adaptor_name
end
end