ruby-fs-stack 0.2.6 → 0.3.0

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.
data/README.rdoc CHANGED
@@ -32,10 +32,17 @@ or for the pure Ruby implementation
32
32
 
33
33
  require 'rubygems'
34
34
  require 'ruby-fs-stack'
35
-
35
+
36
+ # Optionally, you can pass a logger to the communicator
37
+ # the logger can be the standard Ruby Logger or any logger
38
+ # that responds to :info or :debug like the Rails logger
39
+ require 'logger'
40
+ logger = Logger.new('fs_stack.log')
41
+
36
42
  communicator = FsCommunicator.new :domain => 'http://www.dev.usys.org', # or 'https://api.familysearch.org'
37
43
  :key => 'DEVELOPER-KEY',
38
- :user_agent => 'Ruby-Fs-Stack/v.1 (JimmyZimmerman) FsCommunicator/0.1 (Ruby)'
44
+ :user_agent => 'Ruby-Fs-Stack/v.1 (JimmyZimmerman) FsCommunicator/0.1 (Ruby)',
45
+ :logger => logger
39
46
 
40
47
  communicator.identity_v1.authenticate :username => 'USERNAME', :password => 'PASSWORD' #=> true
41
48
  communicator.session #=> "USYSE4EF197..."
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.6
1
+ 0.3.0
@@ -3,7 +3,7 @@ require 'net/https'
3
3
  require 'uri'
4
4
 
5
5
  class FsCommunicator
6
- attr_accessor :domain, :key, :user_agent, :session, :handle_throttling
6
+ attr_accessor :domain, :key, :user_agent, :session, :handle_throttling, :logger
7
7
  include RubyFsStack
8
8
  # ====Params
9
9
  # <tt>options</tt> - a hash with the following options
@@ -17,6 +17,10 @@ class FsCommunicator
17
17
  # You will likely want this turned off when running this library from Rails or any other
18
18
  # system that is single-threaded so as to not sleep the entire process until throttling
19
19
  # is successful.
20
+ # * :logger - (optional) if a logger is assigned to the communicator, all get requests and
21
+ # responses will be logged. The request and response ("GET /path" and "200 OK") will be
22
+ # logged at the info level. Headers and request/response bodies will be logged at the debug
23
+ # level.
20
24
  def initialize(options = {})
21
25
  # merge default options with options hash
22
26
  o = {
@@ -24,13 +28,15 @@ class FsCommunicator
24
28
  :key => '',
25
29
  :user_agent => 'FsCommunicator/0.1 (Ruby)', # should be overridden by options user_agent
26
30
  :session => nil,
27
- :handle_throttling => false
31
+ :handle_throttling => false,
32
+ :logger => nil
28
33
  }.merge(options)
29
34
  @domain = o[:domain]
30
35
  @key = o[:key]
31
36
  @user_agent = o[:user_agent]
32
37
  @session = o[:session]
33
38
  @handle_throttling = o[:handle_throttling]
39
+ @logger = o[:logger]
34
40
  end
35
41
 
36
42
  def post(url,payload)
@@ -40,15 +46,16 @@ class FsCommunicator
40
46
  request.body = payload
41
47
  request['Content-Type'] = "application/json"
42
48
  request['User-Agent'] = self.user_agent
49
+
43
50
  http = Net::HTTP.new(uri.host, uri.port)
44
- if uri.scheme == 'https'
45
- http.use_ssl = true
46
- http.ca_file = File.join File.dirname(__FILE__), 'assets','entrust-ca.crt'
47
- http.verify_mode = OpenSSL::SSL::VERIFY_PEER
48
- end
51
+ set_ssl(http) if uri.scheme == 'https'
52
+
53
+ log_request('POST',full_url,request) if logger
49
54
  res = http.start do |ht|
50
55
  ht.request(request)
51
56
  end
57
+ log_response(res) if logger
58
+
52
59
  if res.code == '503' && @handle_throttling
53
60
  sleep 15
54
61
  res = post(url,payload)
@@ -66,15 +73,16 @@ class FsCommunicator
66
73
  if credentials[:username] && credentials[:password]
67
74
  request.basic_auth credentials[:username], credentials[:password]
68
75
  end
76
+
69
77
  http = Net::HTTP.new(uri.host, uri.port)
70
- if uri.scheme == 'https'
71
- http.use_ssl = true
72
- http.ca_file = File.join File.dirname(__FILE__), 'assets','entrust-ca.crt'
73
- http.verify_mode = OpenSSL::SSL::VERIFY_PEER
74
- end
78
+ set_ssl(http) if uri.scheme == 'https'
79
+
80
+ log_request('GET',full_url,request) if logger
75
81
  res = http.start do |ht|
76
82
  ht.request(request)
77
83
  end
84
+ log_response(res) if logger
85
+
78
86
  if res.code == '503' && @handle_throttling
79
87
  sleep 15
80
88
  res = get(url,credentials)
