orientdb_client 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: