Class: Riak::Client::BeefcakeProtobuffsBackend

Inherits:
ProtobuffsBackend show all
Includes:
ObjectMethods
Defined in:
lib/riak/client/beefcake/messages.rb,
lib/riak/client/beefcake/socket.rb,
lib/riak/client/beefcake/operator.rb,
lib/riak/client/beefcake/protocol.rb,
lib/riak/client/beefcake/crdt_loader.rb,
lib/riak/client/beefcake/ts_cell_codec.rb,
lib/riak/client/beefcake/crdt_operator.rb,
lib/riak/client/beefcake/object_methods.rb,
lib/riak/client/beefcake/message_overlay.rb,
lib/riak/client/beefcake/crdt/set_loader.rb,
lib/riak/client/beefcake/crdt/map_loader.rb,
lib/riak/client/beefcake_protobuffs_backend.rb,
lib/riak/client/beefcake/crdt/counter_loader.rb,
lib/riak/client/beefcake/time_series_get_operator.rb,
lib/riak/client/beefcake/time_series_put_operator.rb,
lib/riak/client/beefcake/time_series_list_operator.rb,
lib/riak/client/beefcake/bucket_properties_operator.rb,
lib/riak/client/beefcake/time_series_query_operator.rb,
lib/riak/client/beefcake/time_series_delete_operator.rb

Defined Under Namespace

Modules: ObjectMethods, TsColumnType Classes: BeefcakeSocket, BucketPropertiesOperator, CounterOp, CrdtLoader, CrdtOperator, DtFetchReq, DtFetchResp, DtOp, DtUpdateReq, DtUpdateResp, DtValue, MapEntry, MapField, MapOp, MapUpdate, Operator, Protocol, RpbAuthReq, RpbBucketKeyPreflistItem, RpbBucketProps, RpbCSBucketReq, RpbCSBucketResp, RpbCommitHook, RpbContent, RpbCounterGetReq, RpbCounterGetResp, RpbCounterUpdateReq, RpbCounterUpdateResp, RpbCoverageEntry, RpbCoverageReq, RpbCoverageResp, RpbDelReq, RpbErrorResp, RpbGetBucketKeyPreflistReq, RpbGetBucketKeyPreflistResp, RpbGetBucketReq, RpbGetBucketResp, RpbGetBucketTypeReq, RpbGetClientIdResp, RpbGetReq, RpbGetResp, RpbGetServerInfoResp, RpbIndexBodyResp, RpbIndexObject, RpbIndexReq, RpbIndexResp, RpbLink, RpbListBucketsReq, RpbListBucketsResp, RpbListKeysReq, RpbListKeysResp, RpbMapRedReq, RpbMapRedResp, RpbModFun, RpbPair, RpbPutReq, RpbPutResp, RpbResetBucketReq, RpbSearchDoc, RpbSearchQueryReq, RpbSearchQueryResp, RpbSetBucketReq, RpbSetBucketTypeReq, RpbSetClientIdReq, RpbYokozunaIndex, RpbYokozunaIndexDeleteReq, RpbYokozunaIndexGetReq, RpbYokozunaIndexGetResp, RpbYokozunaIndexPutReq, RpbYokozunaSchema, RpbYokozunaSchemaGetReq, RpbYokozunaSchemaGetResp, RpbYokozunaSchemaPutReq, SetOp, TimeSeriesDeleteOperator, TimeSeriesGetOperator, TimeSeriesListOperator, TimeSeriesPutOperator, TimeSeriesQueryOperator, TsCell, TsCellCodec, TsColumnDescription, TsDelReq, TsDelResp, TsGetReq, TsGetResp, TsInterpolation, TsListKeysReq, TsListKeysResp, TsPutReq, TsPutResp, TsQueryReq, TsQueryResp, TsRow

Constant Summary

Constants included from ObjectMethods

ObjectMethods::ENCODING

Constants inherited from ProtobuffsBackend

ProtobuffsBackend::MESSAGE_CODES, ProtobuffsBackend::QUORUMS, ProtobuffsBackend::UINTMAX

Constants included from FeatureDetection

FeatureDetection::VERSION

Instance Attribute Summary

Attributes inherited from ProtobuffsBackend

#client, #node

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ObjectMethods

#dump_object, #load_object

Methods inherited from ProtobuffsBackend

#initialize, simple, #socket, #teardown

Methods included from FeatureDetection

#get_server_version, #http_props_clearable?, #index_pagination?, #index_return_terms?, #index_streaming?, #key_object_bucket_timeouts?, #mapred_phaseless?, #pb_conditionals?, #pb_head?, #pb_indexes?, #pb_search?, #quorum_controls?, #server_version, #tombstone_vclocks?

Methods included from Util::Escape

#escape, #maybe_escape, #maybe_unescape, #unescape

Methods included from Util::Translation

#i18n_scope, #t

Constructor Details

This class inherits a constructor from Riak::Client::ProtobuffsBackend

Class Method Details

.configured?Boolean



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/riak/client/beefcake_protobuffs_backend.rb', line 10

def self.configured?
  begin
    require 'beefcake'
    require 'riak/client/beefcake/messages'
    require 'riak/client/beefcake/message_overlay'
    require 'riak/client/beefcake/object_methods'
    require 'riak/client/beefcake/bucket_properties_operator'
    require 'riak/client/beefcake/crdt_operator'
    require 'riak/client/beefcake/crdt_loader'
    require 'riak/client/beefcake/time_series_delete_operator'
    require 'riak/client/beefcake/time_series_get_operator'
    require 'riak/client/beefcake/time_series_list_operator'
    require 'riak/client/beefcake/time_series_put_operator'
    require 'riak/client/beefcake/time_series_query_operator'
    require 'riak/client/beefcake/protocol'
    require 'riak/client/beefcake/socket'
    true
  rescue LoadError, NameError => e
    # put exception into a variable for debugging
    false
  end
end

Instance Method Details

#beefcakeObject

Generated from riak_ts.proto



8
# File 'lib/riak/client/beefcake/messages.rb', line 8

require "beefcake"

#bucket_properties_operatorObject



2
3
4
# File 'lib/riak/client/beefcake/bucket_properties_operator.rb', line 2

def bucket_properties_operator
  BucketPropertiesOperator.new(self)
end

#crdt_loaderObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new CrdtLoader for deserializing a protobuffs response full of CRDTs.



12
13
14
# File 'lib/riak/client/beefcake/crdt_loader.rb', line 12

def crdt_loader
  return CrdtLoader.new self
end

#crdt_operatorObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new CrdtOperator for serializing CRDT operations into protobuffs and sending them to a Riak cluster.



10
11
12
# File 'lib/riak/client/beefcake/crdt_operator.rb', line 10

def crdt_operator
  return CrdtOperator.new self
end

#create_search_index(name, schema = nil, n_val = nil, timeout = nil) ⇒ Object



380
381
382
383
384
385
386
387
388
# File 'lib/riak/client/beefcake_protobuffs_backend.rb', line 380

def create_search_index(name, schema = nil, n_val = nil, timeout = nil)
  index = RpbYokozunaIndex.new(name: name, schema: schema, n_val: n_val)
  req = RpbYokozunaIndexPutReq.new(index: index, timeout: timeout)

  protocol do |p|
    p.write :YokozunaIndexPutReq, req
    p.expect :PutResp
  end
end

#create_search_schema(name, content) ⇒ Object



417
418
419
420
421
422
423
424
425
426
# File 'lib/riak/client/beefcake_protobuffs_backend.rb', line 417

def create_search_schema(name, content)
  schema = RpbYokozunaSchema.new(:name => name, :content => content)
  req = RpbYokozunaSchemaPutReq.new(:schema => schema)

  protocol do |p|
    p.write :YokozunaSchemaPutReq, req
    p.expect :PutResp
  end
  true
end

#delete_object(bucket, key, options = {}) ⇒ Object



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/riak/client/beefcake_protobuffs_backend.rb', line 153

def delete_object(bucket, key, options = {})
  if bucket.is_a? Bucket
    options[:type] = bucket.type.name if bucket.needs_type?
    bucket = bucket.name
  end
  options = normalize_quorums(options)
  options[:bucket] = maybe_encode(bucket)
  options[:key] = maybe_encode(key)
  options[:vclock] = Base64.decode64(options[:vclock]) if options[:vclock]
  req = RpbDelReq.new(prune_unsupported_options(:DelReq, options))

  protocol do |p|
    p.write :DelReq, req
    p.expect :DelResp
  end

  return true
end

#delete_search_index(name) ⇒ Object



408
409
410
411
412
413
414
415
# File 'lib/riak/client/beefcake_protobuffs_backend.rb', line 408

def delete_search_index(name)
  req = RpbYokozunaIndexDeleteReq.new(:name => name)
  protocol do |p|
    p.write :YokozunaIndexDeleteReq, req
    p.expect :DelResp
  end
  true
end

#fetch_object(bucket, key, options = {}) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/riak/client/beefcake_protobuffs_backend.rb', line 89

def fetch_object(bucket, key, options = {})
  options = prune_unsupported_options(:GetReq, normalize_quorums(options))
  bucket = Bucket === bucket ? bucket.name : bucket
  req = RpbGetReq.new(options.merge(:bucket => maybe_encode(bucket), :key => maybe_encode(key)))

  resp = protocol do |p|
    p.write :GetReq, req
    p.expect :GetResp, RpbGetResp, empty_body_acceptable: true
  end

  if :empty == resp
    raise Riak::ProtobuffsFailedRequest.new(:not_found, t('not_found'))
  end

  template = RObject.new(client.bucket(bucket), key)
  load_object(resp, template)
end

#get_bucket_props(bucket, options = { }) ⇒ Object



236
237
238
# File 'lib/riak/client/beefcake_protobuffs_backend.rb', line 236

def get_bucket_props(bucket, options = {  })
  bucket_properties_operator.get bucket, options
end

#get_bucket_type_props(bucket_type) ⇒ Object



255
256
257
258
259
260
261
262
263
264
265
# File 'lib/riak/client/beefcake_protobuffs_backend.rb', line 255

def get_bucket_type_props(bucket_type)
  bucket_type = bucket_type.name if bucket_type.is_a? BucketType
  req = RpbGetBucketTypeReq.new type: bucket_type

  resp = protocol do |p|
    p.write :GetBucketTypeReq, req
    p.expect(:GetBucketResp, RpbGetBucketResp)
  end

  resp.props.to_hash
end

#get_client_idObject



58
59
60
61
62
63
# File 'lib/riak/client/beefcake_protobuffs_backend.rb', line 58

def get_client_id
  protocol do |p|
    p.write :GetClientIdReq
    p.expect(:GetClientIdResp, RpbGetClientIdResp).client_id
  end
end

#get_counter(bucket, key, options = {}) ⇒ Object



193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/riak/client/beefcake_protobuffs_backend.rb', line 193

def get_counter(bucket, key, options = {})
  bucket = bucket.name if bucket.is_a? Bucket

  options = normalize_quorums(options)
  options[:bucket] = bucket
  options[:key] = key

  request = RpbCounterGetReq.new options

  resp = protocol do |p|
    p.write :CounterGetReq, request
    p.expect :CounterGetResp, RpbCounterGetResp, empty_body_acceptable: true
  end

  if :empty == resp
    return 0
  end

  return resp.value || 0
end

#get_index(bucket, index, query, query_options = {}, &block) ⇒ Object



333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
# File 'lib/riak/client/beefcake_protobuffs_backend.rb', line 333