@@ -131,6 +139,28 @@ class FsCommunicator
131
139
  raise exception
132
140
  end
133
141
 
142
+ def log_request(method,url,request)
143
+ logger.info "#{method} #{url}"
144
+ request.each_header do |k,v|
145
+ logger.debug "#{k}: #{v}"
146
+ end
147
+ logger.debug request.body unless request.body.nil?
148
+ end
149
+
150
+ def log_response(response)
151
+ logger.info "#{response.code} #{response.message}"
152
+ response.each_header do |k,v|
153
+ logger.debug "#{k}: #{v}"
154
+ end
155
+ logger.debug response.body
156
+ end
157
+
158
+ def set_ssl(http)
159
+ http.use_ssl = true
160
+ http.ca_file = File.join File.dirname(__FILE__), 'assets','entrust-ca.crt'
161
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
162
+ end
163
+
134
164
  def set_extra_params(uri,credentials = {})
135
165
  if credentials[:username] && credentials[:password]
136
166
  sessionized_url = add_key(uri)
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{ruby-fs-stack}
8
- s.version = "0.2.6"
8
+ s.version = "0.3.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jimmy Zimmerman"]
12
- s.date = %q{2009-12-17}
12
+ s.date = %q{2009-12-18}
13
13
  s.description = %q{A library that enables you to read and update information with the new.familysearch.org API.}
