aerospike 2.6.0 → 2.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/README.md +3 -1
- data/lib/aerospike.rb +9 -5
- data/lib/aerospike/client.rb +101 -83
- data/lib/aerospike/cluster.rb +11 -50
- data/lib/aerospike/cluster/create_connection.rb +1 -1
- data/lib/aerospike/cluster/find_nodes_to_remove.rb +66 -0
- data/lib/aerospike/cluster/partition.rb +5 -2
- data/lib/aerospike/command/batch_direct_command.rb +104 -0
- data/lib/aerospike/command/batch_direct_exists_command.rb +51 -0
- data/lib/aerospike/command/batch_direct_node.rb +40 -0
- data/lib/aerospike/command/batch_index_command.rb +119 -0
- data/lib/aerospike/command/batch_index_exists_command.rb +45 -0
- data/lib/aerospike/command/batch_index_node.rb +52 -0
- data/lib/aerospike/command/batch_item.rb +18 -47
- data/lib/aerospike/command/command.rb +6 -65
- data/lib/aerospike/command/field_type.rb +13 -10
- data/lib/aerospike/command/{batch_command.rb → multi_command.rb} +29 -9
- data/lib/aerospike/command/read_command.rb +4 -2
- data/lib/aerospike/command/single_command.rb +6 -9
- data/lib/aerospike/connection/create.rb +3 -3
- data/lib/aerospike/host/parse.rb +28 -2
- data/lib/aerospike/node.rb +6 -2
- data/lib/aerospike/node/refresh/friends.rb +1 -1
- data/lib/aerospike/node/refresh/peers.rb +1 -1
- data/lib/aerospike/node_validator.rb +3 -3
- data/lib/aerospike/peers.rb +4 -0
- data/lib/aerospike/peers/parse.rb +26 -6
- data/lib/aerospike/policy/batch_policy.rb +25 -15
- data/lib/aerospike/policy/client_policy.rb +2 -2
- data/lib/aerospike/policy/query_policy.rb +25 -12
- data/lib/aerospike/policy/scan_policy.rb +39 -16
- data/lib/aerospike/query/stream_command.rb +6 -5
- data/lib/aerospike/record.rb +4 -3
- data/lib/aerospike/socket/ssl.rb +13 -13
- data/lib/aerospike/socket/tcp.rb +8 -1
- data/lib/aerospike/utils/string_parser.rb +7 -3
- data/lib/aerospike/version.rb +1 -1
- metadata +11 -7
- data/lib/aerospike/command/batch_command_exists.rb +0 -93
- data/lib/aerospike/command/batch_command_get.rb +0 -84
- data/lib/aerospike/command/batch_node.rb +0 -82
data/lib/aerospike/socket/ssl.rb
CHANGED
@@ -22,16 +22,16 @@ module Aerospike
|
|
22
22
|
class SSL < ::OpenSSL::SSL::SSLSocket
|
23
23
|
include Base
|
24
24
|
|
25
|
-
|
26
|
-
|
25
|
+
SUPPORTED_TLS_PARAMS = %i[ca_file ca_path min_version max_version].freeze
|
26
|
+
DEFAULT_TLS_PARAMS = {
|
27
27
|
min_version: :TLS1_2
|
28
28
|
}.freeze
|
29
29
|
|
30
30
|
class << self
|
31
|
-
def connect(host, port, timeout, tls_name,
|
32
|
-
Aerospike.logger.debug("Connecting to #{host}:#{tls_name}:#{port} using
|
31
|
+
def connect(host, port, timeout, tls_name, tls_options)
|
32
|
+
Aerospike.logger.debug("Connecting to #{host}:#{tls_name}:#{port} using TLS options #{tls_options}")
|
33
33
|
tcp_sock = TCP.connect(host, port, timeout)
|
34
|
-
ctx = build_ssl_context(
|
34
|
+
ctx = build_ssl_context(tls_options)
|
35
35
|
new(tcp_sock, ctx).tap do |ssl_sock|
|
36
36
|
ssl_sock.hostname = tls_name
|
37
37
|
ssl_sock.connect
|
@@ -39,15 +39,15 @@ module Aerospike
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
-
def build_ssl_context(
|
43
|
-
|
42
|
+
def build_ssl_context(tls_options)
|
43
|
+
tls_options[:context] || create_context(tls_options)
|
44
44
|
end
|
45
45
|
|
46
|
-
def create_context(
|
46
|
+
def create_context(tls_options)
|
47
47
|
OpenSSL::SSL::SSLContext.new.tap do |ctx|
|
48
|
-
if
|
49
|
-
cert = OpenSSL::X509::Certificate.new(File.read(
|
50
|
-
pkey = OpenSSL::PKey.read(File.read(
|
48
|
+
if tls_options[:cert_file] && tls_options[:pkey_file]
|
49
|
+
cert = OpenSSL::X509::Certificate.new(File.read(tls_options[:cert_file]))
|
50
|
+
pkey = OpenSSL::PKey.read(File.read(tls_options[:pkey_file]), tls_options[:pkey_pass])
|
51
51
|
if ctx.respond_to?(:add_certificate)
|
52
52
|
ctx.add_certificate(cert, pkey)
|
53
53
|
else
|
@@ -56,13 +56,13 @@ module Aerospike
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
-
params =
|
59
|
+
params = DEFAULT_TLS_PARAMS.merge(filter_params(tls_options))
|
60
60
|
ctx.set_params(params) unless params.empty?
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
64
|
def filter_params(params)
|
65
|
-
params.select { |key|
|
65
|
+
params.select { |key| SUPPORTED_TLS_PARAMS.include?(key) }
|
66
66
|
end
|
67
67
|
end
|
68
68
|
end
|
data/lib/aerospike/socket/tcp.rb
CHANGED
@@ -26,7 +26,14 @@ module Aerospike
|
|
26
26
|
|
27
27
|
def self.connect(host, port, timeout)
|
28
28
|
Aerospike.logger.debug("Trying to connect to #{host}:#{port} with #{timeout}s timeout")
|
29
|
-
|
29
|
+
|
30
|
+
domain = if host.match(Resolv::IPv6::Regex)
|
31
|
+
::Socket::AF_INET6
|
32
|
+
else
|
33
|
+
::Socket::AF_INET
|
34
|
+
end
|
35
|
+
|
36
|
+
sock = new(domain, ::Socket::SOCK_STREAM, 0)
|
30
37
|
sockaddr = ::Socket.sockaddr_in(port, host)
|
31
38
|
|
32
39
|
begin
|
@@ -21,6 +21,7 @@ module Aerospike
|
|
21
21
|
module Utils
|
22
22
|
class StringParser
|
23
23
|
attr_reader :io
|
24
|
+
|
24
25
|
def initialize(str)
|
25
26
|
@io = ::StringIO.new(str)
|
26
27
|
end
|
@@ -34,20 +35,23 @@ module Aerospike
|
|
34
35
|
raise ::Aerospike::Exceptions::Parse unless @io.read(1) == char
|
35
36
|
end
|
36
37
|
|
37
|
-
def read_until(
|
38
|
+
def read_until(*args)
|
38
39
|
[].tap do |result|
|
39
40
|
loop do
|
40
41
|
chr = @io.read(1)
|
41
|
-
break if chr
|
42
|
+
break if args.include?(chr)
|
42
43
|
result << chr
|
43
44
|
end
|
44
45
|
end.join
|
45
46
|
end
|
46
47
|
|
48
|
+
def prev
|
49
|
+
@io.string[@io.tell - 1]
|
50
|
+
end
|
51
|
+
|
47
52
|
def step(count = 1)
|
48
53
|
@io.read(count)
|
49
54
|
end
|
50
|
-
|
51
55
|
end
|
52
56
|
end
|
53
57
|
end
|
data/lib/aerospike/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aerospike
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Khosrow Afroozeh
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2018-
|
12
|
+
date: 2018-04-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: msgpack
|
@@ -65,20 +65,24 @@ files:
|
|
65
65
|
- lib/aerospike/cluster.rb
|
66
66
|
- lib/aerospike/cluster/create_connection.rb
|
67
67
|
- lib/aerospike/cluster/find_node.rb
|
68
|
+
- lib/aerospike/cluster/find_nodes_to_remove.rb
|
68
69
|
- lib/aerospike/cluster/partition.rb
|
69
70
|
- lib/aerospike/cluster/partition_tokenizer_new.rb
|
70
71
|
- lib/aerospike/cluster/partition_tokenizer_old.rb
|
71
72
|
- lib/aerospike/command/admin_command.rb
|
72
|
-
- lib/aerospike/command/
|
73
|
-
- lib/aerospike/command/
|
74
|
-
- lib/aerospike/command/
|
73
|
+
- lib/aerospike/command/batch_direct_command.rb
|
74
|
+
- lib/aerospike/command/batch_direct_exists_command.rb
|
75
|
+
- lib/aerospike/command/batch_direct_node.rb
|
76
|
+
- lib/aerospike/command/batch_index_command.rb
|
77
|
+
- lib/aerospike/command/batch_index_exists_command.rb
|
78
|
+
- lib/aerospike/command/batch_index_node.rb
|
75
79
|
- lib/aerospike/command/batch_item.rb
|
76
|
-
- lib/aerospike/command/batch_node.rb
|
77
80
|
- lib/aerospike/command/command.rb
|
78
81
|
- lib/aerospike/command/delete_command.rb
|
79
82
|
- lib/aerospike/command/execute_command.rb
|
80
83
|
- lib/aerospike/command/exists_command.rb
|
81
84
|
- lib/aerospike/command/field_type.rb
|
85
|
+
- lib/aerospike/command/multi_command.rb
|
82
86
|
- lib/aerospike/command/operate_command.rb
|
83
87
|
- lib/aerospike/command/read_command.rb
|
84
88
|
- lib/aerospike/command/read_header_command.rb
|
@@ -177,7 +181,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
177
181
|
version: '0'
|
178
182
|
requirements: []
|
179
183
|
rubyforge_project:
|
180
|
-
rubygems_version: 2.7.
|
184
|
+
rubygems_version: 2.7.6
|
181
185
|
signing_key:
|
182
186
|
specification_version: 4
|
183
187
|
summary: An Aerospike driver for Ruby.
|
@@ -1,93 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
# Copyright 2014-2017 Aerospike, Inc.
|
3
|
-
#
|
4
|
-
# Portions may be licensed to Aerospike, Inc. under one or more contributor
|
5
|
-
# license agreements.
|
6
|
-
#
|
7
|
-
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
8
|
-
# use this file except in compliance with the License. You may obtain a copy of
|
9
|
-
# the License at http:#www.apache.org/licenses/LICENSE-2.0
|
10
|
-
#
|
11
|
-
# Unless required by applicable law or agreed to in writing, software
|
12
|
-
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
13
|
-
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
14
|
-
# License for the specific language governing permissions and limitations under
|
15
|
-
# the License.
|
16
|
-
|
17
|
-
require 'aerospike/command/batch_command'
|
18
|
-
|
19
|
-
module Aerospike
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
class BatchCommandExists < BatchCommand #:nodoc:
|
24
|
-
|
25
|
-
def initialize(node, batch_namespace, policy, key_map, exists_array)
|
26
|
-
super(node)
|
27
|
-
|
28
|
-
@batch_namespace = batch_namespace
|
29
|
-
@policy = policy
|
30
|
-
@key_map = key_map
|
31
|
-
@exists_array = exists_array
|
32
|
-
|
33
|
-
self
|
34
|
-
end
|
35
|
-
|
36
|
-
def write_buffer
|
37
|
-
set_batch_exists(@policy, @batch_namespace)
|
38
|
-
end
|
39
|
-
|
40
|
-
# Parse all results in the batch. Add records to shared list.
|
41
|
-
# If the record was not found, the bins will be nil.
|
42
|
-
def parse_record_results(receive_size)
|
43
|
-
#Parse each message response and add it to the result array
|
44
|
-
@data_offset = 0
|
45
|
-
|
46
|
-
while @data_offset < receive_size
|
47
|
-
if !valid?
|
48
|
-
raise Aerospike::Exceptions::QueryTerminated.new
|
49
|
-
end
|
50
|
-
|
51
|
-
read_bytes(MSG_REMAINING_HEADER_SIZE)
|
52
|
-
|
53
|
-
result_code = @data_buffer.read(5).ord & 0xFF
|
54
|
-
|
55
|
-
# The only valid server return codes are "ok" and "not found".
|
56
|
-
# If other return codes are received, then abort the batch.
|
57
|
-
if result_code != 0 && result_code != Aerospike::ResultCode::KEY_NOT_FOUND_ERROR
|
58
|
-
raise Aerospike::Exceptions::Aerospike.new(result_code)
|
59
|
-
end
|
60
|
-
|
61
|
-
info3 = @data_buffer.read(3).ord
|
62
|
-
|
63
|
-
# If cmd is the end marker of the response, do not proceed further
|
64
|
-
return false if info3 & INFO3_LAST == INFO3_LAST
|
65
|
-
|
66
|
-
field_count = @data_buffer.read_int16(18)
|
67
|
-
op_count = @data_buffer.read_int16(20)
|
68
|
-
|
69
|
-
if op_count > 0
|
70
|
-
raise Aerospike::Exceptions::Parse('Received bins that were not requested!')
|
71
|
-
end
|
72
|
-
|
73
|
-
key = parse_key(field_count)
|
74
|
-
item = @key_map[key.digest]
|
75
|
-
|
76
|
-
if item
|
77
|
-
index = item.index
|
78
|
-
|
79
|
-
# only set the results to true; as a result, no synchronization is needed
|
80
|
-
@exists_array[index] = (result_code == 0)
|
81
|
-
else
|
82
|
-
Aerospike::logger.debug("Unexpected batch key returned: #{key.namespace}, #{key.digest}")
|
83
|
-
end
|
84
|
-
|
85
|
-
end # while
|
86
|
-
|
87
|
-
return true
|
88
|
-
end
|
89
|
-
|
90
|
-
|
91
|
-
end # class
|
92
|
-
|
93
|
-
end # module
|
@@ -1,84 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
# Copyright 2014-2017 Aerospike, Inc.
|
3
|
-
#
|
4
|
-
# Portions may be licensed to Aerospike, Inc. under one or more contributor
|
5
|
-
# license agreements.
|
6
|
-
#
|
7
|
-
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
8
|
-
# use this file except in compliance with the License. You may obtain a copy of
|
9
|
-
# the License at http:#www.apache.org/licenses/LICENSE-2.0
|
10
|
-
#
|
11
|
-
# Unless required by applicable law or agreed to in writing, software
|
12
|
-
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
13
|
-
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
14
|
-
# License for the specific language governing permissions and limitations under
|
15
|
-
# the License.
|
16
|
-
|
17
|
-
require 'aerospike/command/batch_command'
|
18
|
-
|
19
|
-
module Aerospike
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
class BatchCommandGet < BatchCommand #:nodoc:
|
24
|
-
|
25
|
-
def initialize(node, batch_namespace, policy, key_map, bin_names, records, read_attr)
|
26
|
-
super(node)
|
27
|
-
|
28
|
-
@batch_namespace = batch_namespace
|
29
|
-
@policy = policy
|
30
|
-
@key_map = key_map
|
31
|
-
@bin_names = bin_names
|
32
|
-
@records = records
|
33
|
-
@read_attr = read_attr
|
34
|
-
end
|
35
|
-
|
36
|
-
def write_buffer
|
37
|
-
set_batch_get(@policy, @batch_namespace, @bin_names, @read_attr)
|
38
|
-
end
|
39
|
-
|
40
|
-
# Parse all results in the batch. Add records to shared list.
|
41
|
-
# If the record was not found, the bins will be nil.
|
42
|
-
def parse_record_results(receive_size)
|
43
|
-
#Parse each message response and add it to the result array
|
44
|
-
@data_offset = 0
|
45
|
-
|
46
|
-
while @data_offset < receive_size
|
47
|
-
read_bytes(MSG_REMAINING_HEADER_SIZE)
|
48
|
-
result_code = @data_buffer.read(5).ord & 0xFF
|
49
|
-
|
50
|
-
# The only valid server return codes are "ok" and "not found".
|
51
|
-
# If other return codes are received, then abort the batch.
|
52
|
-
if result_code != 0 && result_code != Aerospike::ResultCode::KEY_NOT_FOUND_ERROR
|
53
|
-
raise Aerospike::Exceptions::Aerospike.new(result_code)
|
54
|
-
end
|
55
|
-
|
56
|
-
info3 = @data_buffer.read(3).ord
|
57
|
-
|
58
|
-
# If cmd is the end marker of the response, do not proceed further
|
59
|
-
return false if (info3 & INFO3_LAST) == INFO3_LAST
|
60
|
-
|
61
|
-
generation = @data_buffer.read_int32(6)
|
62
|
-
expiration = @data_buffer.read_int32(10)
|
63
|
-
field_count = @data_buffer.read_int16(18)
|
64
|
-
op_count = @data_buffer.read_int16(20)
|
65
|
-
key = parse_key(field_count)
|
66
|
-
item = @key_map[key.digest]
|
67
|
-
|
68
|
-
if item
|
69
|
-
if result_code == 0
|
70
|
-
index = item.index
|
71
|
-
@records[index] = parse_record(item.key, op_count, generation, expiration)
|
72
|
-
end
|
73
|
-
else
|
74
|
-
Aerospike.logger.debug("Unexpected batch key returned: #{key.namespace}, #{key.digest}")
|
75
|
-
end
|
76
|
-
|
77
|
-
end # while
|
78
|
-
|
79
|
-
true
|
80
|
-
end
|
81
|
-
|
82
|
-
end # class
|
83
|
-
|
84
|
-
end # module
|
@@ -1,82 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
# Copyright 2014-2017 Aerospike, Inc.
|
3
|
-
#
|
4
|
-
# Portions may be licensed to Aerospike, Inc. under one or more contributor
|
5
|
-
# license agreements.
|
6
|
-
#
|
7
|
-
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
8
|
-
# use this file except in compliance with the License. You may obtain a copy of
|
9
|
-
# the License at http:#www.apache.org/licenses/LICENSE-2.0
|
10
|
-
#
|
11
|
-
# Unless required by applicable law or agreed to in writing, software
|
12
|
-
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
13
|
-
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
14
|
-
# License for the specific language governing permissions and limitations under
|
15
|
-
# the License.
|
16
|
-
|
17
|
-
require 'thread'
|
18
|
-
|
19
|
-
require 'aerospike/record'
|
20
|
-
|
21
|
-
require 'aerospike/command/command'
|
22
|
-
|
23
|
-
module Aerospike
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
BatchNamespace = Struct.new :namespace, :keys
|
28
|
-
|
29
|
-
class BatchNode #:nodoc:
|
30
|
-
|
31
|
-
attr_accessor :node, :batch_namespaces, :key_capacity
|
32
|
-
|
33
|
-
def self.generate_list(cluster, keys)
|
34
|
-
nodes = cluster.nodes
|
35
|
-
|
36
|
-
if nodes.length == 0
|
37
|
-
raise Aerospike::Exceptions::Connection.new("command failed because cluster is empty.")
|
38
|
-
end
|
39
|
-
|
40
|
-
node_count = nodes.length
|
41
|
-
keys_per_node = (keys.length/node_count).to_i + 10
|
42
|
-
|
43
|
-
# Split keys by server node.
|
44
|
-
batch_nodes = []
|
45
|
-
|
46
|
-
keys.each do |key|
|
47
|
-
partition = Partition.new_by_key(key)
|
48
|
-
|
49
|
-
# error not required
|
50
|
-
node = cluster.get_node(partition)
|
51
|
-
batch_node = batch_nodes.detect{|bn| bn.node == node}
|
52
|
-
|
53
|
-
unless batch_node
|
54
|
-
batch_nodes << BatchNode.new(node, keys_per_node, key)
|
55
|
-
else
|
56
|
-
batch_node.add_key(key)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
batch_nodes
|
61
|
-
end
|
62
|
-
|
63
|
-
|
64
|
-
def initialize(node, key_capacity, key)
|
65
|
-
@node = node
|
66
|
-
@key_capacity = key_capacity
|
67
|
-
@batch_namespaces = [BatchNamespace.new(key.namespace, [key])]
|
68
|
-
end
|
69
|
-
|
70
|
-
def add_key(key)
|
71
|
-
batch_namespace = @batch_namespaces.detect{|bn| bn.namespace == key.namespace }
|
72
|
-
|
73
|
-
unless batch_namespace
|
74
|
-
@batch_namespaces << BatchNamespace.new(key.namespace, [key])
|
75
|
-
else
|
76
|
-
batch_namespace.keys << key
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
end # class
|
81
|
-
|
82
|
-
end # module
|