tripod 0.4.2 → 0.5.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.
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+ module Tripod::Errors
3
+
4
+ # sparql response too large.
5
+ class SparqlResponseTooLarge < StandardError
6
+ end
7
+
8
+ end
data/lib/tripod/errors.rb CHANGED
@@ -7,5 +7,6 @@ require 'tripod/errors/rdf_type_not_set'
7
7
  require 'tripod/errors/validations'
8
8
  require 'tripod/errors/rdf_parse_failed'
9
9
 
10
+ require 'tripod/errors/sparql_response_too_large'
10
11
  require 'tripod/errors/bad_sparql_request'
11
12
  require 'tripod/errors/bad_data_request'
@@ -21,26 +21,24 @@ module Tripod::SparqlClient
21
21
  Rails.logger.debug "TRIPOD: About to run query:"
22
22
  Rails.logger.debug sparql
23
23
  end
24
+
24
25
  params = {:query => sparql}.merge(extra_params)
25
- hdrs = {:accept => accept_header, :params => params}
26
-
27
- make_the_call = -> {
28
- response = RestClient::Request.execute(
29
- :method => :get,
30
- :url => Tripod.query_endpoint,
31
- :headers => hdrs,
32
- :timeout => Tripod.timeout_seconds
33
- )
34
- response.body
26
+ request_url = Tripod.query_endpoint + '?' + params.to_query
27
+ streaming_opts = {:accept => accept_header, :timeout_seconds => Tripod.timeout_seconds}
28
+ streaming_opts.merge!(:response_limit_bytes => Tripod.response_limit_bytes) if Tripod.response_limit_bytes
29
+
30
+ # Hash.to_query from active support core extensions
31
+ stream_data = -> {
32
+ Tripod::Streaming.get_data(request_url, streaming_opts)
35
33
  }
36
34
 
37
35
  if Tripod.cache_store # if a cache store is configured
38
36
  # SHA-2 the key to keep the it within the small limit for many cache stores (e.g. Memcached is 250bytes)
39
37
  # Note: SHA2's are pretty certain to be unique http://en.wikipedia.org/wiki/SHA-2.
40
38
  key = 'SPARQL-QUERY-' + Digest::SHA2.hexdigest([extra_params, accept_header, sparql].join(" "))
41
- Tripod.cache_store.fetch(key, &make_the_call)
39
+ Tripod.cache_store.fetch(key, &stream_data)
42
40
  else
43
- make_the_call.call()
41
+ stream_data.call()
44
42
  end
45
43
 
46
44
  rescue RestClient::BadRequest => e
@@ -0,0 +1,39 @@
1
+ require 'net/http'
2
+
3
+ module Tripod
4
+ module Streaming
5
+
6
+ # stream data from a url
7
+ # opts
8
+ #  :accept => "*/*"
9
+ # :timeout_seconds = 10
10
+ # :limit_bytes = nil
11
+ def self.get_data(request_url, opts={})
12
+
13
+ accept = opts[:accept] || "*/*"
14
+ timeout_in_seconds = opts[:timeout_seconds] || 10
15
+ limit_in_bytes = opts[:response_limit_bytes]
16
+
17
+ uri = URI(request_url)
18
+
19
+ http = Net::HTTP.new(uri.host, uri.port)
20
+ http.read_timeout = timeout_in_seconds
21
+
22
+ total_bytes = 0
23
+ response_string = ""
24
+
25
+ http.request_get(uri.request_uri, 'Accept' => accept) do |res|
26
+ res.read_body do |seg|
27
+ total_bytes += seg.size
28
+ response_string += seg.to_s
29
+ # if there's a limit, stop when we reach it
30
+ raise Tripod::Errors::SparqlResponseTooLarge.new if limit_in_bytes && (total_bytes > limit_in_bytes)
31
+ end
32
+ end
33
+
34
+ response_string
35
+
36
+ end
37
+
38
+ end
39
+ end
@@ -1,3 +1,3 @@
1
1
  module Tripod
2
- VERSION = "0.4.2"
2
+ VERSION = "0.5.0"
3
3
  end
data/lib/tripod.rb CHANGED
@@ -51,6 +51,9 @@ module Tripod
51
51
  mattr_accessor :timeout_seconds
52
52
  @@timeout_seconds = 30
53
53
 
54
+ mattr_accessor :response_limit_bytes
55
+ @@response_limit_bytes = 4.megabytes
56
+
54
57
  mattr_accessor :cache_store
55
58
 
56
59
  # Use +configure+ to override configuration in an app, (defaults shown)
@@ -59,6 +62,7 @@ module Tripod
59
62
  # config.update_endpoint = 'http://127.0.0.1:3030/tripod/update'
60
63
  # config.query_endpoint = 'http://127.0.0.1:3030/tripod/sparql'
61
64
  # config.timeout_seconds = 30#
65
+ # config.response_limit_bytes = 4.megabytes # omit for no limit
62
66
  # config.cache_store = nil #e.g Tripod::CacheStores::MemcachedCacheStore.new('localhost:11211')
63
67
  # # note: if using memcached, make sure you set the -I (slab size) to big enough to store each result
64
68
  # # and set the -m (total size) to something quite big (or the cache will recycle too often).
@@ -73,6 +77,7 @@ end
73
77
  require 'tripod/cache_stores/memcached_cache_store'
74
78
 
75
79
  require "tripod/extensions"
80
+ require "tripod/streaming"
76
81
  require "tripod/sparql_client"
77
82
  require "tripod/sparql_query"
78
83
  require "tripod/resource_collection"
@@ -4,6 +4,21 @@ describe Tripod::SparqlClient do
4
4
  describe Data do
5
5
  let(:data) { 'some-data-goes-here' }
6
6
 
7
+ describe "Query#query" do
8
+ it "should use Tripod::Streaming to get the data" do
9
+ query = "SELECT * WHERE {?s ?p ?o}"
10
+ Tripod::Streaming.should_receive(:get_data).with(
11
+ Tripod.query_endpoint + "?query=#{CGI.escape(query)}",
12
+ {
13
+ accept: "application/sparql-results+json",
14
+ timeout_seconds: Tripod.timeout_seconds,
15
+ response_limit_bytes: Tripod.response_limit_bytes
16
+ }
17
+ ).and_return("some data")
18
+ Tripod::SparqlClient::Query.query(query, "application/sparql-results+json")
19
+ end
20
+ end
21
+
7
22
  describe "Data#append" do
8
23
  it "should add the graph uri to the configured data endpoint" do
9
24
  RestClient::Request.should_receive(:execute).with(hash_including(url: 'http://127.0.0.1:3030/tripod-test/data?graph=http://example.com/foo'))
@@ -0,0 +1,70 @@
1
+ require "spec_helper"
2
+
3
+ describe Tripod::Streaming do
4
+
5
+ let(:url) { 'http://example.com' }
6
+ let(:response_length) { 64.kilobytes }
7
+
8
+ before do
9
+ WebMock.enable!
10
+ stub_http_request(:get, url).with(:headers => {'Accept' => "*/*"}).to_return(:body => ("0" * response_length))
11
+ end
12
+
13
+ describe ".get_data" do
14
+ it "should make a request to the url passed in" do
15
+ Tripod::Streaming.get_data(url)
16
+ end
17
+
18
+ context "with timeout option" do
19
+ it "should set the read_timeout to that value" do
20
+ Net::HTTP.any_instance.should_receive(:read_timeout=).with(28)
21
+ Tripod::Streaming.get_data(url, :timeout_seconds => 28)
22
+ end
23
+ end
24
+
25
+ context "with no timeout option" do
26
+ it "should set the read_timeout to the default (10s)" do
27
+ Net::HTTP.any_instance.should_receive(:read_timeout=).with(10)
28
+ Tripod::Streaming.get_data(url)
29
+ end
30
+ end
31
+
32
+ context "with an accept header option" do
33
+ it "should use that header for the request " do
34
+ stub_http_request(:get, url).with(:headers => {'Accept' => "application/json"})
35
+ Tripod::Streaming.get_data(url, :accept => 'application/json')
36
+ end
37
+ end
38
+
39
+ # these tests actually download remote resources (from jQuery's CDN) to test the streaming bits
40
+ # TODO: move this out so it doesn't run with the normal rake task??
41
+ context "streaming" do
42
+ before { WebMock.disable! }
43
+
44
+ context "with no limit" do
45
+
46
+ it "should return the full body" do
47
+ full_response_length = RestClient.get('http://code.jquery.com/jquery-1.9.1.js').body.length
48
+ response = Tripod::Streaming.get_data('http://code.jquery.com/jquery-1.9.1.js')
49
+ response.length.should == full_response_length
50
+ end
51
+ end
52
+
53
+ context "with a limit" do
54
+ it "should raise an exception if it's bigger than the limit" do
55
+ unlimited_response = Tripod::Streaming.get_data('http://code.jquery.com/jquery-1.9.1.js')
56
+ unlimited_response.length.should > 48.kilobytes
57
+
58
+ lambda {
59
+ Tripod::Streaming.get_data('http://code.jquery.com/jquery-1.9.1.js', :response_limit_bytes => 32.kilobytes)
60
+ }.should raise_error(Tripod::Errors::SparqlResponseTooLarge)
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ after do
67
+ WebMock.disable!
68
+ end
69
+
70
+ end
data/tripod.gemspec CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |gem|
19
19
  gem.rubyforge_project = "tripod"
20
20
 
21
21
  gem.add_dependency "rest-client"
22
- gem.add_dependency "activemodel", "~> 3.1"
22
+ gem.add_dependency "activemodel", "~> 3.2"
23
23
  gem.add_dependency "equivalent-xml"
24
24
  gem.add_dependency "rdf", "~> 1.0"
25
25
  gem.add_dependency "rdf-rdfxml"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tripod
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.5.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,11 +11,11 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2013-03-21 00:00:00.000000000 Z
14
+ date: 2013-03-26 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rest-client
18
- requirement: &70208187066620 !ruby/object:Gem::Requirement
18
+ requirement: &70308451617140 !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
21
21
  - - ! '>='
@@ -23,21 +23,21 @@ dependencies:
23
23
  version: '0'
24
24
  type: :runtime
25
25
  prerelease: false
26
- version_requirements: *70208187066620
26
+ version_requirements: *70308451617140
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activemodel
29
- requirement: &70208187061260 !ruby/object:Gem::Requirement
29
+ requirement: &70308451616420 !ruby/object:Gem::Requirement
30
30
  none: false
31
31
  requirements:
32
32
  - - ~>
33
33
  - !ruby/object:Gem::Version
34
- version: '3.1'
34
+ version: '3.2'
35
35
  type: :runtime
36
36
  prerelease: false
37
- version_requirements: *70208187061260
37
+ version_requirements: *70308451616420
38
38
  - !ruby/object:Gem::Dependency
39
39
  name: equivalent-xml
40
- requirement: &70208187091120 !ruby/object:Gem::Requirement
40
+ requirement: &70308451632020 !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
43
  - - ! '>='
@@ -45,10 +45,10 @@ dependencies:
45
45
  version: '0'
46
46
  type: :runtime
47
47
  prerelease: false
48
- version_requirements: *70208187091120
48
+ version_requirements: *70308451632020
49
49
  - !ruby/object:Gem::Dependency
50
50
  name: rdf
51
- requirement: &70208187100360 !ruby/object:Gem::Requirement
51
+ requirement: &70308451631020 !ruby/object:Gem::Requirement
52
52
  none: false
53
53
  requirements:
54
54
  - - ~>
@@ -56,10 +56,10 @@ dependencies:
56
56
  version: '1.0'
57
57
  type: :runtime
58
58
  prerelease: false
59
- version_requirements: *70208187100360
59
+ version_requirements: *70308451631020
60
60
  - !ruby/object:Gem::Dependency
61
61
  name: rdf-rdfxml
62
- requirement: &70208187094320 !ruby/object:Gem::Requirement
62
+ requirement: &70308451627060 !ruby/object:Gem::Requirement
63
63
  none: false
64
64
  requirements:
65
65
  - - ! '>='
@@ -67,10 +67,10 @@ dependencies:
67
67
  version: '0'
68
68
  type: :runtime
69
69
  prerelease: false
70
- version_requirements: *70208187094320
70
+ version_requirements: *70308451627060
71
71
  - !ruby/object:Gem::Dependency
72
72
  name: rdf-n3
73
- requirement: &70208186978440 !ruby/object:Gem::Requirement
73
+ requirement: &70308451625140 !ruby/object:Gem::Requirement
74
74
  none: false
75
75
  requirements:
76
76
  - - ! '>='
@@ -78,10 +78,10 @@ dependencies:
78
78
  version: '0'
79
79
  type: :runtime
80
80
  prerelease: false
81
- version_requirements: *70208186978440
81
+ version_requirements: *70308451625140
82
82
  - !ruby/object:Gem::Dependency
83
83
  name: rdf-json
84
- requirement: &70208186977380 !ruby/object:Gem::Requirement
84
+ requirement: &70308451624460 !ruby/object:Gem::Requirement
85
85
  none: false
86
86
  requirements:
87
87
  - - ! '>='
@@ -89,10 +89,10 @@ dependencies:
89
89
  version: '0'
90
90
  type: :runtime
91
91
  prerelease: false
92
- version_requirements: *70208186977380
92
+ version_requirements: *70308451624460
93
93
  - !ruby/object:Gem::Dependency
94
94
  name: json-ld
95
- requirement: &70208186975660 !ruby/object:Gem::Requirement
95
+ requirement: &70308451639760 !ruby/object:Gem::Requirement
96
96
  none: false
97
97
  requirements:
98
98
  - - ! '>='
@@ -100,10 +100,10 @@ dependencies:
100
100
  version: '0'
101
101
  type: :runtime
102
102
  prerelease: false
103
- version_requirements: *70208186975660
103
+ version_requirements: *70308451639760
104
104
  - !ruby/object:Gem::Dependency
105
105
  name: guid
106
- requirement: &70208186974980 !ruby/object:Gem::Requirement
106
+ requirement: &70308451637040 !ruby/object:Gem::Requirement
107
107
  none: false
108
108
  requirements:
109
109
  - - ! '>='
@@ -111,10 +111,10 @@ dependencies:
111
111
  version: '0'
112
112
  type: :runtime
113
113
  prerelease: false
114
- version_requirements: *70208186974980
114
+ version_requirements: *70308451637040
115
115
  - !ruby/object:Gem::Dependency
116
116
  name: dalli
117
- requirement: &70208186973620 !ruby/object:Gem::Requirement
117
+ requirement: &70308451634220 !ruby/object:Gem::Requirement
118
118
  none: false
119
119
  requirements:
120
120
  - - ~>
@@ -122,7 +122,7 @@ dependencies:
122
122
  version: '2.6'
123
123
  type: :runtime
124
124
  prerelease: false
125
- version_requirements: *70208186973620
125
+ version_requirements: *70308451634220
126
126
  description: RDF ruby ORM
127
127
  email:
128
128
  - ric@swirrl.com
@@ -152,6 +152,7 @@ files:
152
152
  - lib/tripod/errors/rdf_parse_failed.rb
153
153
  - lib/tripod/errors/rdf_type_not_set.rb
154
154
  - lib/tripod/errors/resource_not_found.rb
155
+ - lib/tripod/errors/sparql_response_too_large.rb
155
156
  - lib/tripod/errors/uri_not_set.rb
156
157
  - lib/tripod/errors/validations.rb
157
158
  - lib/tripod/extensions.rb
@@ -168,6 +169,7 @@ files:
168
169
  - lib/tripod/sparql_client.rb
169
170
  - lib/tripod/sparql_query.rb
170
171
  - lib/tripod/state.rb
172
+ - lib/tripod/streaming.rb
171
173
  - lib/tripod/version.rb
172
174
  - spec/app/models/person.rb
173
175
  - spec/app/models/resource.rb
@@ -186,6 +188,7 @@ files:
186
188
  - spec/tripod/sparql_client_spec.rb
187
189
  - spec/tripod/sparql_query_spec.rb
188
190
  - spec/tripod/state_spec.rb
191
+ - spec/tripod/streaming_spec.rb
189
192
  - tripod.gemspec
190
193
  homepage: http://github.com/Swirrl/tripod
191
194
  licenses: []
@@ -229,4 +232,5 @@ test_files:
229
232
  - spec/tripod/sparql_client_spec.rb
230
233
  - spec/tripod/sparql_query_spec.rb
231
234
  - spec/tripod/state_spec.rb
235
+ - spec/tripod/streaming_spec.rb
232
236
  has_rdoc: