ripple 0.6.1 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +61 -48
- data/lib/ripple.rb +5 -1
- data/lib/ripple/core_ext/casting.rb +3 -0
- data/lib/ripple/document.rb +6 -2
- data/lib/ripple/document/associations.rb +154 -0
- data/lib/ripple/document/{persistence/callbacks.rb → associations/embedded.rb} +20 -24
- data/lib/ripple/document/associations/instantiators.rb +41 -0
- data/lib/{riak/util/translation.rb → ripple/document/associations/linked.rb} +14 -11
- data/lib/ripple/document/associations/many.rb +52 -0
- data/lib/ripple/document/associations/many_embedded_proxy.rb +49 -0
- data/lib/{riak/i18n.rb → ripple/document/associations/one.rb} +18 -2
- data/lib/ripple/document/associations/one_embedded_proxy.rb +41 -0
- data/lib/ripple/document/associations/proxy.rb +125 -0
- data/lib/ripple/document/attribute_methods.rb +8 -1
- data/lib/ripple/document/attribute_methods/read.rb +4 -0
- data/lib/ripple/document/attribute_methods/write.rb +4 -0
- data/lib/ripple/document/bucket_access.rb +1 -1
- data/lib/ripple/document/callbacks.rb +75 -0
- data/lib/ripple/document/finders.rb +50 -3
- data/lib/ripple/document/persistence.rb +14 -6
- data/lib/ripple/document/validations.rb +35 -7
- data/lib/ripple/document/validations/associated_validator.rb +37 -0
- data/lib/ripple/embedded_document.rb +8 -2
- data/lib/{riak/map_reduce_error.rb → ripple/embedded_document/conversion.rb} +19 -5
- data/lib/{riak/invalid_response.rb → ripple/embedded_document/finders.rb} +17 -8
- data/lib/ripple/embedded_document/persistence.rb +75 -13
- data/lib/ripple/locale/en.yml +7 -1
- data/{spec/riak/net_http_backend_spec.rb → lib/ripple/railtie.rb} +17 -13
- data/spec/fixtures/config.yml +3 -0
- data/spec/integration/ripple/associations_spec.rb +81 -0
- data/spec/integration/ripple/persistence_spec.rb +54 -0
- data/spec/ripple/associations/many_embedded_proxy_spec.rb +124 -0
- data/spec/ripple/associations/one_embedded_proxy_spec.rb +130 -0
- data/spec/ripple/associations/proxy_spec.rb +78 -0
- data/spec/ripple/associations_spec.rb +111 -0
- data/spec/ripple/attribute_methods_spec.rb +37 -16
- data/spec/ripple/bucket_access_spec.rb +3 -14
- data/spec/ripple/callbacks_spec.rb +53 -9
- data/spec/ripple/document_spec.rb +22 -6
- data/spec/ripple/embedded_document/conversion_spec.rb +35 -0
- data/spec/{riak/headers_spec.rb → ripple/embedded_document/finders_spec.rb} +17 -14
- data/spec/ripple/embedded_document/persistence_spec.rb +86 -0
- data/spec/ripple/embedded_document_spec.rb +1 -26
- data/spec/ripple/finders_spec.rb +66 -30
- data/spec/ripple/persistence_spec.rb +33 -21
- data/spec/ripple/properties_spec.rb +1 -7
- data/spec/ripple/ripple_spec.rb +10 -0
- data/spec/ripple/timestamps_spec.rb +12 -19
- data/spec/ripple/validations_spec.rb +48 -6
- data/spec/spec_helper.rb +4 -10
- data/spec/support/associations/proxies.rb +16 -0
- data/spec/support/integration.rb +4 -0
- data/spec/support/mocks.rb +3 -0
- data/spec/support/models/address.rb +8 -0
- data/spec/support/models/box.rb +6 -0
- data/spec/support/models/cardboard_box.rb +3 -0
- data/spec/support/models/clock.rb +6 -0
- data/spec/support/models/customer.rb +4 -0
- data/spec/support/models/email.rb +4 -0
- data/spec/support/models/family.rb +14 -0
- data/spec/support/models/favorite.rb +4 -0
- data/spec/support/models/invoice.rb +6 -0
- data/spec/support/models/late_invoice.rb +3 -0
- data/spec/support/models/note.rb +4 -0
- data/spec/support/models/page.rb +4 -0
- data/spec/support/models/paid_invoice.rb +4 -0
- data/spec/support/models/tree.rb +3 -0
- data/spec/support/models/user.rb +6 -0
- data/spec/support/models/widget.rb +6 -0
- metadata +111 -138
- data/.document +0 -5
- data/.gitignore +0 -26
- data/CONTRIBUTORS.textile +0 -5
- data/LICENSE +0 -13
- data/README.textile +0 -128
- data/RELEASE_NOTES.textile +0 -68
- data/VERSION +0 -1
- data/lib/riak.rb +0 -46
- data/lib/riak/bucket.rb +0 -157
- data/lib/riak/client.rb +0 -139
- data/lib/riak/client/curb_backend.rb +0 -82
- data/lib/riak/client/http_backend.rb +0 -209
- data/lib/riak/client/net_http_backend.rb +0 -49
- data/lib/riak/failed_request.rb +0 -37
- data/lib/riak/link.rb +0 -73
- data/lib/riak/locale/en.yml +0 -37
- data/lib/riak/map_reduce.rb +0 -248
- data/lib/riak/robject.rb +0 -258
- data/lib/riak/util/escape.rb +0 -12
- data/lib/riak/util/fiber1.8.rb +0 -48
- data/lib/riak/util/headers.rb +0 -44
- data/lib/riak/util/multipart.rb +0 -52
- data/lib/riak/walk_spec.rb +0 -117
- data/ripple.gemspec +0 -169
- data/spec/fixtures/cat.jpg +0 -0
- data/spec/fixtures/multipart-blank.txt +0 -7
- data/spec/fixtures/multipart-with-body.txt +0 -16
- data/spec/riak/bucket_spec.rb +0 -230
- data/spec/riak/client_spec.rb +0 -174
- data/spec/riak/curb_backend_spec.rb +0 -50
- data/spec/riak/escape_spec.rb +0 -17
- data/spec/riak/http_backend_spec.rb +0 -131
- data/spec/riak/link_spec.rb +0 -82
- data/spec/riak/map_reduce_spec.rb +0 -352
- data/spec/riak/multipart_spec.rb +0 -36
- data/spec/riak/object_spec.rb +0 -532
- data/spec/riak/walk_spec_spec.rb +0 -208
- data/spec/spec.opts +0 -1
- data/spec/support/http_backend_implementation_examples.rb +0 -215
- data/spec/support/mock_server.rb +0 -58
data/lib/riak/client.rb
DELETED
@@ -1,139 +0,0 @@
|
|
1
|
-
# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
|
2
|
-
#
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
-
# you may not use this file except in compliance with the License.
|
5
|
-
# You may obtain a copy of the License at
|
6
|
-
#
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
-
#
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
-
# See the License for the specific language governing permissions and
|
13
|
-
# limitations under the License.
|
14
|
-
require 'riak'
|
15
|
-
|
16
|
-
module Riak
|
17
|
-
# A client connection to Riak.
|
18
|
-
class Client
|
19
|
-
include Util::Translation
|
20
|
-
include Util::Escape
|
21
|
-
|
22
|
-
autoload :HTTPBackend, "riak/client/http_backend"
|
23
|
-
autoload :NetHTTPBackend, "riak/client/net_http_backend"
|
24
|
-
autoload :CurbBackend, "riak/client/curb_backend"
|
25
|
-
|
26
|
-
# When using integer client IDs, the exclusive upper-bound of valid values.
|
27
|
-
MAX_CLIENT_ID = 4294967296
|
28
|
-
|
29
|
-
# Regexp for validating hostnames, lifted from uri.rb in Ruby 1.8.6
|
30
|
-
HOST_REGEX = /^(?:(?:(?:[a-zA-Z\d](?:[-a-zA-Z\d]*[a-zA-Z\d])?)\.)*(?:[a-zA-Z](?:[-a-zA-Z\d]*[a-zA-Z\d])?)\.?|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|\[(?:(?:[a-fA-F\d]{1,4}:)*(?:[a-fA-F\d]{1,4}|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})|(?:(?:[a-fA-F\d]{1,4}:)*[a-fA-F\d]{1,4})?::(?:(?:[a-fA-F\d]{1,4}:)*(?:[a-fA-F\d]{1,4}|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}))?)\])$/n
|
31
|
-
|
32
|
-
# @return [String] The host or IP address for the Riak endpoint
|
33
|
-
attr_reader :host
|
34
|
-
|
35
|
-
# @return [Fixnum] The port of the Riak HTTP endpoint
|
36
|
-
attr_reader :port
|
37
|
-
|
38
|
-
# @return [String] The internal client ID used by Riak to route responses
|
39
|
-
attr_reader :client_id
|
40
|
-
|
41
|
-
# @return [String] The URL path prefix to the "raw" HTTP endpoint
|
42
|
-
attr_accessor :prefix
|
43
|
-
|
44
|
-
# @return [String] The URL path to the map-reduce HTTP endpoint
|
45
|
-
attr_accessor :mapred
|
46
|
-
|
47
|
-
# Creates a client connection to Riak
|
48
|
-
# @param [Hash] options configuration options for the client
|
49
|
-
# @option options [String] :host ('127.0.0.1') The host or IP address for the Riak endpoint
|
50
|
-
# @option options [Fixnum] :port (8098) The port of the Riak HTTP endpoint
|
51
|
-
# @option options [String] :prefix ('/riak/') The URL path prefix to the main HTTP endpoint
|
52
|
-
# @option options [String] :mapred ('/mapred') The path to the map-reduce HTTP endpoint
|
53
|
-
# @option options [Fixnum, String] :client_id (rand(MAX_CLIENT_ID)) The internal client ID used by Riak to route responses
|
54
|
-
# @raise [ArgumentError] raised if any options are invalid
|
55
|
-
def initialize(options={})
|
56
|
-
options.assert_valid_keys(:host, :port, :prefix, :client_id, :mapred)
|
57
|
-
self.host = options[:host] || "127.0.0.1"
|
58
|
-
self.port = options[:port] || 8098
|
59
|
-
self.client_id = options[:client_id] || make_client_id
|
60
|
-
self.prefix = options[:prefix] || "/riak/"
|
61
|
-
self.mapred = options[:mapred] || "/mapred"
|
62
|
-
raise ArgumentError, t("missing_host_and_port") unless @host && @port
|
63
|
-
end
|
64
|
-
|
65
|
-
# Set the client ID for this client. Must be a string or Fixnum value 0 =< value < MAX_CLIENT_ID.
|
66
|
-
# @param [String, Fixnum] value The internal client ID used by Riak to route responses
|
67
|
-
# @raise [ArgumentError] when an invalid client ID is given
|
68
|
-
# @return [String] the assigned client ID
|
69
|
-
def client_id=(value)
|
70
|
-
@client_id = case value
|
71
|
-
when 0...MAX_CLIENT_ID
|
72
|
-
b64encode(value)
|
73
|
-
when String
|
74
|
-
value
|
75
|
-
else
|
76
|
-
raise ArgumentError, t("invalid_client_id", :max_id => MAX_CLIENT_ID)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
# Set the hostname of the Riak endpoint. Must be an IPv4, IPv6, or valid hostname
|
81
|
-
# @param [String] value The host or IP address for the Riak endpoint
|
82
|
-
# @raise [ArgumentError] if an invalid hostname is given
|
83
|
-
# @return [String] the assigned hostname
|
84
|
-
def host=(value)
|
85
|
-
raise ArgumentError, t("hostname_invalid") unless String === value && value.present? && value =~ HOST_REGEX
|
86
|
-
@host = value
|
87
|
-
end
|
88
|
-
|
89
|
-
# Set the port number of the Riak endpoint. This must be an integer between 0 and 65535.
|
90
|
-
# @param [Fixnum] value The port number of the Riak endpoint
|
91
|
-
# @raise [ArgumentError] if an invalid port number is given
|
92
|
-
# @return [Fixnum] the assigned port number
|
93
|
-
def port=(value)
|
94
|
-
raise ArgumentError, t("port_invalid") unless (0..65535).include?(value)
|
95
|
-
@port = value
|
96
|
-
end
|
97
|
-
|
98
|
-
# Automatically detects and returns an appropriate HTTP backend.
|
99
|
-
# The HTTP backend is used internally by the Riak client, but can also
|
100
|
-
# be used to access the server directly.
|
101
|
-
# @return [HTTPBackend] the HTTP backend for this client
|
102
|
-
def http
|
103
|
-
@http ||= begin
|
104
|
-
require 'curb'
|
105
|
-
CurbBackend.new(self)
|
106
|
-
rescue LoadError, NameError
|
107
|
-
warn t("install_curb")
|
108
|
-
NetHTTPBackend.new(self)
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
# Retrieves a bucket from Riak.
|
113
|
-
# @param [String] bucket the bucket to retrieve
|
114
|
-
# @param [Hash] options options for retrieving the bucket
|
115
|
-
# @option options [Boolean] :keys (true) whether to retrieve the bucket keys
|
116
|
-
# @option options [Boolean] :props (true) whether to retreive the bucket properties
|
117
|
-
# @return [Bucket] the requested bucket
|
118
|
-
def bucket(name, options={})
|
119
|
-
options.assert_valid_keys(:keys, :props)
|
120
|
-
response = http.get(200, prefix, escape(name), options, {})
|
121
|
-
Bucket.new(self, name).load(response)
|
122
|
-
end
|
123
|
-
alias :[] :bucket
|
124
|
-
|
125
|
-
# @return [String] A representation suitable for IRB and debugging output.
|
126
|
-
def inspect
|
127
|
-
"#<Riak::Client #{http.root_uri.to_s}>"
|
128
|
-
end
|
129
|
-
|
130
|
-
private
|
131
|
-
def make_client_id
|
132
|
-
b64encode(rand(MAX_CLIENT_ID))
|
133
|
-
end
|
134
|
-
|
135
|
-
def b64encode(n)
|
136
|
-
Base64.encode64([n].pack("N")).chomp
|
137
|
-
end
|
138
|
-
end
|
139
|
-
end
|
@@ -1,82 +0,0 @@
|
|
1
|
-
# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
|
2
|
-
#
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
-
# you may not use this file except in compliance with the License.
|
5
|
-
# You may obtain a copy of the License at
|
6
|
-
#
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
-
#
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
-
# See the License for the specific language governing permissions and
|
13
|
-
# limitations under the License.
|
14
|
-
require 'riak'
|
15
|
-
|
16
|
-
begin
|
17
|
-
require 'fiber'
|
18
|
-
rescue LoadError
|
19
|
-
require 'riak/util/fiber1.8'
|
20
|
-
end
|
21
|
-
|
22
|
-
module Riak
|
23
|
-
class Client
|
24
|
-
# An HTTP backend for Riak::Client that uses the 'curb' library/gem.
|
25
|
-
# If the 'curb' library is present, this backend will be preferred to
|
26
|
-
# the backend based on Net::HTTP.
|
27
|
-
# Conforms to the Riak::Client::HTTPBackend interface.
|
28
|
-
class CurbBackend < HTTPBackend
|
29
|
-
private
|
30
|
-
def perform(method, uri, headers, expect, data=nil)
|
31
|
-
# Setup
|
32
|
-
curl.headers = headers
|
33
|
-
curl.url = uri.to_s
|
34
|
-
response_headers.initialize_http_header(nil)
|
35
|
-
if block_given?
|
36
|
-
_curl = curl
|
37
|
-
Fiber.new {
|
38
|
-
f = Fiber.current
|
39
|
-
_curl.on_body {|chunk| f.resume(chunk); chunk.size }
|
40
|
-
loop do
|
41
|
-
yield Fiber.yield
|
42
|
-
end
|
43
|
-
}.resume
|
44
|
-
else
|
45
|
-
curl.on_body
|
46
|
-
end
|
47
|
-
# Perform
|
48
|
-
case method
|
49
|
-
when :put, :post
|
50
|
-
curl.send("http_#{method}", data)
|
51
|
-
else
|
52
|
-
curl.send("http_#{method}")
|
53
|
-
end
|
54
|
-
|
55
|
-
# Verify
|
56
|
-
if valid_response?(expect, curl.response_code)
|
57
|
-
result = { :headers => response_headers.to_hash, :code => curl.response_code.to_i }
|
58
|
-
if return_body?(method, curl.response_code, block_given?)
|
59
|
-
result[:body] = curl.body_str
|
60
|
-
end
|
61
|
-
result
|
62
|
-
else
|
63
|
-
raise FailedRequest.new(method, expect, curl.response_code, response_headers.to_hash, curl.body_str)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def curl
|
68
|
-
Thread.current[:curl_easy_handle] ||= Curl::Easy.new.tap do |c|
|
69
|
-
c.follow_location = false
|
70
|
-
c.on_header do |header_line|
|
71
|
-
response_headers.parse(header_line)
|
72
|
-
header_line.size
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
def response_headers
|
78
|
-
Thread.current[:response_headers] ||= Riak::Util::Headers.new
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
@@ -1,209 +0,0 @@
|
|
1
|
-
# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
|
2
|
-
#
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
-
# you may not use this file except in compliance with the License.
|
5
|
-
# You may obtain a copy of the License at
|
6
|
-
#
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
-
#
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
-
# See the License for the specific language governing permissions and
|
13
|
-
# limitations under the License.
|
14
|
-
require 'riak'
|
15
|
-
|
16
|
-
module Riak
|
17
|
-
class Client
|
18
|
-
class HTTPBackend
|
19
|
-
include Util::Translation
|
20
|
-
# The Riak::Client that uses this backend
|
21
|
-
attr_reader :client
|
22
|
-
|
23
|
-
# Create an HTTPBackend for the Riak::Client.
|
24
|
-
# @param [Client] client the client
|
25
|
-
def initialize(client)
|
26
|
-
raise ArgumentError, t("client_type", :client => client) unless Client === client
|
27
|
-
@client = client
|
28
|
-
end
|
29
|
-
|
30
|
-
# Default header hash sent with every request, based on settings in the client
|
31
|
-
# @return [Hash] headers that will be merged with user-specified headers on every request
|
32
|
-
def default_headers
|
33
|
-
{
|
34
|
-
"Accept" => "multipart/mixed, application/json;q=0.7, */*;q=0.5",
|
35
|
-
"X-Riak-ClientId" => @client.client_id
|
36
|
-
}
|
37
|
-
end
|
38
|
-
|
39
|
-
# Performs a HEAD request to the specified resource on the Riak server.
|
40
|
-
# @param [Fixnum, Array] expect the expected HTTP response code(s) from Riak
|
41
|
-
# @param [String, Array<String,Hash>] resource a relative path or array of path segments and optional query params Hash that will be joined to the root URI
|
42
|
-
# @overload head(expect, *resource)
|
43
|
-
# @overload head(expect, *resource, headers)
|
44
|
-
# Send the request with custom headers
|
45
|
-
# @param [Hash] headers custom headers to send with the request
|
46
|
-
# @return [Hash] response data, containing only the :headers and :code keys
|
47
|
-
# @raise [FailedRequest] if the response code doesn't match the expected response
|
48
|
-
def head(expect, *resource)
|
49
|
-
headers = default_headers.merge(resource.extract_options!)
|
50
|
-
verify_path!(resource)
|
51
|
-
perform(:head, path(*resource), headers, expect)
|
52
|
-
end
|
53
|
-
|
54
|
-
# Performs a GET request to the specified resource on the Riak server.
|
55
|
-
# @param [Fixnum, Array] expect the expected HTTP response code(s) from Riak
|
56
|
-
# @param [String, Array<String,Hash>] resource a relative path or array of path segments and optional query params Hash that will be joined to the root URI
|
57
|
-
# @overload get(expect, *resource)
|
58
|
-
# @overload get(expect, *resource, headers)
|
59
|
-
# Send the request with custom headers
|
60
|
-
# @param [Hash] headers custom headers to send with the request
|
61
|
-
# @overload get(expect, *resource, headers={})
|
62
|
-
# Stream the response body through the supplied block
|
63
|
-
# @param [Hash] headers custom headers to send with the request
|
64
|
-
# @yield [chunk] yields successive chunks of the response body as strings
|
65
|
-
# @return [Hash] response data, containing only the :headers and :code keys
|
66
|
-
# @return [Hash] response data, containing :headers, :body, and :code keys
|
67
|
-
# @raise [FailedRequest] if the response code doesn't match the expected response
|
68
|
-
def get(expect, *resource, &block)
|
69
|
-
headers = default_headers.merge(resource.extract_options!)
|
70
|
-
verify_path!(resource)
|
71
|
-
perform(:get, path(*resource), headers, expect, &block)
|
72
|
-
end
|
73
|
-
|
74
|
-
# Performs a PUT request to the specified resource on the Riak server.
|
75
|
-
# @param [Fixnum, Array] expect the expected HTTP response code(s) from Riak
|
76
|
-
# @param [String, Array<String,Hash>] resource a relative path or array of path segments and optional query params Hash that will be joined to the root URI
|
77
|
-
# @param [String] body the request body to send to the server
|
78
|
-
# @overload put(expect, *resource, body)
|
79
|
-
# @overload put(expect, *resource, body, headers)
|
80
|
-
# Send the request with custom headers
|
81
|
-
# @param [Hash] headers custom headers to send with the request
|
82
|
-
# @overload put(expect, *resource, body, headers={})
|
83
|
-
# Stream the response body through the supplied block
|
84
|
-
# @param [Hash] headers custom headers to send with the request
|
85
|
-
# @yield [chunk] yields successive chunks of the response body as strings
|
86
|
-
# @return [Hash] response data, containing only the :headers and :code keys
|
87
|
-
# @return [Hash] response data, containing :headers, :code, and :body keys
|
88
|
-
# @raise [FailedRequest] if the response code doesn't match the expected response
|
89
|
-
def put(expect, *resource, &block)
|
90
|
-
headers = default_headers.merge(resource.extract_options!)
|
91
|
-
uri, data = verify_path_and_body!(resource)
|
92
|
-
perform(:put, path(*uri), headers, expect, data, &block)
|
93
|
-
end
|
94
|
-
|
95
|
-
# Performs a POST request to the specified resource on the Riak server.
|
96
|
-
# @param [Fixnum, Array] expect the expected HTTP response code(s) from Riak
|
97
|
-
# @param [String, Array<String>] resource a relative path or array of path segments that will be joined to the root URI
|
98
|
-
# @param [String] body the request body to send to the server
|
99
|
-
# @overload post(expect, *resource, body)
|
100
|
-
# @overload post(expect, *resource, body, headers)
|
101
|
-
# Send the request with custom headers
|
102
|
-
# @param [Hash] headers custom headers to send with the request
|
103
|
-
# @overload post(expect, *resource, body, headers={})
|
104
|
-
# Stream the response body through the supplied block
|
105
|
-
# @param [Hash] headers custom headers to send with the request
|
106
|
-
# @yield [chunk] yields successive chunks of the response body as strings
|
107
|
-
# @return [Hash] response data, containing only the :headers and :code keys
|
108
|
-
# @return [Hash] response data, containing :headers, :code and :body keys
|
109
|
-
# @raise [FailedRequest] if the response code doesn't match the expected response
|
110
|
-
def post(expect, *resource, &block)
|
111
|
-
headers = default_headers.merge(resource.extract_options!)
|
112
|
-
uri, data = verify_path_and_body!(resource)
|
113
|
-
perform(:post, path(*uri), headers, expect, data, &block)
|
114
|
-
end
|
115
|
-
|
116
|
-
# Performs a DELETE request to the specified resource on the Riak server.
|
117
|
-
# @param [Fixnum, Array] expect the expected HTTP response code(s) from Riak
|
118
|
-
# @param [String, Array<String,Hash>] resource a relative path or array of path segments and optional query params Hash that will be joined to the root URI
|
119
|
-
# @overload delete(expect, *resource)
|
120
|
-
# @overload delete(expect, *resource, headers)
|
121
|
-
# Send the request with custom headers
|
122
|
-
# @param [Hash] headers custom headers to send with the request
|
123
|
-
# @overload delete(expect, *resource, headers={})
|
124
|
-
# Stream the response body through the supplied block
|
125
|
-
# @param [Hash] headers custom headers to send with the request
|
126
|
-
# @yield [chunk] yields successive chunks of the response body as strings
|
127
|
-
# @return [Hash] response data, containing only the :headers and :code keys
|
128
|
-
# @return [Hash] response data, containing :headers, :code and :body keys
|
129
|
-
# @raise [FailedRequest] if the response code doesn't match the expected response
|
130
|
-
def delete(expect, *resource, &block)
|
131
|
-
headers = default_headers.merge(resource.extract_options!)
|
132
|
-
verify_path!(resource)
|
133
|
-
perform(:delete, path(*resource), headers, expect, &block)
|
134
|
-
end
|
135
|
-
|
136
|
-
# @return [URI] The calculated root URI for the Riak HTTP endpoint
|
137
|
-
def root_uri
|
138
|
-
URI.parse("http://#{@client.host}:#{@client.port}")
|
139
|
-
end
|
140
|
-
|
141
|
-
# Calculates an absolute URI from a relative path specification
|
142
|
-
# @param [Array<String,Hash>] segments a relative path or sequence of path segments and optional query params Hash that will be joined to the root URI
|
143
|
-
# @return [URI] an absolute URI for the resource
|
144
|
-
def path(*segments)
|
145
|
-
query = segments.extract_options!.to_param
|
146
|
-
root_uri.merge(segments.join("/").gsub(/\/+/, "/").sub(/^\//, '')).tap do |uri|
|
147
|
-
uri.query = query if query.present?
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
# Verifies that both a resource path and body are present in the arguments
|
152
|
-
# @param [Array] args the arguments to verify
|
153
|
-
# @raise [ArgumentError] if the body or resource is missing, or if the body is not a String
|
154
|
-
def verify_path_and_body!(args)
|
155
|
-
body = args.pop
|
156
|
-
begin
|
157
|
-
verify_path!(args)
|
158
|
-
rescue ArgumentError
|
159
|
-
raise ArgumentError, t("path_and_body_required")
|
160
|
-
end
|
161
|
-
|
162
|
-
raise ArgumentError, t("request_body_type") unless String === body || IO === body
|
163
|
-
[args, body]
|
164
|
-
end
|
165
|
-
|
166
|
-
# Verifies that the specified resource is valid
|
167
|
-
# @param [String, Array] resource the resource specification
|
168
|
-
# @raise [ArgumentError] if the resource path is too short
|
169
|
-
def verify_path!(resource)
|
170
|
-
resource = Array(resource).flatten
|
171
|
-
raise ArgumentError, t("resource_path_short") unless resource.length > 1 || resource.include?(@client.mapred)
|
172
|
-
end
|
173
|
-
|
174
|
-
# Checks the expected response codes against the actual response code. Use internally when
|
175
|
-
# implementing {#perform}.
|
176
|
-
# @param [String, Fixnum, Array<String,Fixnum>] expected the expected response code(s)
|
177
|
-
# @param [String, Fixnum] actual the received response code
|
178
|
-
# @return [Boolean] whether the actual response code is acceptable given the expectations
|
179
|
-
def valid_response?(expected, actual)
|
180
|
-
Array(expected).map(&:to_i).include?(actual.to_i)
|
181
|
-
end
|
182
|
-
|
183
|
-
# Checks whether a combination of the HTTP method, response code, and block should
|
184
|
-
# result in returning the :body in the response hash. Use internally when implementing {#perform}.
|
185
|
-
# @param [Symbol] method the HTTP method
|
186
|
-
# @param [String, Fixnum] code the received response code
|
187
|
-
# @param [Boolean] has_block whether a streaming block was passed to {#perform}. Pass block_given? to this parameter.
|
188
|
-
# @return [Boolean] whether to return the body in the response hash
|
189
|
-
def return_body?(method, code, has_block)
|
190
|
-
method != :head && !valid_response?([204,205,304], code) && !has_block
|
191
|
-
end
|
192
|
-
|
193
|
-
# Executes requests according to the underlying HTTP client library semantics.
|
194
|
-
# @abstract Subclasses must implement this internal method to perform HTTP requests
|
195
|
-
# according to the API of their HTTP libraries.
|
196
|
-
# @param [Symbol] method one of :head, :get, :post, :put, :delete
|
197
|
-
# @param [URI] uri the HTTP URI to request
|
198
|
-
# @param [Hash] headers headers to send along with the request
|
199
|
-
# @param [Fixnum, Array] expect the expected response code(s)
|
200
|
-
# @param [String, IO] body the PUT or POST request body
|
201
|
-
# @return [Hash] response data, containing :headers, :code and :body keys. Only :headers and :code should be present when the body is streamed or the method is :head.
|
202
|
-
# @yield [chunk] if the method is not :head, successive chunks of the response body will be yielded as strings
|
203
|
-
# @raise [NotImplementedError] if a subclass does not implement this method
|
204
|
-
def perform(method, uri, headers, expect, body=nil)
|
205
|
-
raise NotImplementedError
|
206
|
-
end
|
207
|
-
end
|
208
|
-
end
|
209
|
-
end
|
@@ -1,49 +0,0 @@
|
|
1
|
-
# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
|
2
|
-
#
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
-
# you may not use this file except in compliance with the License.
|
5
|
-
# You may obtain a copy of the License at
|
6
|
-
#
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
-
#
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
-
# See the License for the specific language governing permissions and
|
13
|
-
# limitations under the License.
|
14
|
-
require 'riak'
|
15
|
-
|
16
|
-
module Riak
|
17
|
-
class Client
|
18
|
-
# Uses the Ruby standard library Net::HTTP to connect to Riak.
|
19
|
-
# We recommend using the CurbBackend, which will
|
20
|
-
# be preferred when the 'curb' library is available.
|
21
|
-
# Conforms to the Riak::Client::HTTPBackend interface.
|
22
|
-
class NetHTTPBackend < HTTPBackend
|
23
|
-
private
|
24
|
-
def perform(method, uri, headers, expect, data=nil) #:nodoc:
|
25
|
-
Net::HTTP.start(uri.host, uri.port) do |http|
|
26
|
-
request = Net::HTTP.const_get(method.to_s.camelize).new(uri.request_uri, headers)
|
27
|
-
case data
|
28
|
-
when String
|
29
|
-
request.body = data
|
30
|
-
when IO
|
31
|
-
request.body_stream = data
|
32
|
-
end
|
33
|
-
response = http.request(request)
|
34
|
-
|
35
|
-
if valid_response?(expect, response.code)
|
36
|
-
result = {:headers => response.to_hash, :code => response.code.to_i}
|
37
|
-
response.read_body {|chunk| yield chunk } if block_given?
|
38
|
-
if return_body?(method, response.code, block_given?)
|
39
|
-
result[:body] = response.body
|
40
|
-
end
|
41
|
-
result
|
42
|
-
else
|
43
|
-
raise FailedRequest.new(method, expect, response.code, response.to_hash, response.body)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|