hbase-jruby 0.2.2-java → 0.2.3-java

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,6 +1,13 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ 0.2.3
5
+ -----
6
+ - Fix: [Thread.current[:htable] must be local to each connection](https://github.com/junegunn/hbase-jruby/issues/4)
7
+ - Fix: [`HBase.log4j=` to support XML based configuration](https://github.com/junegunn/hbase-jruby/issues/5)
8
+ - Automatically set versions to 1 when counting records
9
+ - New dependency profile: `cdh4.2`
10
+
4
11
  0.2.2
5
12
  -----
6
13
  - Added `HBase::Table#delete_row` method
data/README.md CHANGED
@@ -12,7 +12,7 @@
12
12
  ```ruby
13
13
  require 'hbase-jruby'
14
14
 
15
- HBase.resolve_dependency! 'cdh4.1.3'
15
+ HBase.resolve_dependency! 'cdh4.2.0'
16
16
 
17
17
  hbase = HBase.new
18
18
  table = hbase[:test_table]
@@ -68,6 +68,7 @@ Call `HBase.resolve_dependency!` helper method passing one of the arguments list
68
68
 
69
69
  | Argument | Dependency | Required executable |
70
70
  |------------|--------------------------|---------------------|
71
+ | cdh4.2[.*] | Cloudera CDH4.2 | mvn |
71
72
  | cdh4.1[.*] | Cloudera CDH4.1 | mvn |
72
73
  | cdh3[u*] | Cloudera CDH3 | mvn |
73
74
  | 0.94[.*] | Apache HBase 0.94 | mvn |
@@ -78,9 +79,9 @@ Call `HBase.resolve_dependency!` helper method passing one of the arguments list
78
79
  #### Examples
79
80
 
80
81
  ```ruby
81
- # Load JAR files from CDH4.1.x using Maven
82
+ # Load JAR files from CDH4 using Maven
83
+ HBase.resolve_dependency! 'cdh4.2.0'
82
84
  HBase.resolve_dependency! 'cdh4.1.3'
83
- HBase.resolve_dependency! 'cdh4.1.1'
84
85
 
85
86
  # Load JAR files of HBase 0.94.x using Maven
86
87
  HBase.resolve_dependency! '0.94.1'
@@ -102,8 +103,9 @@ as described in [this page](http://maven.apache.org/guides/mini/guide-proxies.ht
102
103
  You may want to suppress (or customize) log messages from HBase.
103
104
 
104
105
  ```ruby
105
- # With an external log4j.properties file
106
+ # With an external log4j.properties or log4j.xml file
106
107
  HBase.log4j = '/your/log4j.properties'
108
+ HBase.log4j = '/your/log4j.xml'
107
109
 
108
110
  # With a Hash
109
111
  HBase.log4j = { 'log4j.threshold' => 'ERROR' }
@@ -9,6 +9,7 @@ class HBase
9
9
  # @private
10
10
  SUPPORTED_PROFILES = {
11
11
  # Prefix => Latest version
12
+ 'cdh4.2' => 'cdh4.2.0',
12
13
  'cdh4.1' => 'cdh4.1.3',
13
14
  'cdh3' => 'cdh3u5',
14
15
  '0.94' => '0.94.3',
@@ -18,7 +19,7 @@ class HBase
18
19
  class << self
19
20
  # @overload resolve_dependency!(dist, options)
20
21
  # Resolve Hadoop and HBase dependency with a predefined Maven profile
21
- # @param [String] dist HBase distribution: cdh4.1, cdh3, 0.94, 0.92, local
22
+ # @param [String] dist HBase distribution: cdh4.2, cdh4.1, cdh3, 0.94, 0.92, local
22
23
  # @param [Hash] options Options
23
24
  # @option options [Boolean] :verbose Enable verbose output
24
25
  # @return [Array<String>] Loaded JAR files
@@ -10,7 +10,7 @@ class HBase
10
10
 
11
11
  # @overload HBase.log4j=(filename)
12
12
  # Configure Log4j logging with the given file
13
- # @param [String] filename Path to log4j.properties file
13
+ # @param [String] filename Path to log4j.properties or log4j.xml file
14
14
  # @return [nil]
15
15
  # @overload HBase.log4j=(hash)
16
16
  # Configure Log4j logging with the given Hash
@@ -26,10 +26,15 @@ class HBase
26
26
  arg.each do |k, v|
27
27
  props.setProperty k.to_s, v.to_s
28
28
  end
29
- arg = props
29
+ org.apache.log4j.PropertyConfigurator.configure props
30
+ else
31
+ case File.extname(arg).downcase
32
+ when '.xml'
33
+ org.apache.log4j.xml.DOMConfigurator.configure arg
34
+ else
35
+ org.apache.log4j.PropertyConfigurator.configure arg
36
+ end
30
37
  end
31
-
32
- org.apache.log4j.PropertyConfigurator.configure arg
33
38
  end
34
39
 
35
40
  # Connects to HBase
@@ -78,6 +83,9 @@ class HBase
78
83
  unless @closed
79
84
  @htable_pool.close
80
85
  HConnectionManager.deleteConnection(@config, true)
86
+ if Thread.current[:hbase_jruby]
87
+ Thread.current[:hbase_jruby].delete(self)
88
+ end
81
89
  @closed = true
82
90
  end
83
91
  end
@@ -4,12 +4,49 @@
4
4
 
5
5
  <groupId>hbase-jruby</groupId>
6
6
  <artifactId>hbase-project</artifactId>
7
- <version>0.2</version>
7
+ <version>0.2.3</version>
8
8
  <packaging>jar</packaging>
9
9
 
10
10
  <name>hbase-jruby</name>
11
11
 
12
12
  <profiles>
13
+ <profile>
14
+ <id>cdh4.2</id>
15
+ <properties>
16
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
17
+ <hadoop.version>2.0.0-<%= profiles['cdh4.2'] %></hadoop.version>
18
+ <hbase.version>0.94.2-<%= profiles['cdh4.2'] %></hbase.version>
19
+ </properties>
20
+ <repositories>
21
+ <repository>
22
+ <id>cloudera-releases</id>
23
+ <url>https://repository.cloudera.com/artifactory/cloudera-repos</url>
24
+ <releases>
25
+ <enabled>true</enabled>
26
+ </releases>
27
+ <snapshots>
28
+ <enabled>false</enabled>
29
+ </snapshots>
30
+ </repository>
31
+ </repositories>
32
+
33
+ <dependencies>
34
+ <dependency>
35
+ <groupId>org.apache.hadoop</groupId>
36
+ <artifactId>hadoop-common</artifactId>
37
+ <version>${hadoop.version}</version>
38
+ <scope>compile</scope>
39
+ </dependency>
40
+
41
+ <dependency>
42
+ <groupId>org.apache.hbase</groupId>
43
+ <artifactId>hbase</artifactId>
44
+ <version>${hbase.version}</version>
45
+ <scope>compile</scope>
46
+ </dependency>
47
+ </dependencies>
48
+ </profile>
49
+
13
50
  <profile>
14
51
  <id>cdh4.1</id>
15
52
  <properties>
@@ -48,6 +48,8 @@ class Scoped
48
48
  # @param [Array<Object>] *rowkeys Rowkeys
49
49
  # @return [Array<HBase::Result>]
50
50
  def get rowkeys
51
+ check_closed
52
+
51
53
  case rowkeys
52
54
  when Array
53
55
  htable.get(rowkeys.map { |rk| getify rk }).map { |result|
@@ -63,6 +65,8 @@ class Scoped
63
65
  # @yield [row] Yields each row in the scope
64
66
  # @yieldparam [HBase::Result] row
65
67
  def each
68
+ check_closed
69
+
66
70
  if block_given?
67
71
  begin
68
72
  scanner = htable.getScanner(filtered_scan)
@@ -531,9 +535,12 @@ private
531
535
  }
532
536
  end
533
537
 
538
+ # Scanner for just counting records
539
+ # @private
534
540
  def filtered_scan_minimum
535
541
  filtered_scan.tap do |scan|
536
542
  scan.cache_blocks = false
543
+ scan.setMaxVersions 1
537
544
 
538
545
  # A filter that will only return the first KV from each row
539
546
  # A filter that will only return the key component of each KV
@@ -605,6 +612,10 @@ private
605
612
  [val]
606
613
  end
607
614
  end
615
+
616
+ def check_closed
617
+ raise RuntimeError, "HBase connection is already closed" if @table.closed?
618
+ end
608
619
  end#Scoped
609
620
  end#HBase
610
621
 
@@ -24,6 +24,8 @@ module Aggregation
24
24
  # @param [Symbol, org.apache.hadoop.hbase.coprocessor.ColumnInterpreter] type
25
25
  # Column type (only :fixnum is supported as of now) or ColumnInterpreter object used to decode the value
26
26
  def aggregate op, type = :fixnum
27
+ check_closed
28
+
27
29
  aggregation_impl op, type
28
30
  end
29
31
 
@@ -16,11 +16,13 @@ class Table
16
16
  include HBase::Util
17
17
 
18
18
  # (INTERNAL) Returns the underlying org.apache.hadoop.hbase.client.HTable object (local to current thread)
19
- # @return [org.apache.hadoop.hbase.client.HTable]
19
+ # @return [org.apache.hadoop.hbase.client.PooledHTable]
20
20
  def htable
21
21
  check_closed
22
22
 
23
- local_htables = Thread.current[:htable] ||= {}
23
+ # [:hbase_jruby][HBase connection][Table name]
24
+ local_vars = Thread.current[:hbase_jruby] ||= {}
25
+ local_htables = local_vars[@hbase] ||= {}
24
26
  local_htables[@name] ||= @pool.get_table(@name)
25
27
  end
26
28
 
@@ -30,6 +32,12 @@ class Table
30
32
  nil
31
33
  end
32
34
 
35
+ # Returns whether if the connection is closed
36
+ # @return [Boolean]
37
+ def closed?
38
+ @hbase.closed?
39
+ end
40
+
33
41
  [:get, :count, :aggregate,
34
42
  :range, :project, :filter, :while,
35
43
  :limit, :versions, :caching, :batch,
@@ -59,6 +67,8 @@ class Table
59
67
  # @param [Hash<Hash>] data Data to put indexed by rowkeys
60
68
  # @return [Fixnum] Number of puts succeeded
61
69
  def put *args
70
+ check_closed
71
+
62
72
  return put(args.first => args.last) if args.length == 2
63
73
 
64
74
  puts = args.first.map { |rowkey, props| putify rowkey, props }
@@ -106,6 +116,8 @@ class Table
106
116
  # ['a002', 'cf1'],
107
117
  # ['a003'])
108
118
  def delete *args
119
+ check_closed
120
+
109
121
  specs = args.first.is_a?(Array) ? args : [args]
110
122
 
111
123
  htable.delete specs.map { |spec|
@@ -131,6 +143,8 @@ class Table
131
143
  # @param [*Object] rowkeys List of rowkeys of rows to delete
132
144
  # @return [nil]
133
145
  def delete_row *rowkeys
146
+ check_closed
147
+
134
148
  htable.delete rowkeys.map { |rk| Delete.new(Util.to_bytes rk) }
135
149
  end
136
150
 
@@ -150,6 +164,8 @@ class Table
150
164
  # @example
151
165
  # table.increment('a000', 'cf1:col1' => 1, 'cf1:col2' => 2)
152
166
  def increment rowkey, *args
167
+ check_closed
168
+
153
169
  if args.first.is_a?(Hash)
154
170
  cols = args.first
155
171
  htable.increment Increment.new(Util.to_bytes rowkey).tap { |inc|
@@ -1,5 +1,5 @@
1
1
  class HBase
2
2
  module JRuby
3
- VERSION = "0.2.2"
3
+ VERSION = "0.2.3"
4
4
  end
5
5
  end
data/test/helper.rb CHANGED
@@ -24,8 +24,12 @@ class TestHBaseJRubyBase < Test::Unit::TestCase
24
24
  end
25
25
  hbase.close
26
26
 
27
+ def connect
28
+ HBase.new 'hbase.zookeeper.quorum' => ZK
29
+ end
30
+
27
31
  def setup
28
- @hbase ||= HBase.new 'hbase.zookeeper.quorum' => ZK
32
+ @hbase = connect
29
33
  @table = @hbase.table(TABLE)
30
34
 
31
35
  # Drop & Create
@@ -47,5 +51,6 @@ class TestHBaseJRubyBase < Test::Unit::TestCase
47
51
  if RECREATE
48
52
  @table.drop! if @table && @table.exists?
49
53
  end
54
+ @hbase.close
50
55
  end
51
56
  end
data/test/test_hbase.rb CHANGED
@@ -4,6 +4,17 @@ $LOAD_PATH.unshift File.expand_path('..', __FILE__)
4
4
  require 'helper'
5
5
 
6
6
  class TestHBase < TestHBaseJRubyBase
7
+ def test_log4j
8
+ HBase.log4j = File.expand_path('../log4j/log4j.properties', __FILE__)
9
+ HBase.log4j = File.expand_path('../log4j/log4j.xml', __FILE__)
10
+
11
+ begin
12
+ HBase.log4j = File.expand_path('../log4j/log4j_invalid.xml', __FILE__)
13
+ assert false, "Exception must be thrown when invalid XML is given"
14
+ rescue Exception
15
+ end
16
+ end
17
+
7
18
  def test_tables
8
19
  assert @hbase.table_names.include?(TABLE)
9
20
  assert @hbase.list.include?(TABLE)
@@ -15,13 +26,34 @@ class TestHBase < TestHBaseJRubyBase
15
26
  table.exists?
16
27
  assert @hbase.list.is_a?(Array)
17
28
 
29
+ assert_equal table.htable, Thread.current[:hbase_jruby][@hbase][TABLE]
30
+
18
31
  assert !@hbase.closed?
32
+ assert !table.closed?
19
33
  @hbase.close
20
34
  assert @hbase.closed?
35
+ assert table.closed?
36
+
37
+ assert !Thread.current[:hbase_jruby].has_key?(@hbase)
21
38
 
22
39
  assert_raise(RuntimeError) { @hbase.list }
23
40
  assert_raise(RuntimeError) { table.exists? }
24
41
  assert_raise(RuntimeError) { table.drop! }
42
+ # ...
43
+
44
+ # get, delete, put, delete_row, increment, each
45
+ assert_raise(RuntimeError) { table.first }
46
+ assert_raise(RuntimeError) { table.get :key }
47
+ assert_raise(RuntimeError) { table.put :key => {'cf1:a' => 100} }
48
+ assert_raise(RuntimeError) { table.delete :key }
49
+ assert_raise(RuntimeError) { table.delete_row :key }
50
+ assert_raise(RuntimeError) { table.increment :key, 'cf1:a' => 1 }
51
+ assert_raise(RuntimeError) { table.project('cf1:a').aggregate(:row_count) }
52
+
53
+ # Reconnect and check
54
+ @hbase = connect
55
+ table = @hbase[TABLE]
56
+ assert_equal table.htable, Thread.current[:hbase_jruby][@hbase][TABLE]
25
57
  end
26
58
 
27
59
  def test_admin
metadata CHANGED
@@ -2,14 +2,14 @@
2
2
  name: hbase-jruby
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.2.2
5
+ version: 0.2.3
6
6
  platform: java
7
7
  authors:
8
8
  - Junegunn Choi
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-13 00:00:00.000000000 Z
12
+ date: 2013-03-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: test-unit