aerospike 0.1.6 → 1.0.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +22 -0
- data/lib/aerospike.rb +5 -0
- data/lib/aerospike/atomic/atomic.rb +3 -1
- data/lib/aerospike/client.rb +98 -32
- data/lib/aerospike/cluster/cluster.rb +25 -8
- data/lib/aerospike/cluster/connection.rb +1 -1
- data/lib/aerospike/cluster/node.rb +16 -3
- data/lib/aerospike/cluster/node_validator.rb +16 -4
- data/lib/aerospike/cluster/partition.rb +1 -1
- data/lib/aerospike/cluster/partition_tokenizer_new.rb +4 -2
- data/lib/aerospike/cluster/partition_tokenizer_old.rb +1 -1
- data/lib/aerospike/command/admin_command.rb +353 -0
- data/lib/aerospike/command/batch_command.rb +12 -42
- data/lib/aerospike/command/batch_command_exists.rb +1 -1
- data/lib/aerospike/command/batch_command_get.rb +1 -1
- data/lib/aerospike/command/batch_item.rb +1 -1
- data/lib/aerospike/command/batch_node.rb +1 -1
- data/lib/aerospike/command/command.rb +9 -14
- data/lib/aerospike/command/delete_command.rb +1 -1
- data/lib/aerospike/command/execute_command.rb +1 -1
- data/lib/aerospike/command/exists_command.rb +1 -1
- data/lib/aerospike/command/operate_command.rb +1 -1
- data/lib/aerospike/command/read_command.rb +12 -38
- data/lib/aerospike/command/read_header_command.rb +2 -2
- data/lib/aerospike/command/roles.rb +36 -0
- data/lib/aerospike/command/single_command.rb +1 -1
- data/lib/aerospike/command/touch_command.rb +1 -1
- data/lib/aerospike/command/write_command.rb +1 -1
- data/lib/aerospike/info.rb +1 -1
- data/lib/aerospike/loggable.rb +1 -1
- data/lib/aerospike/policy/admin_policy.rb +33 -0
- data/lib/aerospike/policy/batch_policy.rb +5 -5
- data/lib/aerospike/policy/client_policy.rb +15 -4
- data/lib/aerospike/policy/generation_policy.rb +0 -5
- data/lib/aerospike/policy/policy.rb +6 -6
- data/lib/aerospike/policy/query_policy.rb +2 -2
- data/lib/aerospike/policy/scan_policy.rb +6 -6
- data/lib/aerospike/policy/write_policy.rb +8 -8
- data/lib/aerospike/query/query_command.rb +1 -1
- data/lib/aerospike/query/scan_command.rb +1 -1
- data/lib/aerospike/query/stream_command.rb +1 -1
- data/lib/aerospike/record.rb +2 -3
- data/lib/aerospike/result_code.rb +11 -1
- data/lib/aerospike/user_role.rb +30 -0
- data/lib/aerospike/utils/buffer.rb +22 -2
- data/lib/aerospike/utils/epoc.rb +3 -1
- data/lib/aerospike/utils/pool.rb +1 -1
- data/lib/aerospike/value/value.rb +12 -13
- data/lib/aerospike/version.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 60bb290526217118edd3256087baf8f3b1979229
|
4
|
+
data.tar.gz: 3298f8ddaa97c6d93294f8dfa1610f2b0770b7da
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8f0cbc5177d8c217583531fc0408ba07f99d379a66f21e8f723326b06d99aa48d2ab315a636f7fa1ec3497fd52b8aec677b43a195420b289fd091815e80f8a50
|
7
|
+
data.tar.gz: 2900d08848a56766a865080a07ad09df17f23f14374eea6a92f873baddb1ee9d172b737f87934f75cfde425822a9f1d0923abc5bb7252d0252df613563a57c36
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,25 @@
|
|
1
|
+
## Jan 26 2014 (1.0.0)
|
2
|
+
|
3
|
+
Major release. With this release, Ruby client graduates to version 1.
|
4
|
+
|
5
|
+
* **Breaking Changes**:
|
6
|
+
|
7
|
+
* All `policy` initialize signatures have changed. Using policies was not documented, so it shouldn't affect most code. It will however, break any code initializing policies.
|
8
|
+
* Removed `Record.dups` and `GenerationPolicy::DUPLICATE`
|
9
|
+
|
10
|
+
* **New Features**:
|
11
|
+
|
12
|
+
* Added Security Features: Please consult [Security Docs](https://www.aerospike.com/docs/guide/security.html) on Aerospike website.
|
13
|
+
|
14
|
+
* `ClientPolicy.User`, `ClientPolicy.Password`
|
15
|
+
* `Client.CreateUser()`, `Client.DropUser()`, `Client.ChangePassword()`
|
16
|
+
* `Client.GrantRoles()`, `Client.RevokeRoles()`, `Client.ReplaceRoles()`
|
17
|
+
* `Client.QueryUser()`, `Client.QueryUsers`
|
18
|
+
|
19
|
+
* **Fixes**:
|
20
|
+
|
21
|
+
* fixed size returned from `BytesValue.write`
|
22
|
+
|
1
23
|
## Dec 28 2014 (0.1.6)
|
2
24
|
|
3
25
|
Minor features added, minor fixes and improvements.
|
data/lib/aerospike.rb
CHANGED
@@ -5,6 +5,7 @@ require "monitor"
|
|
5
5
|
require "timeout"
|
6
6
|
require 'resolv'
|
7
7
|
require 'msgpack'
|
8
|
+
require 'bcrypt'
|
8
9
|
|
9
10
|
require 'aerospike/atomic/atomic'
|
10
11
|
|
@@ -35,6 +36,7 @@ require 'aerospike/command/touch_command'
|
|
35
36
|
require 'aerospike/command/batch_command_exists'
|
36
37
|
require 'aerospike/command/read_command'
|
37
38
|
require 'aerospike/command/delete_command'
|
39
|
+
require 'aerospike/command/admin_command'
|
38
40
|
require 'aerospike/key'
|
39
41
|
require 'aerospike/operation'
|
40
42
|
|
@@ -48,6 +50,7 @@ require 'aerospike/policy/scan_policy'
|
|
48
50
|
require 'aerospike/policy/query_policy'
|
49
51
|
require 'aerospike/policy/consistency_level'
|
50
52
|
require 'aerospike/policy/commit_level'
|
53
|
+
require 'aerospike/policy/admin_policy'
|
51
54
|
|
52
55
|
require 'aerospike/cluster/connection'
|
53
56
|
require 'aerospike/cluster/cluster'
|
@@ -65,6 +68,8 @@ require 'aerospike/info'
|
|
65
68
|
require 'aerospike/udf'
|
66
69
|
require 'aerospike/bin'
|
67
70
|
require 'aerospike/aerospike_exception'
|
71
|
+
require 'aerospike/user_role'
|
72
|
+
|
68
73
|
require 'aerospike/task/index_task'
|
69
74
|
require 'aerospike/task/udf_remove_task'
|
70
75
|
require 'aerospike/task/udf_register_task'
|
data/lib/aerospike/client.rb
CHANGED
@@ -36,13 +36,15 @@ module Aerospike
|
|
36
36
|
|
37
37
|
class Client
|
38
38
|
|
39
|
-
attr_accessor :default_policy, :default_write_policy
|
39
|
+
attr_accessor :default_policy, :default_write_policy,
|
40
|
+
:default_scan_policy, :default_query_policy, :default_admin_policy
|
40
41
|
|
41
42
|
def initialize(host, port, options={})
|
42
43
|
@default_policy = Policy.new
|
43
44
|
@default_write_policy = WritePolicy.new
|
44
45
|
@default_scan_policy = ScanPolicy.new
|
45
46
|
@default_query_policy = QueryPolicy.new
|
47
|
+
@default_admin_policy = QueryPolicy.new
|
46
48
|
|
47
49
|
policy = opt_to_client_policy(options)
|
48
50
|
|
@@ -594,7 +596,7 @@ module Aerospike
|
|
594
596
|
begin
|
595
597
|
command.execute
|
596
598
|
rescue => e
|
597
|
-
Aerospike.logger.error(e) unless e ==
|
599
|
+
Aerospike.logger.error(e.backtrace.join("\n")) unless e == SCAN_TERMINATED_EXCEPTION
|
598
600
|
recordset.cancel(e)
|
599
601
|
ensure
|
600
602
|
recordset.thread_finished
|
@@ -609,7 +611,7 @@ module Aerospike
|
|
609
611
|
begin
|
610
612
|
command.execute
|
611
613
|
rescue => e
|
612
|
-
Aerospike.logger.error(e) unless e ==
|
614
|
+
Aerospike.logger.error(e.backtrace.join("\n")) unless e == SCAN_TERMINATED_EXCEPTION
|
613
615
|
recordset.cancel(e)
|
614
616
|
ensure
|
615
617
|
recordset.thread_finished
|
@@ -644,7 +646,7 @@ module Aerospike
|
|
644
646
|
begin
|
645
647
|
command.execute
|
646
648
|
rescue => e
|
647
|
-
Aerospike.logger.error(e) unless e ==
|
649
|
+
Aerospike.logger.error(e.backtrace.join("\n")) unless e == SCAN_TERMINATED_EXCEPTION
|
648
650
|
recordset.cancel(e)
|
649
651
|
ensure
|
650
652
|
recordset.thread_finished
|
@@ -684,7 +686,7 @@ module Aerospike
|
|
684
686
|
begin
|
685
687
|
command.execute
|
686
688
|
rescue => e
|
687
|
-
Aerospike.logger.error(e) unless e ==
|
689
|
+
Aerospike.logger.error(e.backtrace.join("\n")) unless e == QUERY_TERMINATED_EXCEPTION
|
688
690
|
recordset.cancel(e)
|
689
691
|
ensure
|
690
692
|
recordset.thread_finished
|
@@ -695,6 +697,82 @@ module Aerospike
|
|
695
697
|
recordset
|
696
698
|
end
|
697
699
|
|
700
|
+
#-------------------------------------------------------
|
701
|
+
# User administration
|
702
|
+
#-------------------------------------------------------
|
703
|
+
|
704
|
+
# Create user with password and roles. Clear-text password will be hashed using bcrypt
|
705
|
+
# before sending to server.
|
706
|
+
def create_user(user, password, roles, options={})
|
707
|
+
policy = opt_to_admin_policy(options)
|
708
|
+
hash = AdminCommand.hash_password(password)
|
709
|
+
command = AdminCommand.new
|
710
|
+
command.create_user(@cluster, policy, user, hash, roles)
|
711
|
+
end
|
712
|
+
|
713
|
+
# Remove user from cluster.
|
714
|
+
def drop_user(user, options={})
|
715
|
+
policy = opt_to_admin_policy(options)
|
716
|
+
command = AdminCommand.new
|
717
|
+
command.drop_user(@cluster, policy, user)
|
718
|
+
end
|
719
|
+
|
720
|
+
# Change user's password. Clear-text password will be hashed using bcrypt before sending to server.
|
721
|
+
def change_password(user, password, options={})
|
722
|
+
policy = opt_to_admin_policy(options)
|
723
|
+
if @cluster.user == ''
|
724
|
+
return NewAerospikeError(INVALID_USER)
|
725
|
+
end
|
726
|
+
|
727
|
+
hash = AdminCommand.hash_password(password)
|
728
|
+
command = AdminCommand.new
|
729
|
+
|
730
|
+
if user == @cluster.user
|
731
|
+
# Change own password.
|
732
|
+
command.change_password(@cluster, policy, user, hash)
|
733
|
+
else
|
734
|
+
# Change other user's password by user admin.
|
735
|
+
command.set_password(@cluster, policy, user, hash)
|
736
|
+
end
|
737
|
+
|
738
|
+
@cluster.change_password(user, hash)
|
739
|
+
end
|
740
|
+
|
741
|
+
# Add roles to user's list of roles.
|
742
|
+
def grant_roles(user, roles, options={})
|
743
|
+
policy = opt_to_admin_policy(options)
|
744
|
+
command = AdminCommand.new
|
745
|
+
command.grant_roles(@cluster, policy, user, roles)
|
746
|
+
end
|
747
|
+
|
748
|
+
# Remove roles from user's list of roles.
|
749
|
+
def revoke_roles(user, roles, options={})
|
750
|
+
policy = opt_to_admin_policy(options)
|
751
|
+
command = AdminCommand.new
|
752
|
+
command.revoke_roles(@cluster, policy, user, roles)
|
753
|
+
end
|
754
|
+
|
755
|
+
# Replace user's list of roles.
|
756
|
+
def replace_roles(user, roles, options={})
|
757
|
+
policy = opt_to_admin_policy(options)
|
758
|
+
command = AdminCommand.new
|
759
|
+
command.replace_roles(@cluster, policy, user, roles)
|
760
|
+
end
|
761
|
+
|
762
|
+
# Retrieve roles for a given user.
|
763
|
+
def query_user(user, options={})
|
764
|
+
policy = opt_to_admin_policy(options)
|
765
|
+
command = AdminCommand.new
|
766
|
+
command.query_user(@cluster, policy, user)
|
767
|
+
end
|
768
|
+
|
769
|
+
# Retrieve all users and their roles.
|
770
|
+
def query_users(options={})
|
771
|
+
policy = opt_to_admin_policy(options)
|
772
|
+
command = AdminCommand.new
|
773
|
+
command.query_users(@cluster, policy)
|
774
|
+
end
|
775
|
+
|
698
776
|
private
|
699
777
|
|
700
778
|
def send_info_command(policy, command)
|
@@ -720,11 +798,7 @@ module Aerospike
|
|
720
798
|
elsif options.is_a?(ClientPolicy)
|
721
799
|
options
|
722
800
|
elsif options.is_a?(Hash)
|
723
|
-
ClientPolicy.new(
|
724
|
-
options[:timeout],
|
725
|
-
options[:connection_queue_size],
|
726
|
-
options[:fail_if_not_connected]
|
727
|
-
)
|
801
|
+
ClientPolicy.new(options)
|
728
802
|
end
|
729
803
|
end
|
730
804
|
|
@@ -734,13 +808,7 @@ module Aerospike
|
|
734
808
|
elsif options.is_a?(Policy)
|
735
809
|
options
|
736
810
|
elsif options.is_a?(Hash)
|
737
|
-
Policy.new(
|
738
|
-
options[:priority],
|
739
|
-
options[:timeout],
|
740
|
-
options[:max_retiries],
|
741
|
-
options[:sleep_between_retries],
|
742
|
-
options[:consistency_level]
|
743
|
-
)
|
811
|
+
Policy.new(options)
|
744
812
|
end
|
745
813
|
end
|
746
814
|
|
@@ -750,14 +818,7 @@ module Aerospike
|
|
750
818
|
elsif options.is_a?(WritePolicy)
|
751
819
|
options
|
752
820
|
elsif options.is_a?(Hash)
|
753
|
-
WritePolicy.new(
|
754
|
-
options[:record_exists_action],
|
755
|
-
options[:gen_policy],
|
756
|
-
options[:generation],
|
757
|
-
options[:expiration],
|
758
|
-
options[:send_key],
|
759
|
-
options[:commit_level]
|
760
|
-
)
|
821
|
+
WritePolicy.new(options)
|
761
822
|
end
|
762
823
|
end
|
763
824
|
|
@@ -767,12 +828,7 @@ module Aerospike
|
|
767
828
|
elsif options.is_a?(ScanPolicy)
|
768
829
|
options
|
769
830
|
elsif options.is_a?(Hash)
|
770
|
-
ScanPolicy.new(
|
771
|
-
options[:scan_percent],
|
772
|
-
options[:concurrent_nodes],
|
773
|
-
options[:include_bin_data],
|
774
|
-
options[:fail_on_cluster_change]
|
775
|
-
)
|
831
|
+
ScanPolicy.new(options)
|
776
832
|
end
|
777
833
|
end
|
778
834
|
|
@@ -782,7 +838,17 @@ module Aerospike
|
|
782
838
|
elsif options.is_a?(QueryPolicy)
|
783
839
|
options
|
784
840
|
elsif options.is_a?(Hash)
|
785
|
-
QueryPolicy.new()
|
841
|
+
QueryPolicy.new(options)
|
842
|
+
end
|
843
|
+
end
|
844
|
+
|
845
|
+
def opt_to_admin_policy(options)
|
846
|
+
if options.nil? || options == {}
|
847
|
+
@default_admin_policy
|
848
|
+
elsif options.is_a?(AdminPolicy)
|
849
|
+
options
|
850
|
+
elsif options.is_a?(Hash)
|
851
|
+
AdminPolicy.new(options)
|
786
852
|
end
|
787
853
|
end
|
788
854
|
|
@@ -25,7 +25,7 @@ module Aerospike
|
|
25
25
|
|
26
26
|
class Cluster
|
27
27
|
|
28
|
-
attr_reader :connection_timeout, :connection_queue_size
|
28
|
+
attr_reader :connection_timeout, :connection_queue_size, :user, :password
|
29
29
|
|
30
30
|
def initialize(policy, *hosts)
|
31
31
|
@cluster_seeds = hosts
|
@@ -38,6 +38,12 @@ module Aerospike
|
|
38
38
|
@closed = Atomic.new(false)
|
39
39
|
@mutex = Mutex.new
|
40
40
|
|
41
|
+
# setup auth info for cluster
|
42
|
+
if policy.requires_authentication
|
43
|
+
@user = policy.user
|
44
|
+
@password = AdminCommand.hash_password(policy.password)
|
45
|
+
end
|
46
|
+
|
41
47
|
wait_till_stablized
|
42
48
|
|
43
49
|
if policy.fail_if_not_connected && !connected?
|
@@ -88,7 +94,8 @@ module Aerospike
|
|
88
94
|
# Must copy array reference for copy on write semantics to work.
|
89
95
|
node_array = nodes
|
90
96
|
length = node_array.length
|
91
|
-
|
97
|
+
i = 0
|
98
|
+
while i < length
|
92
99
|
# Must handle concurrency with other non-tending threads, so node_index is consistent.
|
93
100
|
index = (@node_index.update{|v| v+1} % node_array.length).abs
|
94
101
|
node = node_array[index]
|
@@ -96,6 +103,8 @@ module Aerospike
|
|
96
103
|
if node.active?
|
97
104
|
return node
|
98
105
|
end
|
106
|
+
|
107
|
+
i = i.succ
|
99
108
|
end
|
100
109
|
raise Aerospike::Exceptions::InvalidNode.new
|
101
110
|
end
|
@@ -166,6 +175,11 @@ module Aerospike
|
|
166
175
|
end
|
167
176
|
end
|
168
177
|
|
178
|
+
def change_password(user, password)
|
179
|
+
# change password ONLY if the user is the same
|
180
|
+
@password = password if @user == user
|
181
|
+
end
|
182
|
+
|
169
183
|
private
|
170
184
|
|
171
185
|
def launch_tend_thread
|
@@ -210,7 +224,7 @@ module Aerospike
|
|
210
224
|
refresh_count += 1
|
211
225
|
friend_list.concat(friends) if friends
|
212
226
|
rescue => e
|
213
|
-
Aerospike.logger.error("Node `#{node}` refresh failed: #{e.
|
227
|
+
Aerospike.logger.error("Node `#{node}` refresh failed: #{e.backtrace.join("\n")}")
|
214
228
|
end
|
215
229
|
end
|
216
230
|
end
|
@@ -283,9 +297,9 @@ module Aerospike
|
|
283
297
|
|
284
298
|
seed_array.each do |seed|
|
285
299
|
begin
|
286
|
-
seed_node_validator = NodeValidator.new(seed, @connection_timeout)
|
300
|
+
seed_node_validator = NodeValidator.new(self, seed, @connection_timeout)
|
287
301
|
rescue => e
|
288
|
-
Aerospike.logger.error("Seed #{seed.to_s} failed: #{e}")
|
302
|
+
Aerospike.logger.error("Seed #{seed.to_s} failed: #{e.backtrace.join("\n")}")
|
289
303
|
next
|
290
304
|
end
|
291
305
|
|
@@ -297,7 +311,7 @@ module Aerospike
|
|
297
311
|
nv = seed_node_validator
|
298
312
|
else
|
299
313
|
begin
|
300
|
-
nv = NodeValidator.new(aliass, @connection_timeout)
|
314
|
+
nv = NodeValidator.new(self, aliass, @connection_timeout)
|
301
315
|
rescue Exection => e
|
302
316
|
Aerospike.logger.error("Seed #{seed.to_s} failed: #{e}")
|
303
317
|
next
|
@@ -345,7 +359,7 @@ module Aerospike
|
|
345
359
|
|
346
360
|
hosts.each do |host|
|
347
361
|
begin
|
348
|
-
nv = NodeValidator.new(host, @connection_timeout)
|
362
|
+
nv = NodeValidator.new(self, host, @connection_timeout)
|
349
363
|
|
350
364
|
# if node is already in cluster's node list,
|
351
365
|
# or already included in the list to be added, we should skip it
|
@@ -432,12 +446,15 @@ module Aerospike
|
|
432
446
|
partitions_list.each do |node_array|
|
433
447
|
max = node_array.length
|
434
448
|
|
435
|
-
|
449
|
+
i = 0
|
450
|
+
while i < max
|
436
451
|
node = node_array[i]
|
437
452
|
# Use reference equality for performance.
|
438
453
|
if node == filter
|
439
454
|
return true
|
440
455
|
end
|
456
|
+
|
457
|
+
i = i.succ
|
441
458
|
end
|
442
459
|
end
|
443
460
|
false
|
@@ -47,12 +47,25 @@ module Aerospike
|
|
47
47
|
@connections = Pool.new(@cluster.connection_queue_size)
|
48
48
|
@connections.create_block = Proc.new do
|
49
49
|
while conn = Connection.new(@host.name, @host.port, @cluster.connection_timeout)
|
50
|
+
|
51
|
+
# need to authenticate
|
52
|
+
if @cluster.user && @cluster.user != ''
|
53
|
+
begin
|
54
|
+
command = AdminCommand.new
|
55
|
+
command.authenticate(conn, @cluster.user, @cluster.password)
|
56
|
+
rescue => e
|
57
|
+
# Socket not authenticated. Do not put back into pool.
|
58
|
+
conn.close if conn
|
59
|
+
raise e
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
50
63
|
break if conn.connected?
|
51
64
|
end
|
52
65
|
conn
|
53
66
|
end
|
54
67
|
|
55
|
-
@connections.cleanup_block = Proc.new { |conn| conn.close }
|
68
|
+
@connections.cleanup_block = Proc.new { |conn| conn.close if conn }
|
56
69
|
end
|
57
70
|
|
58
71
|
# Request current status from server node, and update node with the result
|
@@ -65,7 +78,7 @@ module Aerospike
|
|
65
78
|
rescue => e
|
66
79
|
Aerospike.logger.error(e)
|
67
80
|
|
68
|
-
conn.close
|
81
|
+
conn.close if conn
|
69
82
|
decrease_health
|
70
83
|
|
71
84
|
raise e
|
@@ -179,7 +192,7 @@ module Aerospike
|
|
179
192
|
# drain connections and close all of them
|
180
193
|
# non-blocking, does not call create_block when passed false
|
181
194
|
while conn = @connections.poll(false)
|
182
|
-
conn.close
|
195
|
+
conn.close if conn
|
183
196
|
end
|
184
197
|
end
|
185
198
|
|