diff --git a/conf/zeppelin-site.xml.template b/conf/zeppelin-site.xml.template
index 9ca740d139d..467c1d58733 100755
--- a/conf/zeppelin-site.xml.template
+++ b/conf/zeppelin-site.xml.template
@@ -105,7 +105,7 @@
zeppelin.interpreters
- org.apache.zeppelin.spark.SparkInterpreter,org.apache.zeppelin.spark.PySparkInterpreter,org.apache.zeppelin.spark.SparkSqlInterpreter,org.apache.zeppelin.spark.DepInterpreter,org.apache.zeppelin.markdown.Markdown,org.apache.zeppelin.angular.AngularInterpreter,org.apache.zeppelin.shell.ShellInterpreter,org.apache.zeppelin.hive.HiveInterpreter,org.apache.zeppelin.tajo.TajoInterpreter,org.apache.zeppelin.flink.FlinkInterpreter,org.apache.zeppelin.lens.LensInterpreter,org.apache.zeppelin.ignite.IgniteInterpreter,org.apache.zeppelin.ignite.IgniteSqlInterpreter,org.apache.zeppelin.cassandra.CassandraInterpreter,org.apache.zeppelin.geode.GeodeOqlInterpreter,org.apache.zeppelin.postgresql.PostgreSqlInterpreter,org.apache.zeppelin.jdbc.JDBCInterpreter,org.apache.zeppelin.phoenix.PhoenixInterpreter,org.apache.zeppelin.kylin.KylinInterpreter,org.apache.zeppelin.elasticsearch.ElasticsearchInterpreter,org.apache.zeppelin.scalding.ScaldingInterpreter,org.apache.zeppelin.tachyon.TachyonInterpreter
+ org.apache.zeppelin.spark.SparkInterpreter,org.apache.zeppelin.spark.PySparkInterpreter,org.apache.zeppelin.spark.SparkSqlInterpreter,org.apache.zeppelin.spark.DepInterpreter,org.apache.zeppelin.markdown.Markdown,org.apache.zeppelin.angular.AngularInterpreter,org.apache.zeppelin.shell.ShellInterpreter,org.apache.zeppelin.hive.HiveInterpreter,org.apache.zeppelin.tajo.TajoInterpreter,org.apache.zeppelin.flink.FlinkInterpreter,org.apache.zeppelin.lens.LensInterpreter,org.apache.zeppelin.ignite.IgniteInterpreter,org.apache.zeppelin.ignite.IgniteSqlInterpreter,org.apache.zeppelin.cassandra.CassandraInterpreter,org.apache.zeppelin.geode.GeodeOqlInterpreter,org.apache.zeppelin.postgresql.PostgreSqlInterpreter,org.apache.zeppelin.jdbc.JDBCInterpreter,org.apache.zeppelin.phoenix.PhoenixInterpreter,org.apache.zeppelin.kylin.KylinInterpreter,org.apache.zeppelin.elasticsearch.ElasticsearchInterpreter,org.apache.zeppelin.scalding.ScaldingInterpreter,org.apache.zeppelin.tachyon.TachyonInterpreter,org.apache.zeppelin.hbase.HbaseInterpreter
Comma separated interpreter configurations. First interpreter become a default
diff --git a/docs/_includes/themes/zeppelin/_navigation.html b/docs/_includes/themes/zeppelin/_navigation.html
index d0581b14549..fac700defa1 100644
--- a/docs/_includes/themes/zeppelin/_navigation.html
+++ b/docs/_includes/themes/zeppelin/_navigation.html
@@ -43,6 +43,7 @@
Elasticsearch
Flink
Geode
+ HBase
Hive
Ignite
Lens
diff --git a/docs/interpreter/hbase.md b/docs/interpreter/hbase.md
new file mode 100644
index 00000000000..30cec44b25a
--- /dev/null
+++ b/docs/interpreter/hbase.md
@@ -0,0 +1,57 @@
+---
+layout: page
+title: "HBase Shell Interpreter"
+description: ""
+group: manual
+---
+{% include JB/setup %}
+
+
+## HBase Shell Interpreter for Apache Zeppelin
+[HBase Shell](http://hbase.apache.org/book.html#shell) is a JRuby IRB client for Apache HBase.
+This interpreter provides all capabilities of Apache HBase shell within Apache Zeppelin. The
+interpreter assumes that Apache HBase client software has been installed and its possible to
+connect to the Apache HBase cluster from the machine on where Apache Zeppelin is installed.
+
+
+## 1. Configuration
+
+
+
+ | Property |
+ Default |
+ Description |
+
+
+ | hbase.home |
+ /usr/lib/hbase |
+ Installation directory of Hbase |
+
+
+ | hbase.ruby.sources |
+ lib/ruby |
+ Path to Ruby scripts relative to 'hbase.home' |
+
+
+ | hbase.test.mode |
+ false |
+ Disable checks for unit and manual tests |
+
+
+
+## 2. Enabling the HBase Shell Interpreter
+
+In a notebook, to enable the **HBase Shell** interpreter, click the **Gear** icon and select
+**HBase Shell**.
+
+## 3. Using the HBase Shell Interpreter
+
+In a paragraph, use `%hbase` to select the **HBase Shell** interpreter and then input all commands.
+ To get the list of available commands, use `help`.
+
+```bash
+| %hbase
+| help
+```
+
+For more information on all commands available, refer to [HBase Shell Documentation](http://hbase.apache.org/book.html#shell)
\ No newline at end of file
diff --git a/hbase/pom.xml b/hbase/pom.xml
new file mode 100644
index 00000000000..f70ef88cf1e
--- /dev/null
+++ b/hbase/pom.xml
@@ -0,0 +1,176 @@
+
+
+
+ 4.0.0
+
+ zeppelin
+ org.apache.zeppelin
+ 0.6.0-incubating-SNAPSHOT
+
+
+ org.apache.zeppelin
+ zeppelin-hbase
+ jar
+ 0.6.0-incubating-SNAPSHOT
+ Zeppelin: HBase interpreter
+ http://www.apache.org
+
+
+ 1.0.0
+ 2.6.0
+ 1.6.8
+ 2.5.0
+
+
+
+
+ ${project.groupId}
+ zeppelin-interpreter
+ ${project.version}
+ provided
+
+
+
+ org.apache.commons
+ commons-exec
+ 1.1
+
+
+
+ junit
+ junit
+ 4.11
+ test
+
+
+ org.hamcrest
+ hamcrest-all
+ 1.3
+ test
+
+
+ org.jruby
+ jruby-complete
+ ${jruby.version}
+
+
+ org.apache.hadoop
+ hadoop-yarn-common
+ ${hbase.hadoop.version}
+
+
+ org.apache.hadoop
+ hadoop-yarn-api
+ ${hbase.hadoop.version}
+
+
+ org.apache.hbase
+ hbase-client
+ ${hbase.hbase.version}
+
+
+ org.apache.hbase
+ hbase-annotations
+ ${hbase.hbase.version}
+
+
+ com.google.protobuf
+ protobuf-java
+ ${protobuf.version}
+
+
+ org.apache.hbase
+ hbase-server
+ ${hbase.hbase.version}
+
+
+ jline
+ jline
+ 2.12.1
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+ 2.7
+
+ true
+
+
+
+
+ maven-enforcer-plugin
+ 1.3.1
+
+
+ enforce
+ none
+
+
+
+
+
+ maven-dependency-plugin
+ 2.8
+
+
+ copy-dependencies
+ package
+
+ copy-dependencies
+
+
+ ${project.build.directory}/../../interpreter/hbase
+ false
+ false
+ true
+ runtime
+
+
+
+ copy-artifact
+ package
+
+ copy
+
+
+ ${project.build.directory}/../../interpreter/hbase
+ false
+ false
+ true
+ runtime
+
+
+ ${project.groupId}
+ ${project.artifactId}
+ ${project.version}
+ ${project.packaging}
+
+
+
+
+
+
+
+
+
diff --git a/hbase/src/main/java/org/apache/zeppelin/hbase/HbaseInterpreter.java b/hbase/src/main/java/org/apache/zeppelin/hbase/HbaseInterpreter.java
new file mode 100644
index 00000000000..dbcb33d4d99
--- /dev/null
+++ b/hbase/src/main/java/org/apache/zeppelin/hbase/HbaseInterpreter.java
@@ -0,0 +1,158 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.zeppelin.hbase;
+
+import org.apache.zeppelin.interpreter.*;
+import org.apache.zeppelin.scheduler.Scheduler;
+import org.apache.zeppelin.scheduler.SchedulerFactory;
+import org.jruby.embed.LocalContextScope;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.jruby.embed.ScriptingContainer;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * Support for Hbase Shell. All the commands documented here
+ * http://hbase.apache.org/book.html#shell is supported.
+ *
+ * Requirements:
+ * Hbase Shell should be installed on the same machine. To be more specific, the following dir.
+ * should be available: https://github.com/apache/hbase/tree/master/hbase-shell/src/main/ruby
+ * Hbase Shell should be able to connect to the Hbase cluster from terminal. This makes sure
+ * that the client is configured properly.
+ *
+ * The interpreter takes 3 config parameters:
+ * hbase.home: Root dir. where hbase is installed. Default is /usr/lib/hbase/
+ * hbase.ruby.sources: Dir where shell ruby code is installed.
+ * Path is relative to hbase.home. Default: lib/ruby
+ * hbase.irb.load: (Testing only) Default is true.
+ * Whether to load irb in the interpreter.
+ */
+public class HbaseInterpreter extends Interpreter {
+ private Logger logger = LoggerFactory.getLogger(HbaseInterpreter.class);
+ private ScriptingContainer scriptingContainer;
+
+ private StringWriter writer;
+
+ static {
+ Interpreter.register("hbase", "hbase", HbaseInterpreter.class.getName(),
+ new InterpreterPropertyBuilder()
+ .add("hbase.home", "/usr/lib/hbase/", "Installation dir. of Hbase")
+ .add("hbase.ruby.sources", "lib/ruby",
+ "Path to Ruby scripts relative to 'hbase.home'")
+ .add("hbase.test.mode", "false", "Disable checks for unit and manual tests")
+ .build());
+ }
+
+ public HbaseInterpreter(Properties property) {
+ super(property);
+ }
+
+ @Override
+ public void open() {
+ this.scriptingContainer = new ScriptingContainer(LocalContextScope.SINGLETON);
+ this.writer = new StringWriter();
+ scriptingContainer.setOutput(this.writer);
+
+ if (!Boolean.parseBoolean(getProperty("hbase.test.mode"))) {
+ String hbase_home = getProperty("hbase.home");
+ String ruby_src = getProperty("hbase.ruby.sources");
+ Path abs_ruby_src = Paths.get(hbase_home, ruby_src).toAbsolutePath();
+
+ logger.info("Home:" + hbase_home);
+ logger.info("Ruby Src:" + ruby_src);
+
+ File f = abs_ruby_src.toFile();
+ if (!f.exists() || !f.isDirectory()) {
+ throw new InterpreterException("hbase ruby sources is not available at '" + abs_ruby_src
+ + "'");
+ }
+
+ logger.info("Absolute Ruby Source:" + abs_ruby_src.toString());
+ // hirb.rb:41 requires the following system property to be set.
+ Properties sysProps = System.getProperties();
+ sysProps.setProperty("hbase.ruby.sources", abs_ruby_src.toString());
+
+ Path abs_hirb_path = Paths.get(hbase_home, "bin/hirb.rb");
+ try {
+ FileInputStream fis = new FileInputStream(abs_hirb_path.toFile());
+ this.scriptingContainer.runScriptlet(fis, "hirb.rb");
+ fis.close();
+ } catch (IOException e) {
+ throw new InterpreterException(e.getCause());
+ }
+ }
+ }
+
+ @Override
+ public void close() {
+ if (this.scriptingContainer != null) {
+ this.scriptingContainer.terminate();
+ }
+ }
+
+ @Override
+ public InterpreterResult interpret(String cmd, InterpreterContext interpreterContext) {
+ try {
+ logger.info(cmd);
+ this.writer.getBuffer().setLength(0);
+ this.scriptingContainer.runScriptlet(cmd);
+ this.writer.flush();
+ logger.debug(writer.toString());
+ return new InterpreterResult(InterpreterResult.Code.SUCCESS, writer.getBuffer().toString());
+ } catch (Throwable t) {
+ logger.error("Can not run '" + cmd + "'", t);
+ return new InterpreterResult(InterpreterResult.Code.ERROR, t.getMessage());
+ }
+ }
+
+ @Override
+ public void cancel(InterpreterContext context) {}
+
+ @Override
+ public FormType getFormType() {
+ return FormType.SIMPLE;
+ }
+
+ @Override
+ public int getProgress(InterpreterContext context) {
+ return 0;
+ }
+
+ @Override
+ public Scheduler getScheduler() {
+ return SchedulerFactory.singleton().createOrGetFIFOScheduler(
+ HbaseInterpreter.class.getName() + this.hashCode());
+ }
+
+ @Override
+ public List completion(String buf, int cursor) {
+ return null;
+ }
+
+}
diff --git a/hbase/src/test/java/org/apache/zeppelin/hbase/HbaseInterpreterTest.java b/hbase/src/test/java/org/apache/zeppelin/hbase/HbaseInterpreterTest.java
new file mode 100644
index 00000000000..e2180702fce
--- /dev/null
+++ b/hbase/src/test/java/org/apache/zeppelin/hbase/HbaseInterpreterTest.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.zeppelin.hbase;
+
+import org.apache.log4j.BasicConfigurator;
+import org.apache.zeppelin.interpreter.InterpreterResult;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Properties;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Tests for HBase Interpreter
+ */
+public class HbaseInterpreterTest {
+ private static Logger logger = LoggerFactory.getLogger(HbaseInterpreterTest.class);
+ private static HbaseInterpreter hbaseInterpreter;
+
+ @BeforeClass
+ public static void setUp() throws NullPointerException {
+ BasicConfigurator.configure();
+ Properties properties = new Properties();
+ properties.put("hbase.home", "");
+ properties.put("hbase.ruby.sources", "");
+ properties.put("hbase.test.mode", "true");
+
+ hbaseInterpreter = new HbaseInterpreter(properties);
+ hbaseInterpreter.open();
+ }
+
+ @Test
+ public void newObject() {
+ assertThat(hbaseInterpreter, notNullValue());
+ }
+
+ @Test
+ public void putsTest() {
+ InterpreterResult result = hbaseInterpreter.interpret("puts \"Hello World\"", null);
+ assertEquals(InterpreterResult.Code.SUCCESS, result.code());
+ assertEquals(result.type(), InterpreterResult.Type.TEXT);
+ assertEquals("Hello World\n", result.message());
+ }
+
+ public void putsLoadPath() {
+ InterpreterResult result = hbaseInterpreter.interpret("require 'two_power'; puts twoToThePowerOf(4)", null);
+ assertEquals(InterpreterResult.Code.SUCCESS, result.code());
+ assertEquals(result.type(), InterpreterResult.Type.TEXT);
+ assertEquals("16\n", result.message());
+ }
+
+ @Test
+ public void testException() {
+ InterpreterResult result = hbaseInterpreter.interpret("plot practical joke", null);
+ assertEquals(InterpreterResult.Code.ERROR, result.code());
+ assertEquals("(NameError) undefined local variable or method `joke' for main:Object", result.message());
+ }
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index d73caf39a3b..736791f9f7b 100755
--- a/pom.xml
+++ b/pom.xml
@@ -92,6 +92,7 @@
angular
shell
hive
+ hbase
phoenix
postgresql
jdbc
diff --git a/zeppelin-distribution/src/bin_license/LICENSE b/zeppelin-distribution/src/bin_license/LICENSE
index 36e983654bd..a12b9c44454 100644
--- a/zeppelin-distribution/src/bin_license/LICENSE
+++ b/zeppelin-distribution/src/bin_license/LICENSE
@@ -37,6 +37,7 @@ The following components are provided under Apache License.
(Apache 2.0) Apache Cassandra (http://cassandra.apache.org/)
(Apache 2.0) Apache CXF (http://cxf.apache.org/)
(Apache 2.0) Apache Hive (http://hive.apache.org/)
+ (Apache 2.0) Apache HBase (http://hbase.apache.org/)
(Apache 2.0) Apache Ignite (http://ignite.apache.org/)
(Apache 2.0) Apache Kylin (http://kylin.apache.org/)
(Apache 2.0) Apache Lens (http://lens.apache.org/)
@@ -94,6 +95,7 @@ The following components are provided under Apache License.
(Apache 2.0) Shiro Core (org.apache.shiro:shiro-core:1.2.3 - https://shiro.apache.org)
(Apache 2.0) Shiro Web (org.apache.shiro:shiro-web:1.2.3 - https://shiro.apache.org)
(Apache 2.0) SnakeYAML (org.yaml:snakeyaml:1.15 - http://www.snakeyaml.org)
+ (Apache 2.0) Protocol Buffers (com.google.protobuf:protobuf-java:2.4.1 - https://github.com/google/protobuf/releases)
(Apache 2.0) Tachyon Shell (org.tachyonproject:tachyon-shell:0.8.2 - http://tachyon-project.org)
(Apache 2.0) Tachyon Servers (org.tachyonproject:tachyon-servers:0.8.2 - http://tachyon-project.org)
(Apache 2.0) Tachyon Minicluster (org.tachyonproject:tachyon-minicluster:0.8.2 - http://tachyon-project.org)
@@ -154,6 +156,8 @@ The text of each license is also included at licenses/LICENSE-[project]-[version
(BSD Style) dom4j v1.6.1 (http://www.dom4j.org) - https://github.com/dom4j/dom4j/blob/dom4j_1_6_1/LICENSE.txt
(BSD Style) JSch v0.1.53 (http://www.jcraft.com) - http://www.jcraft.com/jsch/LICENSE.txt
(BSD 3 Clause) highlightjs v8.4.0 (https://highlightjs.org/) - https://github.com/isagalaev/highlight.js/blob/8.4/LICENSE
+ (BSD 3 Clause) hamcrest v1.3 (http://hamcrest.org/JavaHamcrest/) - http://opensource.org/licenses/BSD-3-Clause
+ (BSD Style) JLine v2.12.1 (https://github.com/jline/jline2) - https://github.com/jline/jline2/blob/master/LICENSE.txt
@@ -194,6 +198,7 @@ The following components are provided under the EPL License.
(EPL 1.0) Aether (org.sonatype.aether - http://www.eclipse.org/aether/)
(EPL 1.0) JDT Annotations For Enhanced Null Analysis (org.eclipse.jdt:org.eclipse.jdt.annotation:1.1.0 - https://repo.eclipse.org/content/repositories/eclipse-releases/org/eclipse/jdt/org.eclipse.jdt.annotation)
+ (EPL 1.0) JRuby (org.jruby.jruby-complete:v1.6.8 - http://www.jruby.org/)
========================================================================
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java
index 9e606ee2105..3088cfb7731 100755
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java
@@ -454,7 +454,8 @@ public static enum ConfVars {
+ "org.apache.zeppelin.kylin.KylinInterpreter,"
+ "org.apache.zeppelin.elasticsearch.ElasticsearchInterpreter,"
+ "org.apache.zeppelin.scalding.ScaldingInterpreter,"
- + "org.apache.zeppelin.jdbc.JDBCInterpreter"),
+ + "org.apache.zeppelin.jdbc.JDBCInterpreter,"
+ + "org.apache.zeppelin.hbase.HbaseInterpreter"),
ZEPPELIN_INTERPRETER_DIR("zeppelin.interpreter.dir", "interpreter"),
ZEPPELIN_INTERPRETER_CONNECT_TIMEOUT("zeppelin.interpreter.connect.timeout", 30000),
ZEPPELIN_INTERPRETER_MAX_POOL_SIZE("zeppelin.interpreter.max.poolsize", 10),