14
14
  s.email = %q{jimmy.zimmerman@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -54,6 +54,7 @@ Gem::Specification.new do |s|
54
54
  "spec/familytree_v2/match_results_spec.rb",
55
55
  "spec/familytree_v2/person_spec.rb",
56
56
  "spec/familytree_v2/search_results_spec.rb",
57
+ "spec/fixtures/fakeweb_response.txt",
57
58
  "spec/fs_utils_spec.rb",
58
59
  "spec/identity_v1/identity_spec.rb",
59
60
  "spec/identity_v1/json/login.js",
@@ -1,9 +1,18 @@
1
1
  require File.dirname(__FILE__) + '/spec_helper'
2
2
  require 'ruby-fs-stack/fs_communicator'
3
3
  require 'fakeweb'
4
+ require 'logger'
4
5
 
5
6
  describe FsCommunicator do
6
7
  include HttpCommunicatorHelper
8
+
9
+ def fake_web(path,status,message,body = '')
10
+ FakeWeb.register_uri(:get, "https://api.familysearch.org#{path}?sessionId=SESSID&dataFormat=application/json", :body => body,
11
+ :status => [status, message])
12
+ FakeWeb.register_uri(:post, "https://api.familysearch.org#{path}?sessionId=SESSID&dataFormat=application/json", :body => body,
13
+ :status => [status, message])
14
+ end
15
+
7
16
  describe "initializing" do
8
17
  it "should accept a hash of options" do
9
18
  lambda {
@@ -226,12 +235,6 @@ describe FsCommunicator do
226
235
  # 501 NotImplemented
227
236
  # 503 ServiceUnavailable
228
237
  describe "raising exceptions" do
229
- def fake_web(path,status,message)
230
- FakeWeb.register_uri(:get, "https://api.familysearch.org#{path}?sessionId=SESSID&dataFormat=application/json", :body => "",
231
- :status => [status, message])
232
- FakeWeb.register_uri(:post, "https://api.familysearch.org#{path}?sessionId=SESSID&dataFormat=application/json", :body => "",
233
- :status => [status, message])
234
- end
235
238
 
236
239
  before(:each) do
237
240
  options = {
@@ -376,4 +379,71 @@ describe FsCommunicator do
376
379
  end
377
380
  end
378
381
 
382
+ describe "logging" do
383
+
384
+ before(:each) do
385
+ @logger = Logger.new(STDOUT)
386
+ options = {
387
+ :domain => 'https://api.familysearch.org',
388
+ :key => '1111-1111',
389
+ :user_agent => "FsCommunicator/0.1",
390
+ :session => 'SESSID',
391
+ :logger => @logger
392
+ }
393
+ @com = FsCommunicator.new options
394
+ end
395
+
396
+ it "should accept an optional logger object when initializing" do
397
+ @com.logger.should == @logger
398
+ end
399
+
400
+ it "should be able to assign a logger after initialization" do
401
+ @com.logger = @logger
402
+ @com.logger.should == @logger
403
+ end
404
+
405
+ it "should log each GET request URL and headers" do
406
+ response = File.join(File.dirname(__FILE__),'fixtures','fakeweb_response.txt')
407
+ FakeWeb.register_uri(:get, "https://api.familysearch.org/familytree/v2/person/KWQS-BBQ?sessionId=SESSID&dataFormat=application/json",
408
+ :response => response)
409
+ @com.logger.should_receive(:info).with(/GET \/familytree\/v2\/person/)
410
+ @com.logger.should_receive(:debug).with("accept: */*")
411
+ @com.logger.should_receive(:debug).with("user-agent: FsCommunicator/0.1")
412
+ @com.logger.should_receive(:info).with("200 OK")
413
+ @com.logger.should_receive(:debug).with("app_svr_id: 9.32")
414
+ @com.logger.should_receive(:debug).with("expires: Thu, 01 Jan 1970 00:00:00 GMT")
415
+ @com.logger.should_receive(:debug).with("content-language: en-US")
416
+ @com.logger.should_receive(:debug).with("date: Thu, 17 Dec 2009 23:58:48 GMT")
417
+ @com.logger.should_receive(:debug).with("content-length: 779")
418
+ @com.logger.should_receive(:debug).with("x-processing-time: 152")
419
+ @com.logger.should_receive(:debug).with("cache-control: no-store, no-cache")
420
+ @com.logger.should_receive(:debug).with("content-type: application/json;charset=utf-8")
421
+ @com.logger.should_receive(:debug).with(/\{"persons":/)
422
+ @com.get('/familytree/v2/person/KWQS-BBQ')
423
+ end
424
+
425
+ it "should log each POST request URL and headers" do
426
+ response = File.join(File.dirname(__FILE__),'fixtures','fakeweb_response.txt')
427
+ FakeWeb.register_uri(:post, "https://api.familysearch.org/familytree/v2/person/KWQS-BBQ?sessionId=SESSID&dataFormat=application/json",
428
+ :response => response)
429
+ @com.logger.should_receive(:info).with(/POST \/familytree\/v2\/person/)
430
+ @com.logger.should_receive(:debug).with("accept: */*")
431
+ @com.logger.should_receive(:debug).with("user-agent: FsCommunicator/0.1")
432
+ @com.logger.should_receive(:debug).with("content-type: application/json")
433
+ @com.logger.should_receive(:debug).with("CONTENT")
434
+ @com.logger.should_receive(:info).with("200 OK")
435
+ @com.logger.should_receive(:debug).with("app_svr_id: 9.32")
436
+ @com.logger.should_receive(:debug).with("expires: Thu, 01 Jan 1970 00:00:00 GMT")
437
+ @com.logger.should_receive(:debug).with("content-language: en-US")
438
+ @com.logger.should_receive(:debug).with("date: Thu, 17 Dec 2009 23:58:48 GMT")
439
+ @com.logger.should_receive(:debug).with("content-length: 779")
440
+ @com.logger.should_receive(:debug).with("x-processing-time: 152")
441
+ @com.logger.should_receive(:debug).with("cache-control: no-store, no-cache")
442
+ @com.logger.should_receive(:debug).with("content-type: application/json;charset=utf-8")
443
+ @com.logger.should_receive(:debug).with(/\{"persons":/)
444
+ @com.post('/familytree/v2/person/KWQS-BBQ','CONTENT')
445
+ end
446
+
447
+ end
448
+
379
449
  end
@@ -0,0 +1,12 @@
1
+ HTTP/1.1 200 OK
2
+ Content-Type: application/json;charset=utf-8
3
+ Expires: Thu, 01 Jan 1970 00:00:00 GMT
4
+ Cache-Control: no-store
5
+ Cache-Control: no-cache
6
+ X-PROCESSING-TIME: 152
7
+ Date: Thu, 17 Dec 2009 23:58:48 GMT
8
+ Content-Language: en-US
9
+ APP_SVR_ID: 9.32
10
+ Content-Length: 779
11
+
12
+ {"persons":[{"id":"KW3B-N9X","version":"8590000133","assertions":{"events":[{"value":{"type":"Birth","date":{"selected":false,"normalized":"11 March 1950","original":"11 Mar 1950","astro":{"earliest":"2433352","latest":"2433352"}},"place":{"selected":false,"normalized":{"value":"Utah, United States","id":"27","version":"3.5.0"},"original":"Utah"}}}],"names":[{"value":{"type":"Name","forms":[{"selected":false,"pieces":[{"value":"API","type":"Given","predelimiters":"","postdelimiters":" "},{"value":"User","type":"Given","predelimiters":"","postdelimiters":" "},{"value":"1241","type":"Family","predelimiters":"","postdelimiters":""}],"fullText":"API User 1241"}]}}],"genders":[{"value":{"type":"Male"}}]}}],"version":"2.0.20091103.5176","statusCode":200,"statusMessage":"OK"}
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-fs-stack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jimmy Zimmerman
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-12-17 00:00:00 -07:00
12
+ date: 2009-12-18 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -79,6 +79,7 @@ files:
79
79
  - spec/familytree_v2/match_results_spec.rb
80
80
  - spec/familytree_v2/person_spec.rb
81
81
  - spec/familytree_v2/search_results_spec.rb
82
+ - spec/fixtures/fakeweb_response.txt
82
83
  - spec/fs_utils_spec.rb
83
84
  - spec/identity_v1/identity_spec.rb
84
85
  - spec/identity_v1/json/login.js