orientdb_client 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3b21ad9036b5e5873f1f51dc9508dd386bddd7b0
4
- data.tar.gz: 503d006feb63fd5d7ff3ab7994af1e5d86839fed
3
+ metadata.gz: 34b02fe8fb6024627b8f8b7da8b29740018eef44
4
+ data.tar.gz: 293559a446780800aa63e846cad714eef7e24d31
5
5
  SHA512:
6
- metadata.gz: 9eb18afed7dd6191124107a6919df244536c4468e11a599690134f43f150470c20a8d078f3aea3db7131b8c165608cda500fd1a8104182d5385ba6b962480e98
7
- data.tar.gz: 252f573b2958cb4ffcbae1b7a71f0cb115d8e5f78e5748c563f5b9d1a41700c30f2629a7f1da8d51e7849b99c0df4bffd397cd37c453b53c15a9d2ab7737e509
6
+ metadata.gz: 8b2d8dcbdd22d90bd872b182694d410bba586205cb99216f0e89d50cdcd7925d6e963986b1f9d904fd023c894784c941b70ed3080faf2acadd3b759a801e21f1
7
+ data.tar.gz: 88e1a49b4dd43aef5caee889180f3cd8f1ab6ceec199ea47dfdac42e3fee82c887dbe7ba4ff5457316b011bc176cf5e2cc5f2c624266b950f5a8538beffba931
data/.gitignore CHANGED
@@ -20,3 +20,4 @@ tmp
20
20
  *.o
21
21
  *.a
22
22
  mkmf.log
23
+ .byebug_history
data/.travis.yml CHANGED
@@ -1,4 +1,11 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.2.3
3
+ - 2.1
4
+ - 2.2
4
5
  script: bundle exec rspec --tag ~'type:integration'