def get_index(bucket, index, query, query_options = {}, &block)
  return super unless pb_indexes?
  bucket = bucket.name if Bucket === bucket
  if Range === query
    options = {
      :qtype => RpbIndexReq::IndexQueryType::RANGE,
      :range_min => query.begin.to_s,
      :range_max => query.end.to_s
    }
  else
    options = {
      :qtype => RpbIndexReq::IndexQueryType::EQ,
      :key => query.to_s
    }
  end

  options.merge!(:bucket => bucket, :index => index.to_s)
  options.merge!(query_options)
  options[:stream] = block_given?

  req = RpbIndexReq.new(options)

  protocol do |p|
    p.write :IndexReq, req
    decode_index_response(p, &block)
  end
end

#get_preflist(bucket, key, type = nil, options = {}) ⇒ Object



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/riak/client/beefcake_protobuffs_backend.rb', line 172

def get_preflist(bucket, key, type = nil, options = {})
  if type.nil? && bucket.is_a?(Riak::BucketTyped::Bucket)
    type = bucket.type.name
  end
  bucket = bucket.name if bucket.is_a? Bucket
  type = type.name if type.is_a? BucketType

  message = RpbGetBucketKeyPreflistReq.new(
    bucket: bucket,
    key: key,
    type: type
  )

  resp = protocol do |p|
    p.write :GetBucketKeyPreflistReq, message
    p.expect :GetBucketKeyPreflistResp, RpbGetBucketKeyPreflistResp
  end

  resp.preflist
end

#get_search_index(name) ⇒ Object



390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
# File 'lib/riak/client/beefcake_protobuffs_backend.rb', line 390

def get_search_index(name)
  req = RpbYokozunaIndexGetReq.new(:name => name)
  begin
    resp = protocol do |p|
      p.write :YokozunaIndexGetReq, req
      p.expect :YokozunaIndexGetResp, RpbYokozunaIndexGetResp, empty_body_acceptable: true
    end
  rescue ProtobuffsErrorResponse => e
    if e.code == 0 && e.original_message =~ /notfound/
      raise Riak::ProtobuffsFailedRequest.new(:not_found, t('not_found'))
    end

    raise e
  end

  resp
end

#get_search_schema(name) ⇒ Object



428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
# File 'lib/riak/client/beefcake_protobuffs_backend.rb', line 428

def get_search_schema(name)
  req = RpbYokozunaSchemaGetReq.new(:name => name)

  begin
    resp = protocol do |p|
      p.write :YokozunaSchemaGetReq, req
      p.expect :YokozunaSchemaGetResp, RpbYokozunaSchemaGetResp
    end
  rescue ProtobuffsErrorResponse => e
    if e.code == 0 && e.original_message =~ /notfound/
      raise Riak::ProtobuffsFailedRequest.new(:not_found, t('not_found'))
    end

    raise e
  end

  resp.schema ? resp.schema : resp
end

#list_buckets(options = {}, &blk) ⇒ Object

override the simple list_buckets



292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
# File 'lib/riak/client/beefcake_protobuffs_backend.rb', line 292

def list_buckets(options = {}, &blk)
  if block_given?
    return streaming_list_buckets options, &blk
  end

  raise t("streaming_bucket_list_without_block") if options[:stream]

  request = RpbListBucketsReq.new options

  resp = protocol do |p|
    p.write :ListBucketsReq, request

    p.expect :ListBucketsResp, RpbListBucketsResp, empty_body_acceptable: true
  end

  return [] if :empty == resp

  resp.buckets
end

#list_keys(bucket, options = {}, &block) ⇒ Object



267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
# File 'lib/riak/client/beefcake_protobuffs_backend.rb', line 267

def list_keys(bucket, options = {}, &block)
  bucket = bucket.name if Bucket === bucket
  req = RpbListKeysReq.new(options.merge(:bucket => maybe_encode(bucket)))

  keys = []

  protocol do |p|
    p.write :ListKeysReq, req

    while msg = p.expect(:ListKeysResp, RpbListKeysResp)
      break if msg.done
      if block_given?
        yield msg.keys
      else
        keys += msg.keys
      end
    end
  end

  return keys unless block_given?

  return true
end

#mapred(mr, &block) ⇒ Object

Raises:



312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
# File 'lib/riak/client/beefcake_protobuffs_backend.rb', line 312

def mapred(mr, &block)
  raise MapReduceError.new(t("empty_map_reduce_query")) if mr.query.empty? && !mapred_phaseless?
  req = RpbMapRedReq.new(:request => mr.to_json, :content_type => "application/json")

  results = MapReduce::Results.new(mr)

  protocol do |p|
    p.write :MapRedReq, req
    while msg = p.expect(:MapRedResp, RpbMapRedResp)
      break if msg.done
      if block_given?
        yield msg.phase, JSON.parse(msg.response)
      else
        results.add msg.phase, JSON.parse(msg.response)
      end
    end
  end

  block_given? || results.report
end

#new_socketObject



47
48
49
# File 'lib/riak/client/beefcake_protobuffs_backend.rb', line 47

def new_socket
  BeefcakeSocket.new @node.host, @node.pb_port, authentication: client.authentication
end

#pingObject



51
52
53
54
55
56
# File 'lib/riak/client/beefcake_protobuffs_backend.rb', line 51

def ping
  protocol do |p|
    p.write :PingReq
    p.expect :PingResp
  end
end

#post_counter(bucket, key, amount, options = {}) ⇒ Object



214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/riak/client/beefcake_protobuffs_backend.rb', line 214

def post_counter(bucket, key, amount, options = {})
  bucket = bucket.name if bucket.is_a? Bucket

  options = normalize_quorums(options)
  options[:bucket] = bucket
  options[:key] = key
  # TODO: raise if amount doesn't fit in sint64
  options[:amount] = amount
  options[:returnvalue] = options[:returnvalue] || options[:return_value]

  request = RpbCounterUpdateReq.new options

  resp = protocol do |p|
    p.write :CounterUpdateReq, request
    p.expect :CounterUpdateResp, RpbCounterUpdateResp, empty_body_acceptable: true
  end

  return nil if :empty == resp

  return resp.value
end

#protocolObject



33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/riak/client/beefcake_protobuffs_backend.rb', line 33

def protocol
  p = Protocol.new socket
  in_request = false
  result = nil
  begin
    in_request = true
    result = yield p
    in_request = false
  ensure
    reset_socket if in_request
  end
  return result
end

#reload_object(robject, options = {}) ⇒ Object



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/riak/client/beefcake_protobuffs_backend.rb', line 107

def reload_object(robject, options = {})
  options = normalize_quorums(options)
  options[:bucket] = maybe_encode(robject.bucket.name)
  options[:type] = maybe_encode(robject.bucket.type.name) if robject.bucket.needs_type?
  options[:key] = maybe_encode(robject.key)
  options[:if_modified] = maybe_encode Base64.decode64(robject.vclock) if robject.vclock
  req = RpbGetReq.new(prune_unsupported_options(:GetReq, options))

  resp = protocol do |p|
    p.write :GetReq, req
    p.expect :GetResp, RpbGetResp, empty_body_acceptable: true
  end

  if :empty == resp
    raise Riak::ProtobuffsFailedRequest.new(:not_found, t('not_found'))
  end

  load_object(resp, robject)
end

#reset_bucket_props(bucket, options) ⇒ Object



244
245
246
247
248
249
250
251
252
253
# File 'lib/riak/client/beefcake_protobuffs_backend.rb', line 244

def reset_bucket_props(bucket, options)
  bucket = bucket.name if Bucket === bucket
  req = RpbResetBucketReq.new(bucket: maybe_encode(bucket),
                              type: options[:type])

  protocol do |p|
    p.write :ResetBucketReq, req
    p.expect :ResetBucketResp
  end
end

#search(index, query, options = {}) ⇒ Object



361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
# File 'lib/riak/client/beefcake_protobuffs_backend.rb', line 361

def search(index, query, options = {})
  return super unless pb_search?
  options = options.symbolize_keys
  options[:op] = options.delete(:'q.op') if options[:'q.op']
  req = RpbSearchQueryReq.new(options.merge(:index => index || 'search', :q => query))

  resp = protocol do |p|
    p.write :SearchQueryReq, req
    p.expect :SearchQueryResp, RpbSearchQueryResp
  end

  resp.docs = [] if resp.docs.nil?

  ret = { 'max_score' => resp.max_score, 'num_found' => resp.num_found }
  ret['docs'] = resp.docs.map { |d| decode_doc d }

  return ret
end

#server_infoObject



65
66
67
68
69
70
71
72
# File 'lib/riak/client/beefcake_protobuffs_backend.rb', line 65

def server_info
  resp = protocol do |p|
    p.write :GetServerInfoReq
    p.expect(:GetServerInfoResp, RpbGetServerInfoResp)
  end

  { node: resp.node, server_version: resp.server_version }
end

#set_bucket_props(bucket, props, type = nil) ⇒ Object



240
241
242
# File 'lib/riak/client/beefcake_protobuffs_backend.rb', line 240

def set_bucket_props(bucket, props, type = nil)
  bucket_properties_operator.put bucket, props, type: type
end

#set_client_id(id) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/riak/client/beefcake_protobuffs_backend.rb', line 74

def set_client_id(id)
  value = case id
          when Integer
            [id].pack("N")
          else
            id.to_s
          end
  req = RpbSetClientIdReq.new(:client_id => value)
  protocol do |p|
    p.write :SetClientIdReq, req
    p.expect :SetClientIdResp
  end
  return true
end

#store_object(robject, options = {}) ⇒ Object



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/riak/client/beefcake_protobuffs_backend.rb', line 127

def store_object(robject, options = {})
  options[:return_body] ||= options[:returnbody]
  options = normalize_quorums(options)
  if robject.prevent_stale_writes
    unless pb_conditionals?
      other = fetch_object(robject.bucket, robject.key)
      raise Riak::ProtobuffsFailedRequest.new(:stale_object, t("stale_write_prevented")) unless other.vclock == robject.vclock
    end
    if robject.vclock
      options[:if_not_modified] = true
    else
      options[:if_none_match] = true
    end
  end
  req = dump_object(robject, prune_unsupported_options(:PutReq, options))

  resp = protocol do |p|
    p.write(:PutReq, req)
    p.expect :PutResp, RpbPutResp, empty_body_acceptable: true
  end

  return true if :empty == resp

  load_object resp, robject
end

#time_series_delete_operatorObject



5
6
7
# File 'lib/riak/client/beefcake/time_series_delete_operator.rb', line 5

def time_series_delete_operator
  TimeSeriesDeleteOperator.new(self)
end

#time_series_get_operatorObject



5
6
7
# File 'lib/riak/client/beefcake/time_series_get_operator.rb', line 5

def time_series_get_operator
  TimeSeriesGetOperator.new(self)
end

#time_series_list_operatorObject



5
6
7
# File 'lib/riak/client/beefcake/time_series_list_operator.rb', line 5

def time_series_list_operator
  TimeSeriesListOperator.new(self)
end

#time_series_put_operatorObject



5
6
7
# File 'lib/riak/client/beefcake/time_series_put_operator.rb', line 5

def time_series_put_operator
  TimeSeriesPutOperator.new(self)
end

#time_series_query_operatorObject



5
6
7
# File 'lib/riak/client/beefcake/time_series_query_operator.rb', line 5

def time_series_query_operator
  TimeSeriesQueryOperator.new(self)
end

#write_protobuff(code, message) ⇒ Object



447
448
449
450
451
# File 'lib/riak/client/beefcake_protobuffs_backend.rb', line 447

def write_protobuff(code, message)
  encoded = message.encode
  header = [encoded.length+1, MESSAGE_CODES.index(code)].pack("NC")
  socket.write(header + encoded)
end