diff --git hbase-shell/src/main/ruby/hbase.rb hbase-shell/src/main/ruby/hbase.rb index fd053bc..3c09c4d 100644 --- hbase-shell/src/main/ruby/hbase.rb +++ hbase-shell/src/main/ruby/hbase.rb @@ -59,6 +59,8 @@ module HBaseConstants NUMREGIONS = 'NUMREGIONS' CONFIGURATION = org.apache.hadoop.hbase.HConstants::CONFIGURATION ATTRIBUTES="ATTRIBUTES" + VISIBILITY="VISIBILITY" + AUTHORIZATIONS = "AUTHORIZATIONS" # Load constants from hbase java API def self.promote_constants(constants) diff --git hbase-shell/src/main/ruby/hbase/table.rb hbase-shell/src/main/ruby/hbase/table.rb index 22d5d84..d084d49 100644 --- hbase-shell/src/main/ruby/hbase/table.rb +++ hbase-shell/src/main/ruby/hbase/table.rb @@ -132,12 +132,20 @@ EOF family, qualifier = parse_column_name(column) if args.any? attributes = args[ATTRIBUTES] - set_attributes(p, attributes) if attributes + set_attributes(p, attributes) if attributes + visibility = args[VISIBILITY] + set_cell_visibility(p, visibility) if visibility end #Case where attributes are specified without timestamp if timestamp.kind_of?(Hash) timestamp.each do |k, v| - set_attributes(p, v) if v + if v.kind_of?(Hash) + set_attributes(p, v) if v + end + if v.kind_of?(String) + set_cell_visibility(p, v) if v + end + end timestamp = nil end @@ -181,7 +189,9 @@ EOF end if args.any? attributes = args[ATTRIBUTES] - set_attributes(incr, attributes) if attributes + visibility = args[VISIBILITY] + set_attributes(incr, attributes) if attributes + set_cell_visibility(incr, visibility) if visibility end incr.addColumn(family, qualifier, value) @table.increment(incr) @@ -197,7 +207,9 @@ EOF end if args.any? attributes = args[ATTRIBUTES] - set_attributes(append, attributes) if attributes + visibility = args[VISIBILITY] + set_attributes(append, attributes) if attributes + set_cell_visibility(append, visibility) if visibility end append.add(family, qualifier, value.to_s.to_java_bytes) @table.append(append) @@ -256,6 +268,7 @@ EOF maxlength = args.delete(MAXLENGTH) if args[MAXLENGTH] filter = args.delete(FILTER) if args[FILTER] attributes = args[ATTRIBUTES] + authorizations = args[AUTHORIZATIONS] unless args.empty? columns = args[COLUMN] || args[COLUMNS] if args[VERSIONS] @@ -289,6 +302,8 @@ EOF else if attributes set_attributes(get, attributes) if attributes + elsif authorizations + set_authorizations(get, authorizations) if authorizations else # May have passed TIMESTAMP and row only; wants all columns from ts. unless ts = args[TIMESTAMP] || tr = args[TIMERANGE] @@ -301,7 +316,8 @@ EOF get.setTimeStamp(ts.to_i) if args[TIMESTAMP] get.setTimeRange(args[TIMERANGE][0], args[TIMERANGE][1]) if args[TIMERANGE] end - set_attributes(get, attributes) if attributes + set_attributes(get, attributes) if attributes + set_authorizations(get, authorizations) if authorizations end unless filter.class == String @@ -376,7 +392,7 @@ EOF timerange = args[TIMERANGE] raw = args["RAW"] || false attributes = args[ATTRIBUTES] - + authorizations = args[AUTHORIZATIONS] # Normalize column names columns = [columns] if columns.class == String unless columns.kind_of?(Array) @@ -412,6 +428,7 @@ EOF scan.setTimeRange(timerange[0], timerange[1]) if timerange scan.setRaw(raw) set_attributes(scan, attributes) if attributes + set_authorizations(scan, authorizations) if authorizations else scan = org.apache.hadoop.hbase.client.Scan.new end @@ -462,6 +479,16 @@ EOF end end + def set_cell_visibility(oprattr, visibility) + oprattr.setCellVisibility(org.apache.hadoop.hbase.security.visibility.CellVisibility.new(visibility.to_s)) + end + + def set_authorizations(oprattr, authorizations) + raise(ArgumentError, "#{"authorizations"} must be a Array type type") unless authorizations.kind_of?(Array) + auths = [ authorizations ].flatten.compact + oprattr.setAuthorizations(org.apache.hadoop.hbase.security.visibility.Authorizations.new(auths.to_java(:string))) + end + #---------------------------- # Add general administration utilities to the shell # each of the names below adds this method name to the table diff --git hbase-shell/src/main/ruby/hbase/visibility_labels.rb hbase-shell/src/main/ruby/hbase/visibility_labels.rb index 627cdca..73e1d9e 100644 --- hbase-shell/src/main/ruby/hbase/visibility_labels.rb +++ hbase-shell/src/main/ruby/hbase/visibility_labels.rb @@ -32,11 +32,13 @@ module Hbase def add_labels(*args) lables_table_available? - # Normalize args if args.kind_of?(Array) labels = [ args ].flatten.compact end + if labels.size() == 0 + raise(ArgumentError, "Arguments cannot be null") + end begin response = VisibilityClient.addLabels(@config, labels.to_java(:string)) diff --git hbase-shell/src/main/ruby/shell/commands/append.rb hbase-shell/src/main/ruby/shell/commands/append.rb index 55da884..a0ef36d 100644 --- hbase-shell/src/main/ruby/shell/commands/append.rb +++ hbase-shell/src/main/ruby/shell/commands/append.rb @@ -25,11 +25,13 @@ module Shell Appends a cell 'value' at specified table/row/column coordinates. hbase> append 't1', 'r1', 'c1', 'value', ATTRIBUTES=>{'mykey'=>'myvalue'} + hbase> append 't1', 'r1', 'c1', 'value', {VISIBILITY=>'PRIVATE|SECRET'} The same commands also can be run on a table reference. Suppose you had a reference t to table 't1', the corresponding command would be: hbase> t.append 'r1', 'c1', 'value', ATTRIBUTES=>{'mykey'=>'myvalue'} + hbase> t.append 'r1', 'c1', 'value', {VISIBILITY=>'PRIVATE|SECRET'} EOF end diff --git hbase-shell/src/main/ruby/shell/commands/get.rb hbase-shell/src/main/ruby/shell/commands/get.rb index 7ac4033..dc4c296 100644 --- hbase-shell/src/main/ruby/shell/commands/get.rb +++ hbase-shell/src/main/ruby/shell/commands/get.rb @@ -37,6 +37,7 @@ a dictionary of column(s), timestamp, timerange and versions. Examples: hbase> get 't1', 'r1', 'c1', 'c2' hbase> get 't1', 'r1', ['c1', 'c2'] hbsase> get 't1','r1', {COLUMN => 'c1', ATTRIBUTES => {'mykey'=>'myvalue'}} + hbsase> get 't1','r1', {COLUMN => 'c1', AUTHORIZATIONS => ['PRIVATE','SECRET']} Besides the default 'toStringBinary' format, 'get' also supports custom formatting by column. A user can define a FORMATTER by adding it to the column name in the get diff --git hbase-shell/src/main/ruby/shell/commands/incr.rb hbase-shell/src/main/ruby/shell/commands/incr.rb index c3c237e..4d6559c 100644 --- hbase-shell/src/main/ruby/shell/commands/incr.rb +++ hbase-shell/src/main/ruby/shell/commands/incr.rb @@ -29,15 +29,17 @@ To increment a cell value in table 't1' at row 'r1' under column hbase> incr 't1', 'r1', 'c1' hbase> incr 't1', 'r1', 'c1', 1 hbase> incr 't1', 'r1', 'c1', 10 - hbase> incr 't1', 'r1', 'c1', 10, ATTRIBUTES=>{'mykey'=>'myvalue'} - hbase> incr 't1', 'r1', 'c1', ATTRIBUTES=>{'mykey'=>'myvalue'} + hbase> incr 't1', 'r1', 'c1', 10, {ATTRIBUTES=>{'mykey'=>'myvalue'}} + hbase> incr 't1', 'r1', 'c1', {ATTRIBUTES=>{'mykey'=>'myvalue'}} + hbase> incr 't1', 'r1', 'c1', 10, {VISIBILITY=>'PRIVATE|SECRET'} The same commands also can be run on a table reference. Suppose you had a reference t to table 't1', the corresponding command would be: hbase> t.incr 'r1', 'c1' hbase> t.incr 'r1', 'c1', 1 - hbase> t.incr 'r1', 'c1', 10, ATTRIBUTES=>{'mykey'=>'myvalue'} + hbase> t.incr 'r1', 'c1', 10, {ATTRIBUTES=>{'mykey'=>'myvalue'}} + hbase> t.incr 'r1', 'c1', 10, {VISIBILITY=>'PRIVATE|SECRET'} EOF end diff --git hbase-shell/src/main/ruby/shell/commands/put.rb hbase-shell/src/main/ruby/shell/commands/put.rb index 56f8c09..d56fd00 100644 --- hbase-shell/src/main/ruby/shell/commands/put.rb +++ hbase-shell/src/main/ruby/shell/commands/put.rb @@ -28,13 +28,14 @@ row 'r1' under column 'c1' marked with the time 'ts1', do: hbase> put 't1', 'r1', 'c1', 'value' hbase> put 't1', 'r1', 'c1', 'value', ts1 - hbase> put 't1', 'r1', 'c1', 'value', {ATTRIBUTES=>{'mykey'=>'myvalue'} - hbase> put 't1', 'r1', 'c1', 'value', ts1, {ATTRIBUTES=>{'mykey'=>'myvalue'} + hbase> put 't1', 'r1', 'c1', 'value', {ATTRIBUTES=>{'mykey'=>'myvalue'}} + hbase> put 't1', 'r1', 'c1', 'value', ts1, {ATTRIBUTES=>{'mykey'=>'myvalue'}} + hbase> put 't1', 'r1', 'c1', 'value', ts1, {VISIBILITY=>'PRIVATE|SECRET'}} The same commands also can be run on a table reference. Suppose you had a reference t to table 't1', the corresponding command would be: - hbase> t.put 'r1', 'c1', 'value', ts1, {ATTRIBUTES=>{'mykey'=>'myvalue'} + hbase> t.put 'r1', 'c1', 'value', ts1, {ATTRIBUTES=>{'mykey'=>'myvalue'}} EOF end diff --git hbase-shell/src/main/ruby/shell/commands/scan.rb hbase-shell/src/main/ruby/shell/commands/scan.rb index 129961f..99b857b 100644 --- hbase-shell/src/main/ruby/shell/commands/scan.rb +++ hbase-shell/src/main/ruby/shell/commands/scan.rb @@ -49,6 +49,7 @@ Some examples: org.apache.hadoop.hbase.filter.ColumnPaginationFilter.new(1, 0)} For setting the Operation Attributes hbase> scan 't1', { COLUMNS => ['c1', 'c2'], ATTRIBUTES => {'mykey' => 'myvalue'}} + hbase> scan 't1', { COLUMNS => ['c1', 'c2'], AUTHORIZATIONS => ['PRIVATE','SECRET']} For experts, there is an additional option -- CACHE_BLOCKS -- which switches block caching for the scanner on (true) or off (false). By default it is enabled. Examples: diff --git hbase-shell/src/test/ruby/hbase/table_test.rb hbase-shell/src/test/ruby/hbase/table_test.rb index 01781f8..a3ba299 100644 --- hbase-shell/src/test/ruby/hbase/table_test.rb +++ hbase-shell/src/test/ruby/hbase/table_test.rb @@ -138,6 +138,10 @@ module Hbase define_test "put should work with attributes" do @test_table.put("123", "x:a", 4, {ATTRIBUTES=>{'mykey'=>'myvalue'}}) end + + define_test "put should work with attribute" do + @test_table.put("123", "x:a", 4, {VISIBILITY=>'mykey'}) + end #------------------------------------------------------------------------------- define_test "delete should work without timestamp" do @@ -172,22 +176,6 @@ module Hbase assert_nil(res) end - #------------------------------------------------------------------------------- - - define_test "incr should work w/o value" do - @test_table.incr("123", 'x:cnt1') - end - - define_test "incr should work with value" do - @test_table.incr("123", 'x:cnt2', 10) - end - - define_test "incr should work with integer keys" do - @test_table.incr(123, 'x:cnt3') - end - - #------------------------------------------------------------------------------- - define_test "append should work with value" do @test_table.append("123", 'x:cnt2', '123') end @@ -224,6 +212,9 @@ module Hbase @test_table.put(3, "x:a", 21, {ATTRIBUTES=>{'mykey'=>'myvalue'}}) @test_table.put(3, "x:b", 22, @test_ts, {ATTRIBUTES=>{'mykey'=>'myvalue'}}) + + @test_table.put(4, "x:a", 31, {VISIBILITY=>'mykey'}) + @test_table.put(4, "x:b", 32, @test_ts, {VISIBILITY=>'mykey'}) end @@ -257,6 +248,14 @@ module Hbase assert_not_nil(res['x:a']) assert_not_nil(res['x:b']) end + + define_test "get should work for data written with Visibility" do + res = @test_table._get_internal('4') + assert_not_nil(res) + assert_kind_of(Hash, res) + assert_not_nil(res['x:a']) + assert_not_nil(res['x:b']) + end define_test "get should work with integer keys" do res = @test_table._get_internal(1) @@ -297,6 +296,14 @@ module Hbase assert_not_nil(res['x:a']) assert_not_nil(res['x:b']) end + + define_test "get should work with hash columns spec and an array of strings COLUMNS parameter with AUTHORIZATIONS" do + res = @test_table._get_internal('1', COLUMNS => [ 'x:a', 'x:b' ], AUTHORIZATIONS=>['PRIVATE']) + assert_not_nil(res) + assert_kind_of(Hash, res) + assert_not_nil(res['x:a']) + assert_not_nil(res['x:b']) + end define_test "get should work with hash columns spec and TIMESTAMP only" do res = @test_table._get_internal('1', TIMESTAMP => @test_ts) @@ -305,7 +312,12 @@ module Hbase assert_nil(res['x:a']) assert_not_nil(res['x:b']) end - + + define_test "get should work with hash columns spec and TIMESTAMP and AUTHORIZATIONS" do + res = @test_table._get_internal('1', TIMESTAMP => 1234, AUTHORIZATIONS=>['PRIVATE']) + assert_nil(res) + end + define_test "get should fail with hash columns spec and strange COLUMN value" do assert_raise(ArgumentError) do @test_table._get_internal('1', COLUMN => {})