6
+ matrix:
7
+ include:
8
+ - rvm: 2.2
9
+ gemfile: Gemfiles/Gemfile.as3.2
10
+ - rvm: 2.2
11
+ gemfile: Gemfiles/Gemfile.as4.0
data/CHANGELOG.md ADDED
@@ -0,0 +1,19 @@
1
+ # Changelog
2
+
3
+ ## Master
4
+
5
+ ## 0.0.3
6
+
7
+ * Added `CHANGELOG.md`
8
+ * Breaking change: Swapped logging to use ActiveSupport::Notifications (#16). You will need to
9
+ update any code that assigns `MyClient::logger = `. Requests and response processing are
10
+ both instrumented.
11
+
12
+ ## 0.0.2
13
+
14
+ * Integrated Travic CI (#15).
15
+ * Add handling more Orientdb errors (#14).
16
+
17
+ ## 0.0.1
18
+
19
+ * Initial release.
data/Gemfile CHANGED
@@ -3,6 +3,8 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in orientdb_client.gemspec
4
4
  gemspec
5
5
 
6
+ gem 'activesupport', '> 3.2', require: false
7
+
6
8
  group :test do
7
9
  gem 'curb', '~> 0.8'
8
10
  end
@@ -0,0 +1,9 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem 'activesupport', '~> 3.2', require: false
4
+
5
+ group :test do
6
+ gem 'curb', '~> 0.8'
7
+ end
8
+
9
+ gemspec :path => "../"
@@ -0,0 +1,9 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem 'activesupport', '~> 4.0', require: false
4
+
5
+ group :test do
6
+ gem 'curb', '~> 0.8'
7
+ end
8
+
9
+ gemspec :path => "../"
data/README.md CHANGED
@@ -44,20 +44,39 @@ my_client.query('select * from V')
44
44
  # create database
45
45
  my_client.create_database('new_db', 'plocal', 'graph')
46
46
 
47
- # use a different logger
48
- class MyLogger
49
- def info(message)
50
- puts "my message: #{message}"
51
- end
52
- end
53
- Orientdb::logger = MyLogger.new
54
-
55
47
  # use a different HttpAdapter
56
48
  require 'orientdb_client'
57
49
  require 'orientdb_client/http_adapters/curb_adapter'
58
50
  client = OrientdbClient.client(adapter: 'CurbAdapter')
59
51
  ```
60
52
 
53
+ ## Logging/instrumentation
54
+
55
+ OrientdbClient does no logging by default, but will use ActiveSupport::Notifications
56
+ if you `require 'orientdb_client/instrumentation/log_subscriber'`.
57
+
58
+ If you are using Rails, this should *just work*.
59
+
60
+ If you aren't, you'll need to manually specify the logger, like so:
61
+
62
+
63
+ ```ruby
64
+ # activesupport version 3
65
+ OrientdbClient::Instrumentation::LogSubscriber.logger = Logger.new(STDOUT)
66
+
67
+ # activesupport version 4
68
+ ActiveSupport::LogSubscriber.logger = Logger.new(STDOUT)
69
+ ```
70
+
71
+ The right-hand side of the assignment here can be an instance of whatever
72
+ logger class you want.
73
+
74
+ The following events are instrumented:
75
+
76
+ * `request.orientdb_client`: most of this is corresponds to time spent in HTTP
77
+ * `process_response.orientdb_client`: most of this will correspond to JSON parsing
78
+ and error response code/message handling.
79
+
61
80
  ## HTTP Adapters
62
81
 
63
82
  OrientdbClient currently supports Typhoeus and Curb HTTP adapters.
@@ -0,0 +1,22 @@
1
+ require 'active_support/notifications'
2
+ require 'active_support/log_subscriber'
3
+
4
+ module OrientdbClient
5
+ module Instrumentation
6
+ class LogSubscriber < ::ActiveSupport::LogSubscriber
7
+ def request(event)
8
+ return unless logger.debug?
9
+
10
+ method = event.payload[:method]
11
+ response_code = event.payload[:response_code]
12
+ url = event.payload[:url]
13
+ request = "#{method} #{url}: #{response_code}"
14
+
15
+ name = '%s (%.1fms)' % ["OrientdbClient request", event.duration]
16
+ debug " #{color(name, YELLOW, true)} [ #{request} ]"
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ OrientdbClient::Instrumentation::LogSubscriber.attach_to :orientdb_client
@@ -0,0 +1,26 @@
1
+ module OrientdbClient
2
+ module Instrumenters
3
+ # Instrumentor that is useful for tests as it stores each of the events that
4
+ # are instrumented.
5
+ class Memory
6
+ Event = Struct.new(:name, :payload, :result)
7
+
8
+ attr_reader :events
9
+
10
+ def initialize
11
+ @events = []
12
+ end
13
+
14
+ def instrument(name, payload = {})
15
+ result = if block_given?
16
+ yield payload
17
+ else
18
+ nil
19
+ end
20
+
21
+ @events << Event.new(name, payload, result)
22
+ result
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,9 @@
1
+ module OrientdbClient
2
+ module Instrumenters
3
+ class Noop
4
+ def self.instrument(name, payload = {})
5
+ yield payload if block_given?
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,3 +1,3 @@
1
1
  module OrientdbClient
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -1,13 +1,13 @@
1
+ require 'forwardable'
1
2
  require "orientdb_client/version"
2
3
  require "orientdb_client/errors"
3
4
  require "orientdb_client/http_adapters"
4
5
  require "orientdb_client/http_adapters/typhoeus_adapter"
5
6
  require "orientdb_client/class_configurator"
7
+ require "orientdb_client/instrumenters/noop"
6
8
 
7
9
  require 'oj'
8
10
  require 'cgi'
9
- require 'logger'
10
- require 'rainbow'
11
11
 
12
12
  module OrientdbClient
13
13
  class << self
@@ -20,7 +20,8 @@ module OrientdbClient
20
20
 
21
21
  class Client
22
22
  attr_reader :http_client
23
- attr_accessor :logger
23
+ extend Forwardable
24
+ def_delegators :@instrumenter, :instrument
24
25
 
25
26
  def initialize(options)
26
27
  options = {
@@ -34,10 +35,10 @@ module OrientdbClient
34
35
  else
35
36
  HttpAdapters::TyphoeusAdapter
36
37
  end
38
+ @instrumenter = options[:instrumenter] || Instrumenters::Noop
37
39
  @http_client = adapter_klass.new
38
40
  @node = Node.new(host: @host, port: @port, http_client: @http_client, client: self)
39
41
  @connected = false
40
- @logger = Logger.new(STDOUT)
41
42
  self
42
43
  end
43
44
 
@@ -251,12 +252,17 @@ module OrientdbClient
251
252
 
252
253
  def request(method, path, options = {})
253
254
  url = build_url(path)
254
- t1 = Time.now
255
- response = @http_client.request(method, url, options)
256
- time = Time.now - t1
257
- r = handle_response(response)
258
- info("request (#{time}), #{response.response_code}: #{method} #{url}")
259
- r
255
+ request_instrumentation_hash = {method: method, url: url, options: options}
256
+ raw_response = safe_instrument('request.orientdb_client', request_instrumentation_hash) do |payload|
257
+ response = @http_client.request(method, url, options)
258
+ payload[:response_code] = response.response_code
259
+ response
260
+ end
261
+ response_instrumentation_hash = request_instrumentation_hash.merge(response_code: raw_response.response_code)
262
+ processed_response = safe_instrument('process_response.orientdb_client', response_instrumentation_hash) do |payload|
263
+ handle_response(raw_response)
264
+ end
265
+ processed_response
260
266
  end
261
267
 
262
268
  def build_url(path)
@@ -381,10 +387,19 @@ module OrientdbClient
381
387
  end
382
388
  end
383
389
 
384
- def info(message)
385
- wrapped_message = "#{Rainbow('OrientdbClient:').yellow} #{message}"
386
- @client.logger.info(wrapped_message)
390
+ # Ensures instrumentation will complete even if exception is raised.
391
+ def safe_instrument(event_name, args)
392
+ err = nil
393
+ result = @client.instrument(event_name, args) do |payload|
394
+ begin
395
+ yield payload
396
+ rescue => e
397
+ payload[:error] = e.class.to_s
398
+ err = e
399
+ end
400
+ end
401
+ raise err if err
402
+ result
387
403
  end
388
-
389
404
  end
390
405
  end
@@ -20,7 +20,6 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_dependency "typhoeus", "~> 0.6"
22
22
  spec.add_dependency "oj", "~> 2.0"
23
- spec.add_dependency "rainbow", "> 1.99"
24
23
 
25
24
  spec.add_development_dependency "rake"
26
25
  spec.add_development_dependency "pry"
@@ -0,0 +1,56 @@
1
+ require 'spec_helper'
2
+ require 'logger'
3
+ require 'stringio'
4
+ require 'orientdb_client/instrumentation/log_subscriber'
5
+
6
+ # Only required for testing purposes, no difference in public API that impacts
7
+ # actual libraryr code. Rails 4 changes `.logger=` from a `class_attribute` to a
8
+ # `attr_writer` which affects inheritabiltiy.
9
+ begin
10
+ require 'active_support/gem_version'
11
+ version = ActiveSupport::VERSION::MAJOR
12
+ rescue LoadError
13
+ version = 3
14
+ end
15
+
16
+ RSpec.describe OrientdbClient::Instrumentation::LogSubscriber do
17
+ let(:client) { OrientdbClient.client instrumenter: ActiveSupport::Notifications }
18
+
19
+ before do
20
+ @io = StringIO.new
21
+ if version == 3
22
+ OrientdbClient::Instrumentation::LogSubscriber.logger = Logger.new(@io)
23
+ else
24
+ ActiveSupport::LogSubscriber.logger = Logger.new(@io)
25
+ end
26
+ end
27
+
28
+ after do
29
+ if version == 3
30
+ OrientdbClient::Instrumentation::LogSubscriber.logger = nil
31
+ else
32
+ ActiveSupport::LogSubscriber.logger = nil
33
+ end
34
+ end
35
+
36
+ let(:regex) { Regexp.new('get http://localhost:2480/listDatabases') }
37
+
38
+ it "works" do
39
+ begin
40
+ client.list_databases
41
+ rescue
42
+ end
43
+ log = @io.string
44
+ expect(log).to match(regex)
45
+ end
46
+
47
+ it "works through exceptions" do
48
+ allow_any_instance_of(OrientdbClient::HttpAdapters::TyphoeusAdapter).to receive(:request) { raise 'err' }
49
+ begin
50
+ client.list_databases
51
+ rescue
52
+ end
53
+ log = @io.string
54
+ expect(log).to match(regex)
55
+ end
56
+ end
@@ -1,11 +1,8 @@
1
1
  require 'spec_helper'
2
+ require 'orientdb_client/instrumenters/memory'
2
3
 
3
4
  RSpec.describe OrientdbClient do
4
- let(:client) do
5
- c = OrientdbClient.client
6
- c.logger.level = Logger::ERROR
7
- c
8
- end
5
+ let(:client) { OrientdbClient.client }
9
6
  let(:username) { OrientdbClient::Test::Username }
10
7
  let(:valid_username) { OrientdbClient::Test::Username }
11
8
  let(:password) { OrientdbClient::Test::Password }
@@ -680,16 +677,69 @@ RSpec.describe OrientdbClient do
680
677
  end
681
678
  end
682
679
 
680
+ describe 'instrumentation' do
681
+ let(:memory_instrumenter) { OrientdbClient::Instrumenters::Memory.new }
682
+ let(:client) { OrientdbClient.client(instrumenter: memory_instrumenter) }
683
+
684
+ before do
685
+ client.connect(username: username, password: password, db: db)
686
+ end
687
+
688
+ it 'instruments requests' do
689
+ client.list_databases
690
+ request_events = memory_instrumenter.events.select {|e| e.name == 'request.orientdb_client' }
691
+ expect(request_events.size).to eq(2)
692
+
693
+ connect_request_event = request_events.first
694
+ expect(connect_request_event.payload[:url]).to match(/connect/)
695
+ expect(connect_request_event.payload[:response_code]).to eq(204)
696
+
697
+ list_event = request_events.last
698
+ expect(list_event.payload[:url]).to match(/listDatabases/)
699
+ expect(list_event.payload[:response_code]).to eq(200)
700
+ end
701
+
702
+ it 'works when the request fails' do
703
+ allow(client.http_client).to receive(:request).and_call_original
704
+ allow(client.http_client).to receive(:request).with(:get, "http://localhost:2480/class/orientdb_client_rb_test/OUser", anything) { raise 'err' }
705
+
706
+ begin
707
+ client.get_class('OUser')
708
+ rescue
709
+ ensure
710
+ expect(memory_instrumenter.events.last.payload[:error]).to eq('RuntimeError')
711
+ end
712
+ end
713
+
714
+ it 'instruments response handling' do
715
+ client.list_databases
716
+ response_events = memory_instrumenter.events.select {|e| e.name == 'process_response.orientdb_client' }
717
+ expect(response_events.size).to eq(2)
718
+
719
+ connect_response_event = response_events.first
720
+ expect(connect_response_event.payload[:url]).to match(/connect/)
721
+ expect(connect_response_event.payload[:response_code]).to eq(204)
722
+
723
+ list_response_event = response_events.last
724
+ expect(list_response_event.payload[:url]).to match(/listDatabases/)
725
+ expect(list_response_event.payload[:response_code]).to eq(200)
726
+ end
727
+
728
+ it 'works when the response handling fails' do
729
+ begin
730
+ client.command('insert into OUser CONTENT ' + Oj.dump({a:1}))
731
+ rescue
732
+ ensure
733
+ expect(memory_instrumenter.events.last.payload[:error]).to eq('OrientdbClient::SerializationException')
734
+ end
735
+ end
736
+ end
683
737
  end
684
738
 
685
739
  # These specs will sometimes fail, not too much we can do about that, depends
686
740
  # on timing/threading in ruby and odb
687
741
  describe 'mvcc handling', type: :integration do
688
- let(:client) do
689
- c = OrientdbClient.client
690
- c.logger.level = Logger::ERROR
691
- c
692
- end
742
+ let(:client) { OrientdbClient.client }
693
743
  before do
694
744
  client.connect(username: username, password: password, db: db)
695
745
  if client.has_class?('Person')
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: orientdb_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luke Rodgers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-18 00:00:00.000000000 Z
11
+ date: 2015-11-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: typhoeus
@@ -38,20 +38,6 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '2.0'
41
- - !ruby/object:Gem::Dependency
42
- name: rainbow
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">"
46
- - !ruby/object:Gem::Version
47
- version: '1.99'
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">"
53
- - !ruby/object:Gem::Version
54
- version: '1.99'
55
41
  - !ruby/object:Gem::Dependency
56
42
  name: rake
57
43
  requirement: !ruby/object:Gem::Requirement
@@ -147,7 +133,10 @@ files:
147
133
  - ".gitignore"
148
134
  - ".rspec"
149
135
  - ".travis.yml"
136
+ - CHANGELOG.md
150
137
  - Gemfile
138
+ - Gemfiles/Gemfile.as3.2
139
+ - Gemfiles/Gemfile.as4.0
151
140
  - LICENSE.txt
152
141
  - README.md
153
142
  - Rakefile
@@ -157,10 +146,14 @@ files:
157
146
  - lib/orientdb_client/http_adapters.rb
158
147
  - lib/orientdb_client/http_adapters/curb_adapter.rb
159
148
  - lib/orientdb_client/http_adapters/typhoeus_adapter.rb
149
+ - lib/orientdb_client/instrumentation/log_subscriber.rb
150
+ - lib/orientdb_client/instrumenters/memory.rb
151
+ - lib/orientdb_client/instrumenters/noop.rb
160
152
  - lib/orientdb_client/test.rb
161
153
  - lib/orientdb_client/version.rb
162
154
  - orientdb_client.gemspec
163
155
  - spec/curb_adapter_spec.rb
156
+ - spec/integration/orientdb_client/instrumentation/log_subscriber_spec.rb
164
157
  - spec/orientdb_client_spec.rb
165
158
  - spec/spec_helper.rb
166
159
  - spec/support/shared_examples_for_http_adapter.rb
@@ -191,8 +184,8 @@ specification_version: 4
191
184
  summary: Orientdb ruby client
192
185
  test_files:
193
186
  - spec/curb_adapter_spec.rb
187
+ - spec/integration/orientdb_client/instrumentation/log_subscriber_spec.rb
194
188
  - spec/orientdb_client_spec.rb
195
189
  - spec/spec_helper.rb
196
190
  - spec/support/shared_examples_for_http_adapter.rb
197
191
  - spec/typhoeus_adapter_spec.rb
198
- has_rdoc: