@@ -241,55 +242,14 @@
maven-enforcer-plugin
-
-
- enforce
- none
-
-
-
maven-dependency-plugin
-
-
- copy-dependencies
- package
-
- copy-dependencies
-
-
- ${project.build.directory}/../../interpreter/cassandra
- false
- false
- true
- runtime
-
-
-
- copy-artifact
- package
-
- copy
-
-
- ${project.build.directory}/../../interpreter/cassandra
- false
- false
- true
- runtime
-
-
- ${project.groupId}
- ${project.artifactId}
- ${project.version}
- ${project.packaging}
-
-
-
-
-
+
+
+ maven-resources-plugin
+
diff --git a/conf/zeppelin-site.xml.template b/conf/zeppelin-site.xml.template
index f1bfb61038..b25ba19c80 100755
--- a/conf/zeppelin-site.xml.template
+++ b/conf/zeppelin-site.xml.template
@@ -181,13 +181,13 @@
- zeppelin.hdfs.keytab
+ zeppelin.server.kerberos.keytab
keytab for accessing kerberized hdfs
- zeppelin.hdfs.principal
+ zeppelin.server.kerberos.principal
principal for accessing kerberized hdfs
diff --git a/docs/_includes/themes/zeppelin/_navigation.html b/docs/_includes/themes/zeppelin/_navigation.html
index ecdccbd7ff..215c94426a 100644
--- a/docs/_includes/themes/zeppelin/_navigation.html
+++ b/docs/_includes/themes/zeppelin/_navigation.html
@@ -137,6 +137,7 @@
Lens
Livy
Markdown
+ Neo4j
Pig
Postgresql, HAWQ
R
diff --git a/docs/assets/themes/zeppelin/img/docs-img/neo4j-config.png b/docs/assets/themes/zeppelin/img/docs-img/neo4j-config.png
new file mode 100644
index 0000000000..2de3699e8a
Binary files /dev/null and b/docs/assets/themes/zeppelin/img/docs-img/neo4j-config.png differ
diff --git a/docs/assets/themes/zeppelin/img/docs-img/neo4j-dynamic-forms.png b/docs/assets/themes/zeppelin/img/docs-img/neo4j-dynamic-forms.png
new file mode 100644
index 0000000000..177e0a5e76
Binary files /dev/null and b/docs/assets/themes/zeppelin/img/docs-img/neo4j-dynamic-forms.png differ
diff --git a/docs/assets/themes/zeppelin/img/docs-img/neo4j-graph.png b/docs/assets/themes/zeppelin/img/docs-img/neo4j-graph.png
new file mode 100644
index 0000000000..396b960db6
Binary files /dev/null and b/docs/assets/themes/zeppelin/img/docs-img/neo4j-graph.png differ
diff --git a/docs/assets/themes/zeppelin/img/docs-img/neo4j-interpreter-video.gif b/docs/assets/themes/zeppelin/img/docs-img/neo4j-interpreter-video.gif
new file mode 100644
index 0000000000..28c191516f
Binary files /dev/null and b/docs/assets/themes/zeppelin/img/docs-img/neo4j-interpreter-video.gif differ
diff --git a/docs/development/writing_zeppelin_interpreter.md b/docs/development/writing_zeppelin_interpreter.md
index 6ba24bc44a..f4c0bc939d 100644
--- a/docs/development/writing_zeppelin_interpreter.md
+++ b/docs/development/writing_zeppelin_interpreter.md
@@ -40,7 +40,49 @@ In 'Separate Interpreter(scoped / isolated) for each note' mode which you can se
## Make your own Interpreter
Creating a new interpreter is quite simple. Just extend [org.apache.zeppelin.interpreter](https://github.com/apache/zeppelin/blob/master/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/Interpreter.java) abstract class and implement some methods.
-You can include `org.apache.zeppelin:zeppelin-interpreter:[VERSION]` artifact in your build system. And you should put your jars under your interpreter directory with a specific directory name. Zeppelin server reads interpreter directories recursively and initializes interpreters including your own interpreter.
+For your interpreter project, you need to make `interpreter-parent` as your parent project and use plugin `maven-enforcer-plugin`, `maven-dependency-plugin` and `maven-resources-plugin`. Here's one sample pom.xml
+
+```
+
+ 4.0.0
+
+
+ interpreter-parent
+ org.apache.zeppelin
+ 0.8.0-SNAPSHOT
+ ../interpreter-parent
+
+
+ ...
+
+
+
+ org.apache.zeppelin
+ zeppelin-interpreter
+ ${project.version}
+ provided
+
+
+
+
+
+
+ maven-enforcer-plugin
+
+
+ maven-dependency-plugin
+
+
+ maven-resources-plugin
+
+
+
+
+
+```
+
+You should include `org.apache.zeppelin:zeppelin-interpreter:[VERSION]` as your interpreter's dependency in `pom.xml`. Bes
+And you should put your jars under your interpreter directory with a specific directory name. Zeppelin server reads interpreter directories recursively and initializes interpreters including your own interpreter.
There are three locations where you can store your interpreter group, name and other information. Zeppelin server tries to find the location below. Next, Zeppelin tries to find `interpreter-setting.json` in your interpreter jar.
diff --git a/docs/index.md b/docs/index.md
index 5e991f1903..dbec0402d9 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -142,6 +142,7 @@ limitations under the License.
* [Lens](./interpreter/lens.html)
* [Livy](./interpreter/livy.html)
* [markdown](./interpreter/markdown.html)
+ * [Neo4j](./interpreter/neo4j.html)
* [Pig](./interpreter/pig.html)
* [Postgresql, HAWQ](./interpreter/postgresql.html)
* [Python](./interpreter/python.html)
diff --git a/docs/interpreter/livy.md b/docs/interpreter/livy.md
index 1741a80c8b..09bf6e1c27 100644
--- a/docs/interpreter/livy.md
+++ b/docs/interpreter/livy.md
@@ -144,7 +144,12 @@ Example: `spark.driver.memory` to `livy.spark.driver.memory`
zeppelin.livy.ssl.trustStorePassword
password for trustStore file. Used when livy ssl is enabled
-
+
+
+ zeppelin.livy.http.headers
+ key_1: value_1; key_2: value_2
+ custom http headers when calling livy rest api. Each http header is separated by `;`, and each header is one key value pair where key value is separated by `:`
+
**We remove livy.spark.master in zeppelin-0.7. Because we sugguest user to use livy 0.3 in zeppelin-0.7. And livy 0.3 don't allow to specify livy.spark.master, it enfornce yarn-cluster mode.**
diff --git a/docs/interpreter/neo4j.md b/docs/interpreter/neo4j.md
new file mode 100644
index 0000000000..37f1f8c935
--- /dev/null
+++ b/docs/interpreter/neo4j.md
@@ -0,0 +1,117 @@
+---
+layout: page
+title: "Neo4j Interpreter for Apache Zeppelin"
+description: "Neo4j is a native graph database, designed to store and process graphs from bottom to top."
+group: interpreter
+---
+
+{% include JB/setup %}
+
+# Neo4j Interpreter for Apache Zeppelin
+
+
+
+## Overview
+[Neo4j](https://neo4j.com/product/) is a native graph database, designed to store and process graphs from bottom to top.
+
+
+
+
+## Configuration
+
+
+ Property
+ Default
+ Description
+
+
+ neo4j.url
+ bolt://localhost:7687
+ The Neo4j's BOLT url.
+
+
+ neo4j.auth.type
+ BASIC
+ The Neo4j's authentication type (NONE, BASIC).
+
+
+ neo4j.auth.user
+ neo4j
+ The Neo4j user name.
+
+
+ neo4j.auth.password
+ neo4j
+ The Neo4j user password.
+
+
+ neo4j.max.concurrency
+ 50
+ Max concurrency call from Zeppelin to Neo4j server.
+
+
+
+
+ 
+
+
+
+## Enabling the Neo4j Interpreter
+In a notebook, to enable the **Neo4j** interpreter, click the **Gear** icon and select **Neo4j**.
+
+## Using the Neo4j Interpreter
+In a paragraph, use `%neo4j` to select the Neo4j interpreter and then input the Cypher commands.
+For list of Cypher commands please refer to the official [Cyper Refcard](http://neo4j.com/docs/cypher-refcard/current/)
+
+```bash
+%neo4j
+//Sample the TrumpWorld dataset
+WITH
+'https://docs.google.com/spreadsheets/u/1/d/1Z5Vo5pbvxKJ5XpfALZXvCzW26Cl4we3OaN73K9Ae5Ss/export?format=csv&gid=1996904412' AS url
+LOAD CSV WITH HEADERS FROM url AS row
+RETURN row.`Entity A`, row.`Entity A Type`, row.`Entity B`, row.`Entity B Type`, row.Connection, row.`Source(s)`
+LIMIT 10
+```
+
+The Neo4j interpreter leverages the [Network display system](../usage/display_system/basic.html#network) allowing to visualize the them directly from the paragraph.
+
+
+### Write your Cypher queries and navigate your graph
+
+This query:
+
+```bash
+%neo4j
+MATCH (vp:Person {name:"VLADIMIR PUTIN"}), (dt:Person {name:"DONALD J. TRUMP"})
+MATCH path = allShortestPaths( (vp)-[*]-(dt) )
+RETURN path
+```
+produces the following result_
+
+
+### Apply Zeppelin Dynamic Forms
+You can leverage [Zeppelin Dynamic Form](../usage/dynamic_form/intro.html) inside your queries. This query:
+
+```bash
+%neo4j
+MATCH (o:Organization)-[r]-()
+RETURN o.name, count(*), collect(distinct type(r)) AS types
+ORDER BY count(*) DESC
+LIMIT ${Show top=10}
+```
+
+produces the following result:
+
+
diff --git a/docs/interpreter/spark.md b/docs/interpreter/spark.md
index be5b3e5286..bbd9065faa 100644
--- a/docs/interpreter/spark.md
+++ b/docs/interpreter/spark.md
@@ -181,6 +181,7 @@ For example,
* **local[*]** in local mode
* **spark://master:7077** in standalone cluster
* **yarn-client** in Yarn client mode
+ * **yarn-cluster** in Yarn cluster mode
* **mesos://host:5050** in Mesos cluster
That's it. Zeppelin will work with any version of Spark and any deployment type without rebuilding Zeppelin in this way.
@@ -188,6 +189,11 @@ For the further information about Spark & Zeppelin version compatibility, please
> Note that without exporting `SPARK_HOME`, it's running in local mode with included version of Spark. The included version may vary depending on the build profile.
+### 3. Yarn mode
+Zeppelin support both yarn client and yarn cluster mode (yarn cluster mode is supported from 0.8.0). For yarn mode, you must specify `SPARK_HOME` & `HADOOP_CONF_DIR`.
+You can either specify them in `zeppelin-env.sh`, or in interpreter setting page. Specifying them in `zeppelin-env.sh` means you can use only one version of `spark` & `hadoop`. Specifying them
+in interpreter setting page means you can use multiple versions of `spark` & `hadoop` in one zeppelin instance.
+
## SparkContext, SQLContext, SparkSession, ZeppelinContext
SparkContext, SQLContext and ZeppelinContext are automatically created and exposed as variable names `sc`, `sqlContext` and `z`, respectively, in Scala, Python and R environments.
Staring from 0.6.1 SparkSession is available as variable `spark` when you are using Spark 2.x.
diff --git a/docs/setup/operation/configuration.md b/docs/setup/operation/configuration.md
index e91a7df2ba..21ae5b3a60 100644
--- a/docs/setup/operation/configuration.md
+++ b/docs/setup/operation/configuration.md
@@ -77,7 +77,19 @@ If both are defined, then the **environment variables** will take priority.
*
Enables a way to specify a ',' separated list of allowed origins for REST and websockets. e.g. http://localhost:8080
-
+
+ ZEPPELIN_CREDENTIALS_PERSIST
+ zeppelin.credentials.persist
+ true
+ Persist credentials on a JSON file (credentials.json)
+
+
+ ZEPPELIN_CREDENTIALS_ENCRYPT_KEY
+ zeppelin.credentials.encryptKey
+
+ If provided, encrypt passwords on the credentials.json file (passwords will be stored as plain-text otherwise
+
+
N/A
zeppelin.anonymous.allowed
true
@@ -411,6 +423,20 @@ The following properties needs to be updated in the `zeppelin-site.xml` in order
```
+### Storing user credentials
+
+In order to avoid having to re-enter credentials every time you restart/redeploy Zeppelin, you can store the user credentials. Zeppelin supports this via the ZEPPELIN_CREDENTIALS_PERSIST configuration.
+
+Please notice that passwords will be stored in *plain text* by default. To encrypt the passwords, use the ZEPPELIN_CREDENTIALS_ENCRYPT_KEY config variable. This will encrypt passwords using the AES-128 algorithm.
+
+You can generate an appropriate encryption key any way you'd like - for instance, by using the openssl tool:
+
+```
+openssl enc -aes-128-cbc -k secret -P -md sha1
+```
+
+*Important*: storing your encryption key in a configuration file is _not advised_. Depending on your environment security needs, you may want to consider utilizing a credentials server, storing the ZEPPELIN_CREDENTIALS_ENCRYPT_KEY as an OS env variable, or any other approach that would not colocate the encryption key and the encrypted content (the credentials.json file).
+
### Obfuscating Passwords using the Jetty Password Tool
diff --git a/docs/setup/storage/storage.md b/docs/setup/storage/storage.md
index 0b65f91661..f6b8b5c08d 100644
--- a/docs/setup/storage/storage.md
+++ b/docs/setup/storage/storage.md
@@ -57,7 +57,7 @@ To enable versioning for all your local notebooks though a standard Git reposito
## Notebook Storage in hadoop compatible file system repository
Notes may be stored in hadoop compatible file system such as hdfs, so that multiple Zeppelin instances can share the same notes. It supports all the versions of hadoop 2.x. If you use `FileSystemNotebookRepo`, then `zeppelin.notebook.dir` is the path on the hadoop compatible file system. And you need to specify `HADOOP_CONF_DIR` in `zeppelin-env.sh` so that zeppelin can find the right hadoop configuration files.
-If your hadoop cluster is kerberized, then you need to specify `zeppelin.hdfs.keytab` and `zeppelin.hdfs.principal`
+If your hadoop cluster is kerberized, then you need to specify `zeppelin.server.kerberos.keytab` and `zeppelin.server.kerberos.principal`
```
diff --git a/docs/usage/rest_api/notebook.md b/docs/usage/rest_api/notebook.md
index ff935531ae..9879ad999f 100644
--- a/docs/usage/rest_api/notebook.md
+++ b/docs/usage/rest_api/notebook.md
@@ -752,6 +752,59 @@ Notebooks REST API supports the following operations: List, Create, Get, Delete,
+
+
+### Update paragraph
+
+
+
+ Description
+ This ```PUT``` method update paragraph contents using given id, e.g. {"text": "hello"}
+
+
+
+ URL
+ ```http://[zeppelin-server]:[zeppelin-port]/api/notebook/[noteId]/paragraph/[paragraphId]```
+
+
+ Success code
+ 200
+
+
+ Bad Request code
+ 400
+
+
+ Forbidden code
+ 403
+
+
+ Not Found code
+ 404
+
+
+ Fail code
+ 500
+
+
+ sample JSON input
+
+{
+ "title": "Hello world",
+ "text": "println(\"hello world\")"
+}
+
+
+ sample JSON response
+
+{
+ "status": "OK",
+ "message": ""
+ }
+}
+
+
+
### Update paragraph configuration
diff --git a/elasticsearch/pom.xml b/elasticsearch/pom.xml
index 6042a14eae..b317e28581 100644
--- a/elasticsearch/pom.xml
+++ b/elasticsearch/pom.xml
@@ -20,10 +20,10 @@
4.0.0
- zeppelin
+ interpreter-parent
org.apache.zeppelin
0.8.0-SNAPSHOT
- ..
+ ../interpreter-parent
zeppelin-elasticsearch
@@ -32,6 +32,7 @@
Zeppelin: Elasticsearch interpreter
+ elasticsearch
2.4.3
4.0.2
18.0
@@ -93,54 +94,12 @@
maven-enforcer-plugin
-
-
- enforce
- none
-
-
-
maven-dependency-plugin
-
-
- copy-dependencies
- package
-
- copy-dependencies
-
-
- ${project.build.directory}/../../interpreter/elasticsearch
- false
- false
- true
- runtime
-
-
-
- copy-artifact
- package
-
- copy
-
-
- ${project.build.directory}/../../interpreter/elasticsearch
- false
- false
- true
- runtime
-
-
- ${project.groupId}
- ${project.artifactId}
- ${project.version}
- ${project.packaging}
-
-
-
-
-
+
+
+ maven-resources-plugin
diff --git a/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/ElasticsearchInterpreter.java b/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/ElasticsearchInterpreter.java
index 33448df3db..6251b92512 100644
--- a/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/ElasticsearchInterpreter.java
+++ b/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/ElasticsearchInterpreter.java
@@ -112,7 +112,7 @@ public class ElasticsearchInterpreter extends Interpreter {
@Override
public void open() {
- logger.info("Properties: {}", getProperty());
+ logger.info("Properties: {}", getProperties());
String clientType = getProperty(ELASTICSEARCH_CLIENT_TYPE);
clientType = clientType == null ? null : clientType.toLowerCase();
@@ -123,15 +123,15 @@ public class ElasticsearchInterpreter extends Interpreter {
catch (final NumberFormatException e) {
this.resultSize = 10;
logger.error("Unable to parse " + ELASTICSEARCH_RESULT_SIZE + " : " +
- property.get(ELASTICSEARCH_RESULT_SIZE), e);
+ getProperty(ELASTICSEARCH_RESULT_SIZE), e);
}
try {
if (StringUtils.isEmpty(clientType) || "transport".equals(clientType)) {
- elsClient = new TransportBasedClient(getProperty());
+ elsClient = new TransportBasedClient(getProperties());
}
else if ("http".equals(clientType)) {
- elsClient = new HttpBasedClient(getProperty());
+ elsClient = new HttpBasedClient(getProperties());
}
else {
logger.error("Unknown type of Elasticsearch client: " + clientType);
diff --git a/file/pom.xml b/file/pom.xml
index 2493c1fae4..1a76683215 100644
--- a/file/pom.xml
+++ b/file/pom.xml
@@ -20,9 +20,10 @@
4.0.0
- zeppelin
+ interpreter-parent
org.apache.zeppelin
0.8.0-SNAPSHOT
+ ../interpreter-parent
org.apache.zeppelin
@@ -33,11 +34,13 @@
+ file
2.0
2.22.2
2.18.1
+ file
@@ -79,62 +82,14 @@
-
- org.apache.maven.plugins
- maven-surefire-plugin
- ${plugin.surefire.version}
-
-
maven-enforcer-plugin
-
-
- enforce
- none
-
-
-
maven-dependency-plugin
-
-
- copy-dependencies
- package
-
- copy-dependencies
-
-
- ${project.build.directory}/../../interpreter/file
- false
- false
- true
- runtime
-
-
-
- copy-artifact
- package
-
- copy
-
-
- ${project.build.directory}/../../interpreter/file
- false
- false
- true
-
-
-
- ${project.groupId}
- ${project.artifactId}
- ${project.version}
- ${project.packaging}
-
-
-
-
-
+
+
+ maven-resources-plugin
diff --git a/file/src/main/java/org/apache/zeppelin/file/FileInterpreter.java b/file/src/main/java/org/apache/zeppelin/file/FileInterpreter.java
index d7aad192ee..cf83672734 100644
--- a/file/src/main/java/org/apache/zeppelin/file/FileInterpreter.java
+++ b/file/src/main/java/org/apache/zeppelin/file/FileInterpreter.java
@@ -20,6 +20,7 @@ package org.apache.zeppelin.file;
import org.apache.zeppelin.interpreter.Interpreter;
import org.apache.zeppelin.interpreter.InterpreterContext;
+import org.apache.zeppelin.interpreter.InterpreterException;
import org.apache.zeppelin.interpreter.InterpreterResult;
import org.apache.zeppelin.interpreter.InterpreterResult.Code;
import org.apache.zeppelin.interpreter.InterpreterResult.Type;
@@ -86,7 +87,7 @@ public abstract class FileInterpreter extends Interpreter {
// Functions that each file system implementation must override
- public abstract String listAll(String path);
+ public abstract String listAll(String path) throws InterpreterException;
public abstract boolean isDirectory(String path);
diff --git a/file/src/main/java/org/apache/zeppelin/file/HDFSFileInterpreter.java b/file/src/main/java/org/apache/zeppelin/file/HDFSFileInterpreter.java
index 244101c9bd..d715ed93a8 100644
--- a/file/src/main/java/org/apache/zeppelin/file/HDFSFileInterpreter.java
+++ b/file/src/main/java/org/apache/zeppelin/file/HDFSFileInterpreter.java
@@ -202,7 +202,7 @@ public class HDFSFileInterpreter extends FileInterpreter {
return "No such File or directory";
}
- public String listAll(String path) {
+ public String listAll(String path) throws InterpreterException {
String all = "";
if (exceptionOnConnect != null)
return "Error connecting to provided endpoint.";
diff --git a/flink/pom.xml b/flink/pom.xml
index 19e7c5e48b..5c0cc3bf90 100644
--- a/flink/pom.xml
+++ b/flink/pom.xml
@@ -20,10 +20,10 @@
4.0.0
- zeppelin
+ interpreter-parent
org.apache.zeppelin
0.8.0-SNAPSHOT
- ..
+ ../interpreter-parent
org.apache.zeppelin
@@ -35,6 +35,7 @@
+ flink
1.1.3
2.3.7
2.0.1
@@ -280,68 +281,16 @@
-
- maven-enforcer-plugin
-
-
- enforce
- none
-
-
-
+
+ maven-enforcer-plugin
+
+
+ maven-dependency-plugin
+
+
+ maven-resources-plugin
+
-
- org.apache.maven.plugins
- maven-surefire-plugin
-
- 1
- false
- -Xmx1024m -XX:MaxPermSize=256m
-
-
-
-
- org.apache.maven.plugins
- maven-dependency-plugin
-
-
- copy-dependencies
- package
-
- copy-dependencies
-
-
- ${project.build.directory}/../../interpreter/flink
- false
- false
- true
- runtime
-
-
-
- copy-artifact
- package
-
- copy
-
-
- ${project.build.directory}/../../interpreter/flink
- false
- false
- true
- runtime
-
-
- ${project.groupId}
- ${project.artifactId}
- ${project.version}
- ${project.packaging}
-
-
-
-
-
-
diff --git a/flink/src/main/java/org/apache/zeppelin/flink/FlinkInterpreter.java b/flink/src/main/java/org/apache/zeppelin/flink/FlinkInterpreter.java
index 710eace666..19c77de914 100644
--- a/flink/src/main/java/org/apache/zeppelin/flink/FlinkInterpreter.java
+++ b/flink/src/main/java/org/apache/zeppelin/flink/FlinkInterpreter.java
@@ -17,7 +17,6 @@
*/
package org.apache.zeppelin.flink;
-import java.lang.reflect.InvocationTargetException;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
@@ -34,10 +33,8 @@ import org.apache.flink.runtime.akka.AkkaUtils;
import org.apache.flink.runtime.instance.ActorGateway;
import org.apache.flink.runtime.messages.JobManagerMessages;
import org.apache.flink.runtime.minicluster.LocalFlinkMiniCluster;
-import org.apache.flink.runtime.util.EnvironmentInformation;
import org.apache.zeppelin.interpreter.Interpreter;
import org.apache.zeppelin.interpreter.InterpreterContext;
-import org.apache.zeppelin.interpreter.InterpreterPropertyBuilder;
import org.apache.zeppelin.interpreter.InterpreterResult;
import org.apache.zeppelin.interpreter.InterpreterResult.Code;
import org.apache.zeppelin.interpreter.InterpreterUtils;
@@ -46,11 +43,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import scala.Console;
-import scala.None;
-import scala.Option;
import scala.Some;
import scala.collection.JavaConversions;
-import scala.collection.immutable.Nil;
import scala.concurrent.duration.FiniteDuration;
import scala.runtime.AbstractFunction0;
import scala.tools.nsc.Settings;
@@ -80,7 +74,7 @@ public class FlinkInterpreter extends Interpreter {
public void open() {
out = new ByteArrayOutputStream();
flinkConf = new org.apache.flink.configuration.Configuration();
- Properties intpProperty = getProperty();
+ Properties intpProperty = getProperties();
for (Object k : intpProperty.keySet()) {
String key = (String) k;
String val = toString(intpProperty.get(key));
diff --git a/geode/pom.xml b/geode/pom.xml
index e8eb9fc846..4a9dadd234 100644
--- a/geode/pom.xml
+++ b/geode/pom.xml
@@ -21,9 +21,10 @@
4.0.0
- zeppelin
+ interpreter-parent
org.apache.zeppelin
0.8.0-SNAPSHOT
+ ../interpreter-parent
org.apache.zeppelin
@@ -34,6 +35,7 @@
+ geode
1.1.0
1.3
@@ -86,54 +88,12 @@
maven-enforcer-plugin
-
-
- enforce
- none
-
-
-
maven-dependency-plugin
-
-
- copy-dependencies
- package
-
- copy-dependencies
-
-
- ${project.build.directory}/../../interpreter/geode
- false
- false
- true
- runtime
-
-
-
- copy-artifact
- package
-
- copy
-
-
- ${project.build.directory}/../../interpreter/geode
- false
- false
- true
- runtime
-
-
- ${project.groupId}
- ${project.artifactId}
- ${project.version}
- ${project.packaging}
-
-
-
-
-
+
+
+ maven-resources-plugin
diff --git a/groovy/pom.xml b/groovy/pom.xml
index bee50bd82e..64c51f8561 100644
--- a/groovy/pom.xml
+++ b/groovy/pom.xml
@@ -20,11 +20,11 @@
4.0.0
- zeppelin
+ interpreter-parent
org.apache.zeppelin
0.8.0-SNAPSHOT
- ..
+ ../interpreter-parent
org.apache.zeppelin
@@ -33,6 +33,10 @@
0.8.0-SNAPSHOT
Zeppelin: Groovy interpreter
+
+ groovy
+
+
${project.groupId}
@@ -67,81 +71,14 @@
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.1
-
- true
-
-
- -Xlint:unchecked
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-checkstyle-plugin
-
- true
-
-
-
-
maven-enforcer-plugin
- 1.3.1
-
-
- enforce
- none
-
-
-
maven-dependency-plugin
- 2.8
-
-
- copy-dependencies
- package
-
- copy-dependencies
-
-
- ${project.build.directory}/../../interpreter/groovy
- false
- false
- true
- runtime
-
-
-
- copy-artifact
- package
-
- copy
-
-
- ${project.build.directory}/../../interpreter/groovy
- false
- false
- true
- runtime
-
-
- ${project.groupId}
- ${project.artifactId}
- ${project.version}
- ${project.packaging}
-
-
-
-
-
+
+
+ maven-resources-plugin
diff --git a/groovy/src/main/java/org/apache/zeppelin/groovy/GObject.java b/groovy/src/main/java/org/apache/zeppelin/groovy/GObject.java
index 7f6809a899..babda8f760 100644
--- a/groovy/src/main/java/org/apache/zeppelin/groovy/GObject.java
+++ b/groovy/src/main/java/org/apache/zeppelin/groovy/GObject.java
@@ -172,7 +172,7 @@ public class GObject extends groovy.lang.GroovyObjectSupport {
/**
* starts or continues rendering html/angular and returns MarkupBuilder to build html.
* g.html().with{
- * h1("hello")
+ * h1("hello")
* h2("world")
* }
*/
@@ -316,12 +316,12 @@ public class GObject extends groovy.lang.GroovyObjectSupport {
@ZeppelinApi
public void run(String noteId, String paragraphId, InterpreterContext context) {
if (paragraphId.equals(context.getParagraphId())) {
- throw new InterpreterException("Can not run current Paragraph");
+ throw new RuntimeException("Can not run current Paragraph");
}
List runners = getInterpreterContextRunner(noteId, paragraphId,
context);
if (runners.size() <= 0) {
- throw new InterpreterException("Paragraph " + paragraphId + " not found " + runners.size());
+ throw new RuntimeException("Paragraph " + paragraphId + " not found " + runners.size());
}
for (InterpreterContextRunner r : runners) {
r.run();
@@ -338,7 +338,7 @@ public class GObject extends groovy.lang.GroovyObjectSupport {
List runners = getInterpreterContextRunner(noteId, context);
if (runners.size() <= 0) {
- throw new InterpreterException("Note " + noteId + " not found " + runners.size());
+ throw new RuntimeException("Note " + noteId + " not found " + runners.size());
}
for (InterpreterContextRunner r : runners) {
diff --git a/groovy/src/main/java/org/apache/zeppelin/groovy/GroovyInterpreter.java b/groovy/src/main/java/org/apache/zeppelin/groovy/GroovyInterpreter.java
index e10828368f..01e97e6bdd 100644
--- a/groovy/src/main/java/org/apache/zeppelin/groovy/GroovyInterpreter.java
+++ b/groovy/src/main/java/org/apache/zeppelin/groovy/GroovyInterpreter.java
@@ -17,8 +17,6 @@
package org.apache.zeppelin.groovy;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
import java.io.StringWriter;
import java.io.PrintWriter;
import java.io.File;
@@ -26,10 +24,8 @@ import java.util.*;
import org.apache.zeppelin.interpreter.Interpreter;
import org.apache.zeppelin.interpreter.InterpreterContext;
-import org.apache.zeppelin.interpreter.InterpreterPropertyBuilder;
import org.apache.zeppelin.interpreter.InterpreterResult;
import org.apache.zeppelin.interpreter.InterpreterResult.Code;
-import org.apache.zeppelin.interpreter.InterpreterResult.Type;
import org.apache.zeppelin.interpreter.thrift.InterpreterCompletion;
import org.apache.zeppelin.scheduler.Job;
import org.apache.zeppelin.scheduler.Scheduler;
@@ -40,7 +36,6 @@ import org.slf4j.LoggerFactory;
import groovy.lang.GroovyShell;
import groovy.lang.Script;
import org.codehaus.groovy.control.CompilerConfiguration;
-import org.codehaus.groovy.runtime.ResourceGroovyMethods;
import org.codehaus.groovy.runtime.StackTraceUtils;
import java.util.concurrent.ConcurrentHashMap;
@@ -167,7 +162,7 @@ public class GroovyInterpreter extends Interpreter {
//put shared bindings evaluated in this interpreter
bindings.putAll(sharedBindings);
//put predefined bindings
- bindings.put("g", new GObject(log, out, this.getProperty(), contextInterpreter, bindings));
+ bindings.put("g", new GObject(log, out, this.getProperties(), contextInterpreter, bindings));
bindings.put("out", new PrintWriter(out, true));
script.run();
@@ -204,7 +199,7 @@ public class GroovyInterpreter extends Interpreter {
Thread t = (Thread) object;
t.dumpStack();
t.interrupt();
- //t.stop(); //TODO: need some way to terminate maybe through GObject..
+ //t.stop(); //TODO(dlukyanov): need some way to terminate maybe through GObject..
} catch (Throwable t) {
log.error("Failed to cancel script: " + t, t);
}
diff --git a/hbase/pom.xml b/hbase/pom.xml
index 08b0cd7071..8f27631ea2 100644
--- a/hbase/pom.xml
+++ b/hbase/pom.xml
@@ -20,9 +20,10 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
- zeppelin
+ interpreter-parent
org.apache.zeppelin
0.8.0-SNAPSHOT
+ ../interpreter-parent
org.apache.zeppelin
@@ -33,6 +34,7 @@
+ hbase
1.0.0
2.6.0
1.6.8
@@ -115,55 +117,14 @@
maven-enforcer-plugin
-
-
- enforce
- none
-
-
-
maven-dependency-plugin
-
-
- 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}
-
-
-
-
-
+
+
+ maven-resources-plugin
+
diff --git a/hbase/src/main/java/org/apache/zeppelin/hbase/HbaseInterpreter.java b/hbase/src/main/java/org/apache/zeppelin/hbase/HbaseInterpreter.java
index 74d3ed1aec..63c1928334 100644
--- a/hbase/src/main/java/org/apache/zeppelin/hbase/HbaseInterpreter.java
+++ b/hbase/src/main/java/org/apache/zeppelin/hbase/HbaseInterpreter.java
@@ -68,7 +68,7 @@ public class HbaseInterpreter extends Interpreter {
}
@Override
- public void open() {
+ public void open() throws InterpreterException {
this.scriptingContainer = new ScriptingContainer(LocalContextScope.SINGLETON);
this.writer = new StringWriter();
scriptingContainer.setOutput(this.writer);
@@ -88,7 +88,7 @@ public class HbaseInterpreter extends Interpreter {
}
logger.info("Absolute Ruby Source:" + abs_ruby_src.toString());
- // hirb.rb:41 requires the following system property to be set.
+ // hirb.rb:41 requires the following system properties to be set.
Properties sysProps = System.getProperties();
sysProps.setProperty(HBASE_RUBY_SRC, abs_ruby_src.toString());
diff --git a/hbase/src/test/java/org/apache/zeppelin/hbase/HbaseInterpreterTest.java b/hbase/src/test/java/org/apache/zeppelin/hbase/HbaseInterpreterTest.java
index 38a8b4d1e0..53040f91a5 100644
--- a/hbase/src/test/java/org/apache/zeppelin/hbase/HbaseInterpreterTest.java
+++ b/hbase/src/test/java/org/apache/zeppelin/hbase/HbaseInterpreterTest.java
@@ -15,6 +15,7 @@
package org.apache.zeppelin.hbase;
import org.apache.log4j.BasicConfigurator;
+import org.apache.zeppelin.interpreter.InterpreterException;
import org.apache.zeppelin.interpreter.InterpreterResult;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -35,7 +36,7 @@ public class HbaseInterpreterTest {
private static HbaseInterpreter hbaseInterpreter;
@BeforeClass
- public static void setUp() throws NullPointerException {
+ public static void setUp() throws NullPointerException, InterpreterException {
BasicConfigurator.configure();
Properties properties = new Properties();
properties.put("hbase.home", "");
diff --git a/helium-dev/pom.xml b/helium-dev/pom.xml
index 77c4dee8e0..8514946d76 100644
--- a/helium-dev/pom.xml
+++ b/helium-dev/pom.xml
@@ -23,8 +23,9 @@
org.apache.zeppelin
- zeppelin
+ interpreter-parent
0.8.0-SNAPSHOT
+ ../interpreter-parent
org.apache.zeppelin
@@ -32,6 +33,10 @@
0.8.0-SNAPSHOT
Zeppelin: Helium development interpreter
+
+ helium-dev
+
+
org.apache.zeppelin
@@ -43,46 +48,14 @@
+
+ maven-enforcer-plugin
+
maven-dependency-plugin
-
-
- copy-dependencies
- package
-
- copy-dependencies
-
-
- ${project.build.directory}/../../interpreter/helium-dev
- false
- false
- true
- runtime
-
-
-
- copy-artifact
- package
-
- copy
-
-
- ${project.build.directory}/../../interpreter/helium-dev
- false
- false
- true
- runtime
-
-
- ${project.groupId}
- ${project.artifactId}
- ${project.version}
- ${project.packaging}
-
-
-
-
-
+
+
+ maven-resources-plugin
diff --git a/helium-dev/src/main/java/org/apache/zeppelin/helium/DevInterpreter.java b/helium-dev/src/main/java/org/apache/zeppelin/helium/DevInterpreter.java
index 7d1c361de7..ba1a564dd7 100644
--- a/helium-dev/src/main/java/org/apache/zeppelin/helium/DevInterpreter.java
+++ b/helium-dev/src/main/java/org/apache/zeppelin/helium/DevInterpreter.java
@@ -74,7 +74,8 @@ public class DevInterpreter extends Interpreter {
}
@Override
- public InterpreterResult interpret(String st, InterpreterContext context) {
+ public InterpreterResult interpret(String st, InterpreterContext context)
+ throws InterpreterException {
this.context = context;
try {
return interpreterEvent.interpret(st, context);
diff --git a/ignite/pom.xml b/ignite/pom.xml
index 9b1855c6ff..ccbd37d8e4 100644
--- a/ignite/pom.xml
+++ b/ignite/pom.xml
@@ -20,10 +20,10 @@
4.0.0
- zeppelin
+ interpreter-parent
org.apache.zeppelin
0.8.0-SNAPSHOT
- ..
+ ../interpreter-parent
zeppelin-ignite_2.10
@@ -32,6 +32,7 @@
Zeppelin: Apache Ignite interpreter
+ ignite
2.2.0
@@ -106,55 +107,12 @@
maven-enforcer-plugin
-
-
- enforce
- none
-
-
-
- org.apache.maven.plugins
maven-dependency-plugin
-
-
- copy-dependencies
- package
-
- copy-dependencies
-
-
- ${project.build.directory}/../../interpreter/ignite
- false
- false
- true
- runtime
-
-
-
- copy-artifact
- package
-
- copy
-
-
- ${project.build.directory}/../../interpreter/ignite
- false
- false
- true
- runtime
-
-
- ${project.groupId}
- ${project.artifactId}
- ${project.version}
- ${project.packaging}
-
-
-
-
-
+
+
+ maven-resources-plugin
diff --git a/ignite/src/main/java/org/apache/zeppelin/ignite/IgniteSqlInterpreter.java b/ignite/src/main/java/org/apache/zeppelin/ignite/IgniteSqlInterpreter.java
index 41803bb31b..6af8eb549e 100644
--- a/ignite/src/main/java/org/apache/zeppelin/ignite/IgniteSqlInterpreter.java
+++ b/ignite/src/main/java/org/apache/zeppelin/ignite/IgniteSqlInterpreter.java
@@ -93,7 +93,7 @@ public class IgniteSqlInterpreter extends Interpreter {
}
@Override
- public void close() {
+ public void close() throws InterpreterException {
try {
if (conn != null) {
conn.close();
diff --git a/ignite/src/test/java/org/apache/zeppelin/ignite/IgniteSqlInterpreterTest.java b/ignite/src/test/java/org/apache/zeppelin/ignite/IgniteSqlInterpreterTest.java
index b06d457c38..a6ae0ea6a5 100644
--- a/ignite/src/test/java/org/apache/zeppelin/ignite/IgniteSqlInterpreterTest.java
+++ b/ignite/src/test/java/org/apache/zeppelin/ignite/IgniteSqlInterpreterTest.java
@@ -27,6 +27,7 @@ import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
import org.apache.zeppelin.interpreter.InterpreterContext;
+import org.apache.zeppelin.interpreter.InterpreterException;
import org.apache.zeppelin.interpreter.InterpreterResult;
import org.apache.zeppelin.interpreter.InterpreterResult.Code;
import org.apache.zeppelin.interpreter.InterpreterResult.Type;
@@ -82,7 +83,7 @@ public class IgniteSqlInterpreterTest {
}
@After
- public void tearDown() {
+ public void tearDown() throws InterpreterException {
intp.close();
ignite.close();
}
diff --git a/interpreter-parent/pom.xml b/interpreter-parent/pom.xml
new file mode 100644
index 0000000000..32bdc570e7
--- /dev/null
+++ b/interpreter-parent/pom.xml
@@ -0,0 +1,138 @@
+
+
+
+
+ 4.0.0
+
+
+ zeppelin
+ org.apache.zeppelin
+ 0.8.0-SNAPSHOT
+ ..
+
+
+ org.apache.zeppelin
+ interpreter-parent
+ pom
+ 0.8.0-SNAPSHOT
+ Zeppelin: Interpreter Parent
+
+
+
+
+ ${project.groupId}
+ zeppelin-interpreter
+ 0.8.0-SNAPSHOT
+ provided
+
+
+
+ junit
+ junit
+ ${junit.version}
+ test
+
+
+
+ org.slf4j
+ slf4j-api
+ ${slf4j.version}
+
+
+
+ org.slf4j
+ slf4j-log4j12
+ ${slf4j.version}
+
+
+
+
+
+
+
+
+ maven-enforcer-plugin
+
+
+ enforce
+ none
+
+
+
+
+
+ maven-dependency-plugin
+
+
+ copy-interpreter-dependencies
+ package
+
+ copy-dependencies
+
+
+ ${project.build.directory}/../../interpreter/${interpreter.name}
+ false
+ false
+ true
+ runtime
+
+
+
+ copy-artifact
+ package
+
+ copy
+
+
+ ${project.build.directory}/../../interpreter/${interpreter.name}
+ false
+ false
+ true
+
+
+ ${project.groupId}
+ ${project.artifactId}
+ ${project.version}
+ ${project.packaging}
+
+
+
+
+
+
+
+
+ maven-resources-plugin
+
+
+ copy-interpreter-setting
+ package
+
+ resources
+
+
+ ${project.build.directory}/../../interpreter/${interpreter.name}
+
+
+
+
+
+
+
+
+
diff --git a/jdbc/pom.xml b/jdbc/pom.xml
index 71d33109e6..beec50c0ad 100644
--- a/jdbc/pom.xml
+++ b/jdbc/pom.xml
@@ -21,9 +21,10 @@
4.0.0
- zeppelin
+ interpreter-parent
org.apache.zeppelin
0.8.0-SNAPSHOT
+ ../interpreter-parent
org.apache.zeppelin
@@ -34,6 +35,7 @@
+ jdbc
9.4-1201-jdbc41
2.7.2
1.4.190
@@ -158,54 +160,12 @@
maven-enforcer-plugin
-
-
- enforce
- none
-
-
-
maven-dependency-plugin
-
-
- copy-dependencies
- package
-
- copy-dependencies
-
-
- ${project.build.directory}/../../interpreter/jdbc
- false
- false
- true
- runtime
-
-
-
- copy-artifact
- package
-
- copy
-
-
- ${project.build.directory}/../../interpreter/jdbc
- false
- false
- true
- runtime
-
-
- ${project.groupId}
- ${project.artifactId}
- ${project.version}
- ${project.packaging}
-
-
-
-
-
+
+
+ maven-resources-plugin
diff --git a/jdbc/src/main/java/org/apache/zeppelin/jdbc/JDBCInterpreter.java b/jdbc/src/main/java/org/apache/zeppelin/jdbc/JDBCInterpreter.java
index 2c5258cfd7..f3dfddcbfd 100644
--- a/jdbc/src/main/java/org/apache/zeppelin/jdbc/JDBCInterpreter.java
+++ b/jdbc/src/main/java/org/apache/zeppelin/jdbc/JDBCInterpreter.java
@@ -45,8 +45,6 @@ import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.security.alias.CredentialProvider;
import org.apache.hadoop.security.alias.CredentialProviderFactory;
-import org.apache.thrift.transport.TTransportException;
-import org.apache.zeppelin.interpreter.Interpreter;
import org.apache.zeppelin.interpreter.InterpreterContext;
import org.apache.zeppelin.interpreter.InterpreterException;
import org.apache.zeppelin.interpreter.InterpreterResult;
@@ -172,7 +170,7 @@ public class JDBCInterpreter extends KerberosInterpreter {
@Override
public void open() {
super.open();
- for (String propertyKey : property.stringPropertyNames()) {
+ for (String propertyKey : properties.stringPropertyNames()) {
logger.debug("propertyKey: {}", propertyKey);
String[] keyValue = propertyKey.split("\\.", 2);
if (2 == keyValue.length) {
@@ -185,7 +183,7 @@ public class JDBCInterpreter extends KerberosInterpreter {
prefixProperties = new Properties();
basePropretiesMap.put(keyValue[0].trim(), prefixProperties);
}
- prefixProperties.put(keyValue[1].trim(), property.getProperty(propertyKey));
+ prefixProperties.put(keyValue[1].trim(), getProperty(propertyKey));
}
}
@@ -211,8 +209,8 @@ public class JDBCInterpreter extends KerberosInterpreter {
protected boolean isKerboseEnabled() {
- if (!isEmpty(property.getProperty("zeppelin.jdbc.auth.type"))) {
- UserGroupInformation.AuthenticationMethod authType = JDBCSecurityImpl.getAuthtype(property);
+ if (!isEmpty(getProperty("zeppelin.jdbc.auth.type"))) {
+ UserGroupInformation.AuthenticationMethod authType = JDBCSecurityImpl.getAuthtype(properties);
if (authType.equals(KERBEROS)) {
return true;
}
@@ -356,7 +354,7 @@ public class JDBCInterpreter extends KerberosInterpreter {
}
private void setUserProperty(String propertyKey, InterpreterContext interpreterContext)
- throws SQLException, IOException {
+ throws SQLException, IOException, InterpreterException {
String user = interpreterContext.getAuthenticationInfo().getUser();
@@ -424,18 +422,19 @@ public class JDBCInterpreter extends KerberosInterpreter {
final Properties properties = jdbcUserConfigurations.getPropertyMap(propertyKey);
final String url = properties.getProperty(URL_KEY);
- if (isEmpty(property.getProperty("zeppelin.jdbc.auth.type"))) {
+ if (isEmpty(getProperty("zeppelin.jdbc.auth.type"))) {
connection = getConnectionFromPool(url, user, propertyKey, properties);
} else {
- UserGroupInformation.AuthenticationMethod authType = JDBCSecurityImpl.getAuthtype(property);
+ UserGroupInformation.AuthenticationMethod authType =
+ JDBCSecurityImpl.getAuthtype(getProperties());
final String connectionUrl = appendProxyUserToURL(url, user, propertyKey);
- JDBCSecurityImpl.createSecureConfiguration(property, authType);
+ JDBCSecurityImpl.createSecureConfiguration(getProperties(), authType);
switch (authType) {
case KERBEROS:
if (user == null || "false".equalsIgnoreCase(
- property.getProperty("zeppelin.jdbc.auth.kerberos.proxy.enable"))) {
+ getProperty("zeppelin.jdbc.auth.kerberos.proxy.enable"))) {
connection = getConnectionFromPool(connectionUrl, user, propertyKey, properties);
} else {
if (basePropretiesMap.get(propertyKey).containsKey("proxy.user.property")) {
@@ -497,7 +496,7 @@ public class JDBCInterpreter extends KerberosInterpreter {
return connectionUrl.toString();
}
- private String getPassword(Properties properties) throws IOException {
+ private String getPassword(Properties properties) throws IOException, InterpreterException {
if (isNotEmpty(properties.getProperty(PASSWORD_KEY))) {
return properties.getProperty(PASSWORD_KEY);
} else if (isNotEmpty(properties.getProperty(JDBC_JCEKS_FILE))
@@ -850,7 +849,7 @@ public class JDBCInterpreter extends KerberosInterpreter {
@Override
public List completion(String buf, int cursor,
- InterpreterContext interpreterContext) {
+ InterpreterContext interpreterContext) throws InterpreterException {
List candidates = new ArrayList<>();
String propertyKey = getPropertyKey(buf);
String sqlCompleterKey =
diff --git a/jdbc/src/test/java/org/apache/zeppelin/jdbc/JDBCInterpreterTest.java b/jdbc/src/test/java/org/apache/zeppelin/jdbc/JDBCInterpreterTest.java
index e6f9598f8b..1b3f045ce6 100644
--- a/jdbc/src/test/java/org/apache/zeppelin/jdbc/JDBCInterpreterTest.java
+++ b/jdbc/src/test/java/org/apache/zeppelin/jdbc/JDBCInterpreterTest.java
@@ -37,6 +37,7 @@ import java.util.Properties;
import org.apache.zeppelin.completer.CompletionType;
import org.apache.zeppelin.interpreter.InterpreterContext;
+import org.apache.zeppelin.interpreter.InterpreterException;
import org.apache.zeppelin.interpreter.InterpreterResult;
import org.apache.zeppelin.interpreter.thrift.InterpreterCompletion;
import org.apache.zeppelin.scheduler.FIFOScheduler;
@@ -349,7 +350,7 @@ public class JDBCInterpreterTest extends BasicJDBCTestCaseAdapter {
}
@Test
- public void testAutoCompletion() throws SQLException, IOException {
+ public void testAutoCompletion() throws SQLException, IOException, InterpreterException {
Properties properties = new Properties();
properties.setProperty("common.max_count", "1000");
properties.setProperty("common.max_retry", "3");
diff --git a/kylin/pom.xml b/kylin/pom.xml
index c3559cd04b..b70facbcc1 100644
--- a/kylin/pom.xml
+++ b/kylin/pom.xml
@@ -21,9 +21,10 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- zeppelin
+ interpreter-parent
org.apache.zeppelin
0.8.0-SNAPSHOT
+ ../interpreter-parent
4.0.0
@@ -33,6 +34,10 @@
0.8.0-SNAPSHOT
Zeppelin: Kylin interpreter
+
+ kylin
+
+
@@ -61,57 +66,14 @@
maven-enforcer-plugin
-
-
- enforce
- none
-
-
-
maven-dependency-plugin
-
-
- copy-dependencies
- package
-
- copy-dependencies
-
-
- ${project.build.directory}/../../interpreter/kylin
- false
- false
- true
- runtime
-
-
-
- copy-artifact
- package
-
- copy
-
-
- ${project.build.directory}/../../interpreter/kylin
- false
- false
- true
- runtime
-
-
- ${project.groupId}
- ${project.artifactId}
- ${project.version}
- ${project.packaging}
-
-
-
-
-
+
+
+ maven-resources-plugin
-
diff --git a/lens/pom.xml b/lens/pom.xml
index 0328355793..ecc0a12ed6 100644
--- a/lens/pom.xml
+++ b/lens/pom.xml
@@ -20,10 +20,10 @@
4.0.0
- zeppelin
+ interpreter-parent
org.apache.zeppelin
0.8.0-SNAPSHOT
- ..
+ ../interpreter-parent
org.apache.zeppelin
@@ -34,6 +34,7 @@
+ lens
2.5.0-beta
1.1.0.RELEASE
2.4.0
@@ -163,69 +164,13 @@
maven-enforcer-plugin
-
-
- enforce
- none
-
-
-
maven-dependency-plugin
-
-
- copy-dependencies
- package
-
- copy-dependencies
-
-
- ${project.build.directory}/../../interpreter/lens
- false
- false
- true
- runtime
-
-
-
- copy-artifact
- package
-
- copy
-
-
- ${project.build.directory}/../../interpreter/lens
- false
- false
- true
- runtime
-
-
- ${project.groupId}
- ${project.artifactId}
- ${project.version}
- ${project.packaging}
-
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-clean-plugin
-
-
-
- ${basedir}/../interpreter/lens
- false
-
-
-
-
-
+
+ maven-resources-plugin
+
diff --git a/livy/pom.xml b/livy/pom.xml
index e7217fb9da..0ec174a9c4 100644
--- a/livy/pom.xml
+++ b/livy/pom.xml
@@ -22,10 +22,10 @@
4.0.0
- zeppelin
+ interpreter-parent
org.apache.zeppelin
0.8.0-SNAPSHOT
- ..
+ ../interpreter-parent
org.apache.zeppelin
@@ -36,6 +36,7 @@
+ livy
1.3
4.3.0.RELEASE
1.0.1.RELEASE
@@ -193,56 +194,12 @@
maven-enforcer-plugin
-
-
- enforce
- none
-
-
-
maven-dependency-plugin
-
-
- copy-dependencies
- package
-
- copy-dependencies
-
-
- ${project.build.directory}/../../interpreter/livy
-
- false
- false
- true
- runtime
-
-
-
- copy-artifact
- package
-
- copy
-
-
- ${project.build.directory}/../../interpreter/livy
-
- false
- false
- true
- runtime
-
-
- ${project.groupId}
- ${project.artifactId}
- ${project.version}
- ${project.packaging}
-
-
-
-
-
+
+
+ maven-resources-plugin
diff --git a/livy/src/main/java/org/apache/zeppelin/livy/BaseLivyInterpreter.java b/livy/src/main/java/org/apache/zeppelin/livy/BaseLivyInterpreter.java
index ccab09bfce..03a269eeae 100644
--- a/livy/src/main/java/org/apache/zeppelin/livy/BaseLivyInterpreter.java
+++ b/livy/src/main/java/org/apache/zeppelin/livy/BaseLivyInterpreter.java
@@ -62,6 +62,8 @@ import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
@@ -80,6 +82,7 @@ public abstract class BaseLivyInterpreter extends Interpreter {
protected boolean displayAppInfo;
protected LivyVersion livyVersion;
private RestTemplate restTemplate;
+ private Map customHeaders = new HashMap<>();
Set paragraphsToCancel = Collections.newSetFromMap(
new ConcurrentHashMap());
@@ -96,12 +99,39 @@ public abstract class BaseLivyInterpreter extends Interpreter {
this.pullStatusInterval = Integer.parseInt(
property.getProperty("zeppelin.livy.pull_status.interval.millis", 1000 + ""));
this.restTemplate = createRestTemplate();
+ if (!StringUtils.isBlank(property.getProperty("zeppelin.livy.http.headers"))) {
+ String[] headers = property.getProperty("zeppelin.livy.http.headers").split(";");
+ for (String header : headers) {
+ String[] splits = header.split(":", -1);
+ if (splits.length != 2) {
+ throw new RuntimeException("Invalid format of http headers: " + header +
+ ", valid http header format is HEADER_NAME:HEADER_VALUE");
+ }
+ customHeaders.put(splits[0].trim(), envSubstitute(splits[1].trim()));
+ }
+ }
+ }
+
+ private String envSubstitute(String value) {
+ String newValue = new String(value);
+ Pattern pattern = Pattern.compile("\\$\\{(.*)\\}");
+ Matcher matcher = pattern.matcher(value);
+ while (matcher.find()) {
+ String env = matcher.group(1);
+ newValue = newValue.replace("${" + env + "}", System.getenv(env));
+ }
+ return newValue;
+ }
+
+ // only for testing
+ Map getCustomHeaders() {
+ return customHeaders;
}
public abstract String getSessionKind();
@Override
- public void open() {
+ public void open() throws InterpreterException {
try {
initLivySession();
} catch (LivyException e) {
@@ -198,7 +228,7 @@ public abstract class BaseLivyInterpreter extends Interpreter {
throws LivyException {
try {
Map conf = new HashMap<>();
- for (Map.Entry entry : property.entrySet()) {
+ for (Map.Entry entry : getProperties().entrySet()) {
if (entry.getKey().toString().startsWith("livy.spark.") &&
!entry.getValue().toString().isEmpty())
conf.put(entry.getKey().toString().substring(5), entry.getValue().toString());
@@ -428,15 +458,15 @@ public abstract class BaseLivyInterpreter extends Interpreter {
private RestTemplate createRestTemplate() {
- String keytabLocation = property.getProperty("zeppelin.livy.keytab");
- String principal = property.getProperty("zeppelin.livy.principal");
+ String keytabLocation = getProperty("zeppelin.livy.keytab");
+ String principal = getProperty("zeppelin.livy.principal");
boolean isSpnegoEnabled = StringUtils.isNotEmpty(keytabLocation) &&
StringUtils.isNotEmpty(principal);
HttpClient httpClient = null;
if (livyURL.startsWith("https:")) {
- String keystoreFile = property.getProperty("zeppelin.livy.ssl.trustStore");
- String password = property.getProperty("zeppelin.livy.ssl.trustStorePassword");
+ String keystoreFile = getProperty("zeppelin.livy.ssl.trustStore");
+ String password = getProperty("zeppelin.livy.ssl.trustStorePassword");
if (StringUtils.isBlank(keystoreFile)) {
throw new RuntimeException("No zeppelin.livy.ssl.trustStore specified for livy ssl");
}
@@ -523,6 +553,9 @@ public abstract class BaseLivyInterpreter extends Interpreter {
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", MediaType.APPLICATION_JSON_UTF8_VALUE);
headers.add("X-Requested-By", "zeppelin");
+ for (Map.Entry entry : customHeaders.entrySet()) {
+ headers.add(entry.getKey(), entry.getValue());
+ }
ResponseEntity response = null;
try {
if (method.equals("POST")) {
diff --git a/livy/src/main/java/org/apache/zeppelin/livy/LivySparkSQLInterpreter.java b/livy/src/main/java/org/apache/zeppelin/livy/LivySparkSQLInterpreter.java
index 20d044811b..486e31c2c7 100644
--- a/livy/src/main/java/org/apache/zeppelin/livy/LivySparkSQLInterpreter.java
+++ b/livy/src/main/java/org/apache/zeppelin/livy/LivySparkSQLInterpreter.java
@@ -59,7 +59,7 @@ public class LivySparkSQLInterpreter extends BaseLivyInterpreter {
}
@Override
- public void open() {
+ public void open() throws InterpreterException {
this.sparkInterpreter = getSparkInterpreter();
// As we don't know whether livyserver use spark2 or spark1, so we will detect SparkSession
// to judge whether it is using spark2.
@@ -93,7 +93,7 @@ public class LivySparkSQLInterpreter extends BaseLivyInterpreter {
}
}
- private LivySparkInterpreter getSparkInterpreter() {
+ private LivySparkInterpreter getSparkInterpreter() throws InterpreterException {
LazyOpenInterpreter lazy = null;
LivySparkInterpreter spark = null;
Interpreter p = getInterpreterInTheSameSessionByClassName(LivySparkInterpreter.class.getName());
diff --git a/livy/src/test/java/org/apache/zeppelin/livy/LivyInterpreterIT.java b/livy/src/test/java/org/apache/zeppelin/livy/LivyInterpreterIT.java
index 9a0aef481e..d4131345f1 100644
--- a/livy/src/test/java/org/apache/zeppelin/livy/LivyInterpreterIT.java
+++ b/livy/src/test/java/org/apache/zeppelin/livy/LivyInterpreterIT.java
@@ -75,8 +75,9 @@ public class LivyInterpreterIT {
return true;
}
+
// @Test
- public void testSparkInterpreterRDD() {
+ public void testSparkInterpreterRDD() throws InterpreterException {
if (!checkPreCondition()) {
return;
}
@@ -195,8 +196,9 @@ public class LivyInterpreterIT {
}
}
+
// @Test
- public void testSparkInterpreterDataFrame() {
+ public void testSparkInterpreterDataFrame() throws InterpreterException {
if (!checkPreCondition()) {
return;
}
@@ -284,7 +286,7 @@ public class LivyInterpreterIT {
}
// @Test
- public void testSparkSQLInterpreter() {
+ public void testSparkSQLInterpreter() throws InterpreterException {
if (!checkPreCondition()) {
return;
}
@@ -319,7 +321,7 @@ public class LivyInterpreterIT {
// @Test
- public void testSparkSQLCancellation() {
+ public void testSparkSQLCancellation() throws InterpreterException {
if (!checkPreCondition()) {
return;
}
@@ -400,7 +402,7 @@ public class LivyInterpreterIT {
}
// @Test
- public void testStringWithTruncation() {
+ public void testStringWithTruncation() throws InterpreterException {
if (!checkPreCondition()) {
return;
}
@@ -459,8 +461,9 @@ public class LivyInterpreterIT {
}
}
+
// @Test
- public void testStringWithoutTruncation() {
+ public void testStringWithoutTruncation() throws InterpreterException {
if (!checkPreCondition()) {
return;
}
@@ -525,7 +528,7 @@ public class LivyInterpreterIT {
}
@Test
- public void testPySparkInterpreter() throws LivyException {
+ public void testPySparkInterpreter() throws LivyException, InterpreterException {
if (!checkPreCondition()) {
return;
}
@@ -645,7 +648,7 @@ public class LivyInterpreterIT {
}
// @Test
- public void testSparkInterpreterWithDisplayAppInfo() {
+ public void testSparkInterpreterWithDisplayAppInfo() throws InterpreterException {
if (!checkPreCondition()) {
return;
}
@@ -684,7 +687,7 @@ public class LivyInterpreterIT {
}
// @Test
- public void testSparkRInterpreter() throws LivyException {
+ public void testSparkRInterpreter() throws LivyException, InterpreterException {
if (!checkPreCondition()) {
return;
}
@@ -756,7 +759,7 @@ public class LivyInterpreterIT {
}
// @Test
- public void testLivyTutorialNote() throws IOException {
+ public void testLivyTutorialNote() throws IOException, InterpreterException {
if (!checkPreCondition()) {
return;
}
diff --git a/livy/src/test/java/org/apache/zeppelin/livy/LivySQLInterpreterTest.java b/livy/src/test/java/org/apache/zeppelin/livy/LivySQLInterpreterTest.java
index fdef9b13d1..24d70ec2b0 100644
--- a/livy/src/test/java/org/apache/zeppelin/livy/LivySQLInterpreterTest.java
+++ b/livy/src/test/java/org/apache/zeppelin/livy/LivySQLInterpreterTest.java
@@ -39,9 +39,17 @@ public class LivySQLInterpreterTest {
properties.setProperty("zeppelin.livy.url", "http://localhost:8998");
properties.setProperty("zeppelin.livy.session.create_timeout", "120");
properties.setProperty("zeppelin.livy.spark.sql.maxResult", "3");
+ properties.setProperty("zeppelin.livy.http.headers", "HEADER_1: VALUE_1_${HOME}");
sqlInterpreter = new LivySparkSQLInterpreter(properties);
}
+ @Test
+ public void testHttpHeaders() {
+ assertEquals(1, sqlInterpreter.getCustomHeaders().size());
+ assertTrue(sqlInterpreter.getCustomHeaders().get("HEADER_1").startsWith("VALUE_1_"));
+ assertNotEquals("VALUE_1_${HOME}", sqlInterpreter.getCustomHeaders().get("HEADER_1"));
+ }
+
@Test
public void testParseSQLOutput() {
// Empty sql output
diff --git a/markdown/pom.xml b/markdown/pom.xml
index 9675aa7095..ca95449807 100644
--- a/markdown/pom.xml
+++ b/markdown/pom.xml
@@ -20,10 +20,10 @@
4.0.0
- zeppelin
+ interpreter-parent
org.apache.zeppelin
0.8.0-SNAPSHOT
- ..
+ ../interpreter-parent
org.apache.zeppelin
@@ -33,6 +33,7 @@
Zeppelin: Markdown interpreter
+ md
3.4
2.2-cj-1.0
1.6.0
@@ -85,54 +86,12 @@
maven-enforcer-plugin
-
-
- enforce
- none
-
-
-
maven-dependency-plugin
-
-
- copy-dependencies
- package
-
- copy-dependencies
-
-
- ${project.build.directory}/../../interpreter/md
- false
- false
- true
- runtime
-
-
-
- copy-artifact
- package
-
- copy
-
-
- ${project.build.directory}/../../interpreter/md
- false
- false
- true
- runtime
-
-
- ${project.groupId}
- ${project.artifactId}
- ${project.version}
- ${project.packaging}
-
-
-
-
-
+
+
+ maven-resources-plugin
diff --git a/neo4j/pom.xml b/neo4j/pom.xml
new file mode 100644
index 0000000000..298726fb82
--- /dev/null
+++ b/neo4j/pom.xml
@@ -0,0 +1,144 @@
+
+
+
+
+ 4.0.0
+
+
+ zeppelin
+ org.apache.zeppelin
+ 0.8.0-SNAPSHOT
+ ..
+
+
+ org.apache.zeppelin
+ zeppelin-neo4j
+ jar
+ 0.8.0-SNAPSHOT
+ Zeppelin: Neo4j interpreter
+
+
+ 1.4.3
+ 3.2.3
+ 3.2.3
+ 2.8.9
+
+
+
+
+ ${project.groupId}
+ zeppelin-interpreter
+ ${project.version}
+ provided
+
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ ${jackson.version}
+
+
+
+ org.neo4j.driver
+ neo4j-java-driver
+ ${neo4j.driver.version}
+
+
+
+ org.slf4j
+ slf4j-api
+
+
+
+ org.slf4j
+ slf4j-log4j12
+
+
+
+ junit
+ junit
+ test
+
+
+
+ org.neo4j.test
+ neo4j-harness
+ ${neo4j.version}
+ test
+
+
+
+
+
+
+ maven-enforcer-plugin
+ 1.3.1
+
+
+ enforce
+ none
+
+
+
+
+
+ maven-dependency-plugin
+ 2.8
+
+
+ copy-dependencies
+ package
+
+ copy-dependencies
+
+
+ ${project.build.directory}/../../interpreter/neo4j
+ false
+ false
+ true
+ runtime
+
+
+
+ copy-artifact
+ package
+
+ copy
+
+
+ ${project.build.directory}/../../interpreter/neo4j
+ false
+ false
+ true
+ runtime
+
+
+ ${project.groupId}
+ ${project.artifactId}
+ ${project.version}
+ ${project.packaging}
+
+
+
+
+
+
+
+
+
+
diff --git a/neo4j/src/main/java/org/apache/zeppelin/graph/neo4j/Neo4jConnectionManager.java b/neo4j/src/main/java/org/apache/zeppelin/graph/neo4j/Neo4jConnectionManager.java
new file mode 100644
index 0000000000..7cd504ef20
--- /dev/null
+++ b/neo4j/src/main/java/org/apache/zeppelin/graph/neo4j/Neo4jConnectionManager.java
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.graph.neo4j;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.zeppelin.interpreter.InterpreterContext;
+import org.apache.zeppelin.resource.Resource;
+import org.apache.zeppelin.resource.ResourcePool;
+import org.neo4j.driver.v1.AuthToken;
+import org.neo4j.driver.v1.AuthTokens;
+import org.neo4j.driver.v1.Config;
+import org.neo4j.driver.v1.Driver;
+import org.neo4j.driver.v1.GraphDatabase;
+import org.neo4j.driver.v1.Session;
+import org.neo4j.driver.v1.StatementResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Neo4j connection manager for Zeppelin.
+ */
+public class Neo4jConnectionManager {
+ static final Logger LOGGER = LoggerFactory.getLogger(Neo4jConnectionManager.class);
+
+ public static final String NEO4J_SERVER_URL = "neo4j.url";
+ public static final String NEO4J_AUTH_TYPE = "neo4j.auth.type";
+ public static final String NEO4J_AUTH_USER = "neo4j.auth.user";
+ public static final String NEO4J_AUTH_PASSWORD = "neo4j.auth.password";
+ public static final String NEO4J_MAX_CONCURRENCY = "neo4j.max.concurrency";
+
+ private static final Pattern PROPERTY_PATTERN = Pattern.compile("\\{\\w+\\}");
+ private static final String REPLACE_CURLY_BRACKETS = "\\{|\\}";
+
+ private static final Pattern $_PATTERN = Pattern.compile("\\$\\w+\\}");
+ private static final String REPLACE_$ = "\\$";
+
+ private Driver driver = null;
+
+ private final String neo4jUrl;
+
+ private final Config config;
+
+ private final AuthToken authToken;
+
+ /**
+ *
+ * Enum type for the AuthToken
+ *
+ */
+ public enum Neo4jAuthType {NONE, BASIC}
+
+ public Neo4jConnectionManager(Properties properties) {
+ this.neo4jUrl = properties.getProperty(NEO4J_SERVER_URL);
+ this.config = Config.build()
+ .withMaxIdleSessions(Integer.parseInt(properties.getProperty(NEO4J_MAX_CONCURRENCY)))
+ .toConfig();
+ String authType = properties.getProperty(NEO4J_AUTH_TYPE);
+ switch (Neo4jAuthType.valueOf(authType.toUpperCase())) {
+ case BASIC:
+ String username = properties.getProperty(NEO4J_AUTH_USER);
+ String password = properties.getProperty(NEO4J_AUTH_PASSWORD);
+ this.authToken = AuthTokens.basic(username, password);
+ break;
+ case NONE:
+ LOGGER.debug("Creating NONE authentication");
+ this.authToken = AuthTokens.none();
+ break;
+ default:
+ throw new RuntimeException("Neo4j authentication type not supported");
+ }
+ }
+
+ private Driver getDriver() {
+ if (driver == null) {
+ driver = GraphDatabase.driver(this.neo4jUrl, this.authToken, this.config);
+ }
+ return driver;
+ }
+
+ public void open() {
+ getDriver();
+ }
+
+ public void close() {
+ getDriver().close();
+ }
+
+ private Session getSession() {
+ return getDriver().session();
+ }
+
+ public StatementResult execute(String cypherQuery,
+ InterpreterContext interpreterContext) {
+ Map params = new HashMap<>();
+ if (interpreterContext != null) {
+ ResourcePool resourcePool = interpreterContext.getResourcePool();
+ Set keys = extractParams(cypherQuery, PROPERTY_PATTERN, REPLACE_CURLY_BRACKETS);
+ keys.addAll(extractParams(cypherQuery, $_PATTERN, REPLACE_$));
+ for (String key : keys) {
+ Resource resource = resourcePool.get(key);
+ if (resource != null) {
+ params.put(key, resource.get());
+ }
+ }
+ }
+ LOGGER.debug("Executing cypher query {} with params {}", cypherQuery, params);
+ StatementResult result;
+ try (Session session = getSession()) {
+ result = params.isEmpty()
+ ? getSession().run(cypherQuery) : getSession().run(cypherQuery, params);
+ }
+ return result;
+ }
+
+ public StatementResult execute(String cypherQuery) {
+ return execute(cypherQuery, null);
+ }
+
+ private Set extractParams(String cypherQuery, Pattern pattern, String replaceChar) {
+ Matcher matcher = pattern.matcher(cypherQuery);
+ Set keys = new HashSet<>();
+ while (matcher.find()) {
+ keys.add(matcher.group().replaceAll(replaceChar, StringUtils.EMPTY));
+ }
+ return keys;
+ }
+
+}
diff --git a/neo4j/src/main/java/org/apache/zeppelin/graph/neo4j/Neo4jCypherInterpreter.java b/neo4j/src/main/java/org/apache/zeppelin/graph/neo4j/Neo4jCypherInterpreter.java
new file mode 100644
index 0000000000..a625522558
--- /dev/null
+++ b/neo4j/src/main/java/org/apache/zeppelin/graph/neo4j/Neo4jCypherInterpreter.java
@@ -0,0 +1,274 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.graph.neo4j;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.zeppelin.graph.neo4j.utils.Neo4jConversionUtils;
+import org.apache.zeppelin.interpreter.Interpreter;
+import org.apache.zeppelin.interpreter.InterpreterContext;
+import org.apache.zeppelin.interpreter.InterpreterResult;
+import org.apache.zeppelin.interpreter.InterpreterResult.Code;
+import org.apache.zeppelin.interpreter.graph.GraphResult;
+import org.apache.zeppelin.scheduler.Scheduler;
+import org.apache.zeppelin.scheduler.SchedulerFactory;
+import org.neo4j.driver.internal.types.InternalTypeSystem;
+import org.neo4j.driver.internal.util.Iterables;
+import org.neo4j.driver.v1.Record;
+import org.neo4j.driver.v1.StatementResult;
+import org.neo4j.driver.v1.Value;
+import org.neo4j.driver.v1.types.Node;
+import org.neo4j.driver.v1.types.Relationship;
+import org.neo4j.driver.v1.types.TypeSystem;
+import org.neo4j.driver.v1.util.Pair;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+/**
+ * Neo4j interpreter for Zeppelin.
+ */
+public class Neo4jCypherInterpreter extends Interpreter {
+ private static final String TABLE = "%table";
+ public static final String NEW_LINE = "\n";
+ public static final String TAB = "\t";
+
+ private static final String MAP_KEY_TEMPLATE = "%s.%s";
+
+ private Map labels;
+
+ private Set types;
+
+ private final Neo4jConnectionManager neo4jConnectionManager;
+
+ private final ObjectMapper jsonMapper = new ObjectMapper();
+
+ public Neo4jCypherInterpreter(Properties properties) {
+ super(properties);
+ this.neo4jConnectionManager = new Neo4jConnectionManager(properties);
+ }
+
+ @Override
+ public void open() {
+ this.neo4jConnectionManager.open();
+ }
+
+ @Override
+ public void close() {
+ this.neo4jConnectionManager.close();
+ }
+
+ public Map getLabels(boolean refresh) {
+ if (labels == null || refresh) {
+ Map old = labels == null ?
+ new LinkedHashMap() : new LinkedHashMap<>(labels);
+ labels = new LinkedHashMap<>();
+ StatementResult result = this.neo4jConnectionManager.execute("CALL db.labels()");
+ Set colors = new HashSet<>();
+ while (result.hasNext()) {
+ Record record = result.next();
+ String label = record.get("label").asString();
+ String color = old.get(label);
+ while (color == null || colors.contains(color)) {
+ color = Neo4jConversionUtils.getRandomLabelColor();
+ }
+ colors.add(color);
+ labels.put(label, color);
+ }
+ }
+ return labels;
+ }
+
+ private Set getTypes(boolean refresh) {
+ if (types == null || refresh) {
+ types = new HashSet<>();
+ StatementResult result = this.neo4jConnectionManager.execute("CALL db.relationshipTypes()");
+ while (result.hasNext()) {
+ Record record = result.next();
+ types.add(record.get("relationshipType").asString());
+ }
+ }
+ return types;
+ }
+
+ @Override
+ public InterpreterResult interpret(String cypherQuery, InterpreterContext interpreterContext) {
+ logger.info("Opening session");
+ if (StringUtils.isBlank(cypherQuery)) {
+ return new InterpreterResult(Code.SUCCESS);
+ }
+ try {
+ StatementResult result = this.neo4jConnectionManager.execute(cypherQuery,
+ interpreterContext);
+ Set nodes = new HashSet<>();
+ Set relationships = new HashSet<>();
+ List columns = new ArrayList<>();
+ List> lines = new ArrayList>();
+ while (result.hasNext()) {
+ Record record = result.next();
+ List> fields = record.fields();
+ List line = new ArrayList<>();
+ for (Pair field : fields) {
+ if (field.value().hasType(InternalTypeSystem.TYPE_SYSTEM.NODE())) {
+ nodes.add(field.value().asNode());
+ } else if (field.value().hasType(InternalTypeSystem.TYPE_SYSTEM.RELATIONSHIP())) {
+ relationships.add(field.value().asRelationship());
+ } else if (field.value().hasType(InternalTypeSystem.TYPE_SYSTEM.PATH())) {
+ nodes.addAll(Iterables.asList(field.value().asPath().nodes()));
+ relationships.addAll(Iterables.asList(field.value().asPath().relationships()));
+ } else {
+ setTabularResult(field.key(), field.value(), columns, line,
+ InternalTypeSystem.TYPE_SYSTEM);
+ }
+ }
+ if (!line.isEmpty()) {
+ lines.add(line);
+ }
+ }
+ if (!nodes.isEmpty()) {
+ return renderGraph(nodes, relationships);
+ } else {
+ return renderTable(columns, lines);
+ }
+ } catch (Exception e) {
+ logger.error("Exception while interpreting cypher query", e);
+ return new InterpreterResult(Code.ERROR, e.getMessage());
+ }
+ }
+
+ private void setTabularResult(String key, Object obj, List columns, List line,
+ TypeSystem typeSystem) {
+ if (obj instanceof Value) {
+ Value value = (Value) obj;
+ if (value.hasType(typeSystem.MAP())) {
+ Map map = value.asMap();
+ for (Entry entry : map.entrySet()) {
+ setTabularResult(String.format(MAP_KEY_TEMPLATE, key, entry.getKey()), entry.getValue(),
+ columns, line, typeSystem);
+ }
+ } else {
+ addValueToLine(key, columns, line, value);
+ }
+ } else if (obj instanceof Map) {
+ Map map = (Map) obj;
+ for (Entry entry : map.entrySet()) {
+ setTabularResult(String.format(MAP_KEY_TEMPLATE, key, entry.getKey()), entry.getValue(),
+ columns, line, typeSystem);
+ }
+ } else {
+ addValueToLine(key, columns, line, obj);
+ }
+ }
+
+ private void addValueToLine(String key, List columns, List line, Object value) {
+ if (!columns.contains(key)) {
+ columns.add(key);
+ }
+ int position = columns.indexOf(key);
+ if (line.size() < columns.size()) {
+ for (int i = line.size(); i < columns.size(); i++) {
+ line.add(null);
+ }
+ }
+ if (value != null) {
+ if (value instanceof Value) {
+ Value val = (Value) value;
+ if (val.hasType(InternalTypeSystem.TYPE_SYSTEM.LIST())) {
+ value = val.asList();
+ } else if (val.hasType(InternalTypeSystem.TYPE_SYSTEM.MAP())) {
+ value = val.asMap();
+ }
+ }
+ if (value instanceof Collection) {
+ try {
+ value = jsonMapper.writer().writeValueAsString(value);
+ } catch (Exception ignored) {}
+ }
+ }
+ line.set(position, value == null ? null : value.toString());
+ }
+
+ private InterpreterResult renderTable(List cols, List> lines) {
+ logger.info("Executing renderTable method");
+ StringBuilder msg = null;
+ if (cols.isEmpty()) {
+ msg = new StringBuilder();
+ } else {
+ msg = new StringBuilder(TABLE);
+ msg.append(NEW_LINE);
+ msg.append(StringUtils.join(cols, TAB));
+ msg.append(NEW_LINE);
+ for (List line : lines) {
+ if (line.size() < cols.size()) {
+ for (int i = line.size(); i < cols.size(); i++) {
+ line.add(null);
+ }
+ }
+ msg.append(StringUtils.join(line, TAB));
+ msg.append(NEW_LINE);
+ }
+ }
+ return new InterpreterResult(Code.SUCCESS, msg.toString());
+ }
+
+ private InterpreterResult renderGraph(Set nodes,
+ Set relationships) {
+ logger.info("Executing renderGraph method");
+ List nodesList = new ArrayList<>();
+ List relsList = new ArrayList<>();
+ for (Relationship rel : relationships) {
+ relsList.add(Neo4jConversionUtils.toZeppelinRelationship(rel));
+ }
+ Map labels = getLabels(true);
+ for (Node node : nodes) {
+ nodesList.add(Neo4jConversionUtils.toZeppelinNode(node, labels));
+ }
+ return new GraphResult(Code.SUCCESS,
+ new GraphResult.Graph(nodesList, relsList, labels, getTypes(true), true));
+ }
+
+ @Override
+ public Scheduler getScheduler() {
+ return SchedulerFactory.singleton()
+ .createOrGetParallelScheduler(Neo4jCypherInterpreter.class.getName() + this.hashCode(),
+ Integer.parseInt(getProperty(Neo4jConnectionManager.NEO4J_MAX_CONCURRENCY)));
+ }
+
+ @Override
+ public int getProgress(InterpreterContext context) {
+ return 0;
+ }
+
+ @Override
+ public FormType getFormType() {
+ return FormType.SIMPLE;
+ }
+
+ @Override
+ public void cancel(InterpreterContext context) {
+ }
+
+}
diff --git a/neo4j/src/main/java/org/apache/zeppelin/graph/neo4j/utils/Neo4jConversionUtils.java b/neo4j/src/main/java/org/apache/zeppelin/graph/neo4j/utils/Neo4jConversionUtils.java
new file mode 100644
index 0000000000..484940198a
--- /dev/null
+++ b/neo4j/src/main/java/org/apache/zeppelin/graph/neo4j/utils/Neo4jConversionUtils.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.graph.neo4j.utils;
+
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.neo4j.driver.v1.types.Node;
+import org.neo4j.driver.v1.types.Relationship;
+
+/**
+ * Neo4jConversionUtils
+ */
+public class Neo4jConversionUtils {
+ private Neo4jConversionUtils() {}
+
+ private static final String[] LETTERS = "0123456789ABCDEF".split("");
+
+ public static final String COLOR_GREY = "#D3D3D3";
+
+ public static org.apache.zeppelin.tabledata.Node toZeppelinNode(Node n,
+ Map graphLabels) {
+ Set labels = new LinkedHashSet<>();
+ String firstLabel = null;
+ for (String label : n.labels()) {
+ if (firstLabel == null) {
+ firstLabel = label;
+ }
+ labels.add(label);
+ }
+ return new org.apache.zeppelin.tabledata.Node(n.id(), n.asMap(),
+ labels);
+ }
+
+ public static org.apache.zeppelin.tabledata.Relationship
+ toZeppelinRelationship(Relationship r) {
+ return new org.apache.zeppelin.tabledata.Relationship(r.id(), r.asMap(),
+ r.startNodeId(), r.endNodeId(), r.type());
+ }
+
+ public static String getRandomLabelColor() {
+ char[] color = new char[7];
+ color[0] = '#';
+ for (int i = 1; i < color.length; i++) {
+ color[i] = LETTERS[(int) Math.floor(Math.random() * 16)].charAt(0);
+ }
+ return new String(color);
+ }
+
+}
diff --git a/neo4j/src/main/resources/interpreter-setting.json b/neo4j/src/main/resources/interpreter-setting.json
new file mode 100644
index 0000000000..8db4367cc3
--- /dev/null
+++ b/neo4j/src/main/resources/interpreter-setting.json
@@ -0,0 +1,42 @@
+[
+ {
+ "group": "neo4j",
+ "name": "neo4j",
+ "className": "org.apache.zeppelin.graph.neo4j.Neo4jCypherInterpreter",
+ "properties": {
+ "neo4j.url": {
+ "envName": null,
+ "propertyName": "neo4j.url",
+ "defaultValue": "bolt://localhost:7687",
+ "description": "The Neo4j's BOLT url."
+ },
+ "neo4j.auth.type": {
+ "envName": null,
+ "propertyName": "neo4j.auth.type",
+ "defaultValue": "BASIC",
+ "description": "The Neo4j's authentication type (NONE, BASIC)."
+ },
+ "neo4j.auth.user": {
+ "envName": null,
+ "propertyName": "neo4j.auth.user",
+ "defaultValue": "",
+ "description": "The Neo4j user name."
+ },
+ "neo4j.auth.password": {
+ "envName": null,
+ "propertyName": "neo4j.auth.password",
+ "defaultValue": "",
+ "description": "The Neo4j user password."
+ },
+ "neo4j.max.concurrency": {
+ "envName": null,
+ "propertyName": "neo4j.max.concurrency",
+ "defaultValue": "50",
+ "description": "Max concurrency call from Zeppelin to Neo4j server."
+ }
+ },
+ "editor": {
+ "editOnDblClick": false
+ }
+ }
+]
diff --git a/neo4j/src/test/java/org/apache/zeppelin/graph/neo4j/Neo4jCypherInterpreterTest.java b/neo4j/src/test/java/org/apache/zeppelin/graph/neo4j/Neo4jCypherInterpreterTest.java
new file mode 100644
index 0000000000..1bb14b71e1
--- /dev/null
+++ b/neo4j/src/test/java/org/apache/zeppelin/graph/neo4j/Neo4jCypherInterpreterTest.java
@@ -0,0 +1,249 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.graph.neo4j;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.zeppelin.display.AngularObjectRegistry;
+import org.apache.zeppelin.display.GUI;
+import org.apache.zeppelin.graph.neo4j.Neo4jConnectionManager.Neo4jAuthType;
+import org.apache.zeppelin.interpreter.InterpreterContext;
+import org.apache.zeppelin.interpreter.InterpreterContextRunner;
+import org.apache.zeppelin.interpreter.InterpreterGroup;
+import org.apache.zeppelin.interpreter.InterpreterOutput;
+import org.apache.zeppelin.interpreter.InterpreterResult;
+import org.apache.zeppelin.interpreter.InterpreterResult.Code;
+import org.apache.zeppelin.interpreter.graph.GraphResult;
+import org.apache.zeppelin.resource.LocalResourcePool;
+import org.apache.zeppelin.user.AuthenticationInfo;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+import org.neo4j.harness.ServerControls;
+import org.neo4j.harness.TestServerBuilders;
+
+import com.google.gson.Gson;
+
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class Neo4jCypherInterpreterTest {
+
+ private Neo4jCypherInterpreter interpreter;
+
+ private InterpreterContext context;
+
+ private static ServerControls server;
+
+ private static final Gson gson = new Gson();
+
+ private static final String LABEL_PERSON = "Person";
+ private static final String REL_KNOWS = "KNOWS";
+
+ private static final String CYPHER_FOREACH = "FOREACH (x in range(1,1000) | CREATE (:%s{name: \"name\" + x, age: %s}))";
+ private static final String CHPHER_UNWIND = "UNWIND range(1,1000) as x "
+ + "MATCH (n), (m) WHERE id(n) = x AND id(m) = toInt(rand() * 1000) "
+ + "CREATE (n)-[:%s]->(m)";
+
+ @BeforeClass
+ public static void setUpNeo4jServer() throws Exception {
+ server = TestServerBuilders.newInProcessBuilder()
+ .withConfig("dbms.security.auth_enabled","false")
+ .withFixture(String.format(CYPHER_FOREACH, LABEL_PERSON, "x % 10"))
+ .withFixture(String.format(CHPHER_UNWIND, REL_KNOWS))
+ .newServer();
+ }
+
+ @AfterClass
+ public static void tearDownNeo4jServer() throws Exception {
+ server.close();
+ }
+
+ @Before
+ public void setUpZeppelin() {
+ Properties p = new Properties();
+ p.setProperty(Neo4jConnectionManager.NEO4J_SERVER_URL, server.boltURI().toString());
+ p.setProperty(Neo4jConnectionManager.NEO4J_AUTH_TYPE, Neo4jAuthType.NONE.toString());
+ p.setProperty(Neo4jConnectionManager.NEO4J_MAX_CONCURRENCY, "50");
+ interpreter = new Neo4jCypherInterpreter(p);
+ context = new InterpreterContext("note", "id", null, "title", "text",
+ new AuthenticationInfo(),
+ new HashMap(),
+ new GUI(),
+ new AngularObjectRegistry(new InterpreterGroup().getId(), null),
+ new LocalResourcePool("id"),
+ new LinkedList(),
+ new InterpreterOutput(null));
+ }
+
+ @After
+ public void tearDownZeppelin() throws Exception {
+ interpreter.close();
+ }
+
+ @Test
+ public void testTableWithArray() {
+ interpreter.open();
+ InterpreterResult result = interpreter.interpret("return 'a' as colA, 'b' as colB, [1, 2, 3] as colC", context);
+ assertEquals(Code.SUCCESS, result.code());
+ final String tableResult = "colA\tcolB\tcolC\n\"a\"\t\"b\"\t[1,2,3]\n";
+ assertEquals(tableResult, result.toString().replace("%table ", StringUtils.EMPTY));
+
+ result = interpreter.interpret("return 'a' as colA, 'b' as colB, [{key: \"value\"}, {key: 1}] as colC", context);
+ assertEquals(Code.SUCCESS, result.code());
+ final String tableResultWithMap = "colA\tcolB\tcolC\n\"a\"\t\"b\"\t[{\"key\":\"value\"},{\"key\":1}]\n";
+ assertEquals(tableResultWithMap, result.toString().replace("%table ", StringUtils.EMPTY));
+ }
+
+ @Test
+ public void testCreateIndex() {
+ interpreter.open();
+ InterpreterResult result = interpreter.interpret("CREATE INDEX ON :Person(name)", context);
+ assertEquals(Code.SUCCESS, result.code());
+ assertEquals(StringUtils.EMPTY, result.toString());
+ }
+
+ @Test
+ public void testRenderTable() {
+ interpreter.open();
+ InterpreterResult result = interpreter.interpret("MATCH (n:Person) "
+ + "WHERE n.name IN ['name1', 'name2', 'name3'] "
+ + "RETURN n.name AS name, n.age AS age", context);
+ assertEquals(Code.SUCCESS, result.code());
+ final String tableResult = "name\tage\n\"name1\"\t1\n\"name2\"\t2\n\"name3\"\t3\n";
+ assertEquals(tableResult, result.toString().replace("%table ", StringUtils.EMPTY));
+ }
+
+ @Test
+ public void testRenderMap() {
+ interpreter.open();
+ final String jsonQuery = "RETURN {key: \"value\", listKey: [{inner: \"Map1\"}, {inner: \"Map2\"}]} as object";
+ final String objectKey = "object.key";
+ final String objectListKey = "object.listKey";
+ InterpreterResult result = interpreter.interpret(jsonQuery, context);
+ assertEquals(Code.SUCCESS, result.code());
+ String[] rows = result.toString().replace("%table ", StringUtils.EMPTY).split(Neo4jCypherInterpreter.NEW_LINE);
+ assertEquals(rows.length, 2);
+ List header = Arrays.asList(rows[0].split(Neo4jCypherInterpreter.TAB));
+ assertEquals(header.contains(objectKey), true);
+ assertEquals(header.contains(objectListKey), true);
+ List row = Arrays.asList(rows[1].split(Neo4jCypherInterpreter.TAB));
+ assertEquals(row.size(), header.size());
+ assertEquals(row.get(header.indexOf(objectKey)), "value");
+ assertEquals(row.get(header.indexOf(objectListKey)), "[{\"inner\":\"Map1\"},{\"inner\":\"Map2\"}]");
+
+ final String query = "WITH [{key: \"value\", listKey: [{inner: \"Map1\"}, {inner: \"Map2\"}]},"
+ + "{key: \"value2\", listKey: [{inner: \"Map12\"}, {inner: \"Map22\"}]}] "
+ + "AS array UNWIND array AS object RETURN object";
+ result = interpreter.interpret(query, context);
+ assertEquals(Code.SUCCESS, result.code());
+ rows = result.toString().replace("%table ", StringUtils.EMPTY).split(Neo4jCypherInterpreter.NEW_LINE);
+ assertEquals(rows.length, 3);
+ header = Arrays.asList(rows[0].split(Neo4jCypherInterpreter.TAB));
+ assertEquals(header.contains(objectKey), true);
+ assertEquals(header.contains(objectListKey), true);
+ row = Arrays.asList(rows[1].split(Neo4jCypherInterpreter.TAB));
+ assertEquals(row.size(), header.size());
+ assertEquals(row.get(header.indexOf(objectKey)), "value");
+ assertEquals(row.get(header.indexOf(objectListKey)), "[{\"inner\":\"Map1\"},{\"inner\":\"Map2\"}]");
+ row = Arrays.asList(rows[2].split(Neo4jCypherInterpreter.TAB));
+ assertEquals(row.size(), header.size());
+ assertEquals(row.get(header.indexOf(objectKey)), "value2");
+ assertEquals(row.get(header.indexOf(objectListKey)), "[{\"inner\":\"Map12\"},{\"inner\":\"Map22\"}]");
+
+ final String jsonListWithNullQuery = "WITH [{key: \"value\", listKey: null},"
+ + "{key: \"value2\", listKey: [{inner: \"Map1\"}, {inner: \"Map2\"}]}] "
+ + "AS array UNWIND array AS object RETURN object";
+ result = interpreter.interpret(jsonListWithNullQuery, context);
+ assertEquals(Code.SUCCESS, result.code());
+ rows = result.toString().replace("%table ", StringUtils.EMPTY).split(Neo4jCypherInterpreter.NEW_LINE);
+ assertEquals(rows.length, 3);
+ header = Arrays.asList(rows[0].split(Neo4jCypherInterpreter.TAB, -1));
+ assertEquals(header.contains(objectKey), true);
+ assertEquals(header.contains(objectListKey), true);
+ row = Arrays.asList(rows[1].split(Neo4jCypherInterpreter.TAB, -1));
+ assertEquals(row.size(), header.size());
+ assertEquals(row.get(header.indexOf(objectKey)), "value");
+ assertEquals(row.get(header.indexOf(objectListKey)), StringUtils.EMPTY);
+ assertEquals(row.get(header.indexOf(objectListKey)), "");
+ row = Arrays.asList(rows[2].split(Neo4jCypherInterpreter.TAB, -1));
+ assertEquals(row.size(), header.size());
+ assertEquals(row.get(header.indexOf(objectKey)), "value2");
+ assertEquals(row.get(header.indexOf(objectListKey)), "[{\"inner\":\"Map1\"},{\"inner\":\"Map2\"}]");
+
+ final String jsonListWithoutListKeyQuery = "WITH [{key: \"value\"},"
+ + "{key: \"value2\", listKey: [{inner: \"Map1\"}, {inner: \"Map2\"}]}] "
+ + "AS array UNWIND array AS object RETURN object";
+ result = interpreter.interpret(jsonListWithoutListKeyQuery, context);
+ assertEquals(Code.SUCCESS, result.code());
+ rows = result.toString().replace("%table ", StringUtils.EMPTY).split(Neo4jCypherInterpreter.NEW_LINE);
+ assertEquals(rows.length, 3);
+ header = Arrays.asList(rows[0].split(Neo4jCypherInterpreter.TAB, -1));
+ assertEquals(header.contains(objectKey), true);
+ assertEquals(header.contains(objectListKey), true);
+ row = Arrays.asList(rows[1].split(Neo4jCypherInterpreter.TAB, -1));
+ assertEquals(row.size(), header.size());
+ assertEquals(row.get(header.indexOf(objectKey)), "value");
+ assertEquals(row.get(header.indexOf(objectListKey)), StringUtils.EMPTY);
+ row = Arrays.asList(rows[2].split(Neo4jCypherInterpreter.TAB, -1));
+ assertEquals(row.size(), header.size());
+ assertEquals(row.get(header.indexOf(objectKey)), "value2");
+ assertEquals(row.get(header.indexOf(objectListKey)), "[{\"inner\":\"Map1\"},{\"inner\":\"Map2\"}]");
+ }
+
+ @Test
+ public void testRenderNetwork() {
+ interpreter.open();
+ InterpreterResult result = interpreter.interpret("MATCH (n)-[r:KNOWS]-(m) RETURN n, r, m LIMIT 1", context);
+ GraphResult.Graph graph = gson.fromJson(result.toString().replace("%network ", StringUtils.EMPTY), GraphResult.Graph.class);
+ assertEquals(2, graph.getNodes().size());
+ assertEquals(true, graph.getNodes().iterator().next().getLabel().equals(LABEL_PERSON));
+ assertEquals(1, graph.getEdges().size());
+ assertEquals(true, graph.getEdges().iterator().next().getLabel().equals(REL_KNOWS));
+ assertEquals(1, graph.getLabels().size());
+ assertEquals(1, graph.getTypes().size());
+ assertEquals(true, graph.getLabels().containsKey(LABEL_PERSON));
+ assertEquals(REL_KNOWS, graph.getTypes().iterator().next());
+ assertEquals(Code.SUCCESS, result.code());
+ }
+
+ @Test
+ public void testFallingQuery() {
+ interpreter.open();
+ final String ERROR_MSG_EMPTY = "";
+ InterpreterResult result = interpreter.interpret(StringUtils.EMPTY, context);
+ assertEquals(Code.SUCCESS, result.code());
+ assertEquals(ERROR_MSG_EMPTY, result.toString());
+
+ result = interpreter.interpret(null, context);
+ assertEquals(Code.SUCCESS, result.code());
+ assertEquals(ERROR_MSG_EMPTY, result.toString());
+
+ result = interpreter.interpret("MATCH (n:Person{name: }) RETURN n.name AS name, n.age AS age", context);
+ assertEquals(Code.ERROR, result.code());
+ }
+
+}
diff --git a/pig/pom.xml b/pig/pom.xml
index f76a3f90cc..4a56a34290 100644
--- a/pig/pom.xml
+++ b/pig/pom.xml
@@ -22,9 +22,10 @@
4.0.0
- zeppelin
+ interpreter-parent
org.apache.zeppelin
0.8.0-SNAPSHOT
+ ../interpreter-parent
org.apache.zeppelin
@@ -36,6 +37,7 @@
http://zeppelin.apache.org
+ pig
0.17.0
2.6.0
0.7.0
@@ -175,58 +177,13 @@
maven-enforcer-plugin
-
-
- enforce
- none
-
-
-
maven-dependency-plugin
-
-
- copy-dependencies
- package
-
- copy-dependencies
-
-
- ${project.build.directory}/../../interpreter/pig
-
- false
- false
- true
- runtime
-
-
-
- copy-artifact
- package
-
- copy
-
-
- ${project.build.directory}/../../interpreter/pig
-
- false
- false
- true
- runtime
-
-
- ${project.groupId}
- ${project.artifactId}
- ${project.version}
- ${project.packaging}
-
-
-
-
-
-
+
+ maven-resources-plugin
+
maven-surefire-plugin
diff --git a/pig/src/main/java/org/apache/zeppelin/pig/PigInterpreter.java b/pig/src/main/java/org/apache/zeppelin/pig/PigInterpreter.java
index 893741651f..0f2d59bb9e 100644
--- a/pig/src/main/java/org/apache/zeppelin/pig/PigInterpreter.java
+++ b/pig/src/main/java/org/apache/zeppelin/pig/PigInterpreter.java
@@ -18,7 +18,6 @@
package org.apache.zeppelin.pig;
import org.apache.commons.io.output.ByteArrayOutputStream;
-import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.pig.PigServer;
import org.apache.pig.impl.logicalLayer.FrontendException;
@@ -60,7 +59,7 @@ public class PigInterpreter extends BasePigInterpreter {
}
try {
pigServer = new PigServer(execType);
- for (Map.Entry entry : getProperty().entrySet()) {
+ for (Map.Entry entry : getProperties().entrySet()) {
if (!entry.getKey().toString().startsWith("zeppelin.")) {
pigServer.getPigContext().getProperties().setProperty(entry.getKey().toString(),
entry.getValue().toString());
diff --git a/pig/src/main/java/org/apache/zeppelin/pig/PigQueryInterpreter.java b/pig/src/main/java/org/apache/zeppelin/pig/PigQueryInterpreter.java
index d3bc4325c4..da3d50e09b 100644
--- a/pig/src/main/java/org/apache/zeppelin/pig/PigQueryInterpreter.java
+++ b/pig/src/main/java/org/apache/zeppelin/pig/PigQueryInterpreter.java
@@ -55,7 +55,7 @@ public class PigQueryInterpreter extends BasePigInterpreter {
}
@Override
- public void open() {
+ public void open() throws InterpreterException {
pigServer = getPigInterpreter().getPigServer();
maxResult = Integer.parseInt(getProperty(MAX_RESULTS));
}
@@ -159,7 +159,7 @@ public class PigQueryInterpreter extends BasePigInterpreter {
return this.pigServer;
}
- private PigInterpreter getPigInterpreter() {
+ private PigInterpreter getPigInterpreter() throws InterpreterException {
LazyOpenInterpreter lazy = null;
PigInterpreter pig = null;
Interpreter p = getInterpreterInTheSameSessionByClassName(PigInterpreter.class.getName());
diff --git a/pig/src/test/java/org/apache/zeppelin/pig/PigQueryInterpreterTest.java b/pig/src/test/java/org/apache/zeppelin/pig/PigQueryInterpreterTest.java
index de297c75e9..f14cad6f27 100644
--- a/pig/src/test/java/org/apache/zeppelin/pig/PigQueryInterpreterTest.java
+++ b/pig/src/test/java/org/apache/zeppelin/pig/PigQueryInterpreterTest.java
@@ -21,6 +21,7 @@ package org.apache.zeppelin.pig;
import org.apache.commons.io.IOUtils;
import org.apache.zeppelin.interpreter.Interpreter;
import org.apache.zeppelin.interpreter.InterpreterContext;
+import org.apache.zeppelin.interpreter.InterpreterException;
import org.apache.zeppelin.interpreter.InterpreterGroup;
import org.apache.zeppelin.interpreter.InterpreterResult;
import org.junit.After;
@@ -48,7 +49,7 @@ public class PigQueryInterpreterTest {
private InterpreterContext context;
@Before
- public void setUp() {
+ public void setUp() throws InterpreterException {
Properties properties = new Properties();
properties.put("zeppelin.pig.execType", "local");
properties.put("zeppelin.pig.maxResult", "20");
diff --git a/pom.xml b/pom.xml
index acfcd0572c..7ff9acd7ae 100644
--- a/pom.xml
+++ b/pom.xml
@@ -76,6 +76,7 @@
bigquery
alluxio
scio
+ neo4j
zeppelin-web
zeppelin-server
zeppelin-jupyter
diff --git a/python/pom.xml b/python/pom.xml
index d46cd10c2d..a906b5d5f5 100644
--- a/python/pom.xml
+++ b/python/pom.xml
@@ -20,10 +20,10 @@
4.0.0
- zeppelin
+ interpreter-parent
org.apache.zeppelin
0.8.0-SNAPSHOT
- ..
+ ../interpreter-parent
org.apache.zeppelin
@@ -33,6 +33,7 @@
Zeppelin: Python interpreter
+ python
0.9.2
**/PythonInterpreterWithPythonInstalledTest.java,
@@ -141,17 +142,6 @@
-
- maven-enforcer-plugin
- 1.3.1
-
-
- enforce
- none
-
-
-
-
org.codehaus.mojo
wagon-maven-plugin
@@ -212,47 +202,14 @@
+
+ maven-enforcer-plugin
+
maven-dependency-plugin
- 2.8
-
-
- copy-dependencies
- package
-
- copy-dependencies
-
-
- ${project.build.directory}/../../interpreter/python
- false
- false
- true
- runtime
-
-
-
- copy-artifact
- package
-
- copy
-
-
- ${project.build.directory}/../../interpreter/python
- false
- false
- true
- runtime
-
-
- ${project.groupId}
- ${project.artifactId}
- ${project.version}
- ${project.packaging}
-
-
-
-
-
+
+
+ maven-resources-plugin
diff --git a/python/src/main/java/org/apache/zeppelin/python/IPythonClient.java b/python/src/main/java/org/apache/zeppelin/python/IPythonClient.java
index 40b9afdac4..05fe4ba47a 100644
--- a/python/src/main/java/org/apache/zeppelin/python/IPythonClient.java
+++ b/python/src/main/java/org/apache/zeppelin/python/IPythonClient.java
@@ -40,7 +40,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
-import java.util.Random;
+import java.security.SecureRandom;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -55,7 +55,7 @@ public class IPythonClient {
private final IPythonGrpc.IPythonBlockingStub blockingStub;
private final IPythonGrpc.IPythonStub asyncStub;
- private Random random = new Random();
+ private SecureRandom random = new SecureRandom();
/**
* Construct client for accessing RouteGuide server at {@code host:port}.
diff --git a/python/src/main/java/org/apache/zeppelin/python/IPythonInterpreter.java b/python/src/main/java/org/apache/zeppelin/python/IPythonInterpreter.java
index 193c3434c8..1c2ced501b 100644
--- a/python/src/main/java/org/apache/zeppelin/python/IPythonInterpreter.java
+++ b/python/src/main/java/org/apache/zeppelin/python/IPythonInterpreter.java
@@ -30,6 +30,7 @@ import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.zeppelin.interpreter.Interpreter;
import org.apache.zeppelin.interpreter.InterpreterContext;
+import org.apache.zeppelin.interpreter.InterpreterException;
import org.apache.zeppelin.interpreter.InterpreterResult;
import org.apache.zeppelin.interpreter.remote.RemoteInterpreterUtils;
import org.apache.zeppelin.interpreter.thrift.InterpreterCompletion;
@@ -112,19 +113,20 @@ public class IPythonInterpreter extends Interpreter implements ExecuteResultHand
}
@Override
- public void open() {
+ public void open() throws InterpreterException {
try {
if (ipythonClient != null) {
// IPythonInterpreter might already been opened by PythonInterpreter
return;
}
- pythonExecutable = getProperty().getProperty("zeppelin.python", "python");
+ pythonExecutable = getProperty("zeppelin.python", "python");
LOGGER.info("Python Exec: " + pythonExecutable);
+
ipythonLaunchTimeout = Long.parseLong(
- getProperty().getProperty("zeppelin.ipython.launch.timeout", "30000"));
+ getProperty("zeppelin.ipython.launch.timeout", "30000"));
this.zeppelinContext = new PythonZeppelinContext(
getInterpreterGroup().getInterpreterHookRegistry(),
- Integer.parseInt(getProperty().getProperty("zeppelin.python.maxResult", "1000")));
+ Integer.parseInt(getProperty("zeppelin.python.maxResult", "1000")));
int ipythonPort = RemoteInterpreterUtils.findRandomAvailablePortOnAllLocalInterfaces();
int jvmGatewayPort = RemoteInterpreterUtils.findRandomAvailablePortOnAllLocalInterfaces();
LOGGER.info("Launching IPython Kernel at port: " + ipythonPort);
@@ -243,16 +245,7 @@ public class IPythonInterpreter extends Interpreter implements ExecuteResultHand
}
}
- Map envs = EnvironmentUtils.getProcEnvironment();
- if (envs.containsKey("PYTHONPATH")) {
- if (additionalPythonPath != null) {
- envs.put("PYTHONPATH", additionalPythonPath + ":" + envs.get("PYTHONPATH"));
- }
- } else {
- envs.put("PYTHONPATH", additionalPythonPath);
- }
-
- LOGGER.info("PYTHONPATH: " + envs.get("PYTHONPATH"));
+ Map envs = setupIPythonEnv();
executor.execute(cmd, envs, this);
// wait until IPython kernel is started or timeout
@@ -284,6 +277,18 @@ public class IPythonInterpreter extends Interpreter implements ExecuteResultHand
}
}
+ protected Map setupIPythonEnv() throws IOException {
+ Map envs = EnvironmentUtils.getProcEnvironment();
+ if (envs.containsKey("PYTHONPATH")) {
+ if (additionalPythonPath != null) {
+ envs.put("PYTHONPATH", additionalPythonPath + ":" + envs.get("PYTHONPATH"));
+ }
+ } else {
+ envs.put("PYTHONPATH", additionalPythonPath);
+ }
+ return envs;
+ }
+
@Override
public void close() {
if (watchDog != null) {
diff --git a/python/src/main/java/org/apache/zeppelin/python/PythonCondaInterpreter.java b/python/src/main/java/org/apache/zeppelin/python/PythonCondaInterpreter.java
index 0d122f5719..887beb8ce7 100644
--- a/python/src/main/java/org/apache/zeppelin/python/PythonCondaInterpreter.java
+++ b/python/src/main/java/org/apache/zeppelin/python/PythonCondaInterpreter.java
@@ -67,7 +67,8 @@ public class PythonCondaInterpreter extends Interpreter {
}
@Override
- public InterpreterResult interpret(String st, InterpreterContext context) {
+ public InterpreterResult interpret(String st, InterpreterContext context)
+ throws InterpreterException {
InterpreterOutput out = context.out;
Matcher activateMatcher = PATTERN_COMMAND_ACTIVATE.matcher(st);
Matcher createMatcher = PATTERN_COMMAND_CREATE.matcher(st);
@@ -126,7 +127,7 @@ public class PythonCondaInterpreter extends Interpreter {
}
private void changePythonEnvironment(String envName)
- throws IOException, InterruptedException {
+ throws IOException, InterruptedException, InterpreterException {
PythonInterpreter python = getPythonInterpreter();
String binPath = null;
if (envName == null) {
@@ -147,13 +148,13 @@ public class PythonCondaInterpreter extends Interpreter {
python.setPythonCommand(binPath);
}
- private void restartPythonProcess() {
+ private void restartPythonProcess() throws InterpreterException {
PythonInterpreter python = getPythonInterpreter();
python.close();
python.open();
}
- protected PythonInterpreter getPythonInterpreter() {
+ protected PythonInterpreter getPythonInterpreter() throws InterpreterException {
LazyOpenInterpreter lazy = null;
PythonInterpreter python = null;
Interpreter p =
@@ -213,7 +214,7 @@ public class PythonCondaInterpreter extends Interpreter {
}
private InterpreterResult runCondaActivate(String envName)
- throws IOException, InterruptedException {
+ throws IOException, InterruptedException, InterpreterException {
if (null == envName || envName.isEmpty()) {
return new InterpreterResult(Code.ERROR, "Env name should be specified");
@@ -226,7 +227,7 @@ public class PythonCondaInterpreter extends Interpreter {
}
private InterpreterResult runCondaDeactivate()
- throws IOException, InterruptedException {
+ throws IOException, InterruptedException, InterpreterException {
changePythonEnvironment(null);
restartPythonProcess();
@@ -375,10 +376,16 @@ public class PythonCondaInterpreter extends Interpreter {
*/
@Override
public Scheduler getScheduler() {
- PythonInterpreter pythonInterpreter = getPythonInterpreter();
- if (pythonInterpreter != null) {
- return pythonInterpreter.getScheduler();
- } else {
+ PythonInterpreter pythonInterpreter = null;
+ try {
+ pythonInterpreter = getPythonInterpreter();
+ if (pythonInterpreter != null) {
+ return pythonInterpreter.getScheduler();
+ } else {
+ return null;
+ }
+ } catch (InterpreterException e) {
+ e.printStackTrace();
return null;
}
}
diff --git a/python/src/main/java/org/apache/zeppelin/python/PythonDockerInterpreter.java b/python/src/main/java/org/apache/zeppelin/python/PythonDockerInterpreter.java
index cb0f62078f..22f6c2ee99 100644
--- a/python/src/main/java/org/apache/zeppelin/python/PythonDockerInterpreter.java
+++ b/python/src/main/java/org/apache/zeppelin/python/PythonDockerInterpreter.java
@@ -56,7 +56,8 @@ public class PythonDockerInterpreter extends Interpreter {
}
@Override
- public InterpreterResult interpret(String st, InterpreterContext context) {
+ public InterpreterResult interpret(String st, InterpreterContext context)
+ throws InterpreterException {
File pythonScript = new File(getPythonInterpreter().getScriptPath());
InterpreterOutput out = context.out;
@@ -105,7 +106,7 @@ public class PythonDockerInterpreter extends Interpreter {
}
- public void setPythonCommand(String cmd) {
+ public void setPythonCommand(String cmd) throws InterpreterException {
PythonInterpreter python = getPythonInterpreter();
python.setPythonCommand(cmd);
}
@@ -140,21 +141,27 @@ public class PythonDockerInterpreter extends Interpreter {
*/
@Override
public Scheduler getScheduler() {
- PythonInterpreter pythonInterpreter = getPythonInterpreter();
- if (pythonInterpreter != null) {
- return pythonInterpreter.getScheduler();
- } else {
+ PythonInterpreter pythonInterpreter = null;
+ try {
+ pythonInterpreter = getPythonInterpreter();
+ if (pythonInterpreter != null) {
+ return pythonInterpreter.getScheduler();
+ } else {
+ return null;
+ }
+ } catch (InterpreterException e) {
+ e.printStackTrace();
return null;
}
}
- private void restartPythonProcess() {
+ private void restartPythonProcess() throws InterpreterException {
PythonInterpreter python = getPythonInterpreter();
python.close();
python.open();
}
- protected PythonInterpreter getPythonInterpreter() {
+ protected PythonInterpreter getPythonInterpreter() throws InterpreterException {
LazyOpenInterpreter lazy = null;
PythonInterpreter python = null;
Interpreter p = getInterpreterInTheSameSessionByClassName(PythonInterpreter.class.getName());
@@ -173,7 +180,7 @@ public class PythonDockerInterpreter extends Interpreter {
return python;
}
- public boolean pull(InterpreterOutput out, String image) {
+ public boolean pull(InterpreterOutput out, String image) throws InterpreterException {
int exit = 0;
try {
exit = runCommand(out, "docker", "pull", image);
diff --git a/python/src/main/java/org/apache/zeppelin/python/PythonInterpreter.java b/python/src/main/java/org/apache/zeppelin/python/PythonInterpreter.java
index 50f6a8b9c6..4f897c8d6d 100644
--- a/python/src/main/java/org/apache/zeppelin/python/PythonInterpreter.java
+++ b/python/src/main/java/org/apache/zeppelin/python/PythonInterpreter.java
@@ -57,7 +57,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import py4j.GatewayServer;
-import py4j.commands.Command;
/**
* Python interpreter for Zeppelin.
@@ -101,7 +100,7 @@ public class PythonInterpreter extends Interpreter implements ExecuteResultHandl
File scriptFile = File.createTempFile("zeppelin_python-", ".py", new File("/tmp"));
scriptPath = scriptFile.getAbsolutePath();
} catch (IOException e) {
- throw new InterpreterException(e);
+ throw new RuntimeException(e);
}
}
@@ -116,7 +115,7 @@ public class PythonInterpreter extends Interpreter implements ExecuteResultHandl
return path;
}
- private void createPythonScript() {
+ private void createPythonScript() throws InterpreterException {
File out = new File(scriptPath);
if (out.exists() && out.isDirectory()) {
@@ -131,7 +130,7 @@ public class PythonInterpreter extends Interpreter implements ExecuteResultHandl
return scriptPath;
}
- private void copyFile(File out, String sourceFile) {
+ private void copyFile(File out, String sourceFile) throws InterpreterException {
ClassLoader classLoader = getClass().getClassLoader();
try {
FileOutputStream outStream = new FileOutputStream(out);
@@ -144,7 +143,8 @@ public class PythonInterpreter extends Interpreter implements ExecuteResultHandl
}
}
- private void createGatewayServerAndStartScript() throws UnknownHostException {
+ private void createGatewayServerAndStartScript()
+ throws UnknownHostException, InterpreterException {
createPythonScript();
if (System.getenv("ZEPPELIN_HOME") != null) {
py4jLibPath = System.getenv("ZEPPELIN_HOME") + File.separator + ZEPPELIN_PY4JPATH;
@@ -219,11 +219,11 @@ public class PythonInterpreter extends Interpreter implements ExecuteResultHandl
}
@Override
- public void open() {
+ public void open() throws InterpreterException {
// try IPythonInterpreter first. If it is not available, we will fallback to the original
// python interpreter implementation.
iPythonInterpreter = getIPythonInterpreter();
- if (getProperty().getProperty("zeppelin.python.useIPython", "true").equals("true") &&
+ if (getProperty("zeppelin.python.useIPython", "true").equals("true") &&
iPythonInterpreter.checkIPythonPrerequisite()) {
try {
iPythonInterpreter.open();
@@ -369,7 +369,8 @@ public class PythonInterpreter extends Interpreter implements ExecuteResultHandl
}
@Override
- public InterpreterResult interpret(String cmd, InterpreterContext contextInterpreter) {
+ public InterpreterResult interpret(String cmd, InterpreterContext contextInterpreter)
+ throws InterpreterException {
if (iPythonInterpreter != null) {
return iPythonInterpreter.interpret(cmd, contextInterpreter);
}
@@ -551,7 +552,11 @@ public class PythonInterpreter extends Interpreter implements ExecuteResultHandl
bootstrapCode += line + "\n";
}
- interpret(bootstrapCode, context);
+ try {
+ interpret(bootstrapCode, context);
+ } catch (InterpreterException e) {
+ throw new IOException(e);
+ }
}
public GUI getGui() {
diff --git a/python/src/main/java/org/apache/zeppelin/python/PythonInterpreterPandasSql.java b/python/src/main/java/org/apache/zeppelin/python/PythonInterpreterPandasSql.java
index e73d7b36bd..54984c3ce7 100644
--- a/python/src/main/java/org/apache/zeppelin/python/PythonInterpreterPandasSql.java
+++ b/python/src/main/java/org/apache/zeppelin/python/PythonInterpreterPandasSql.java
@@ -22,6 +22,7 @@ import java.util.Properties;
import org.apache.zeppelin.interpreter.Interpreter;
import org.apache.zeppelin.interpreter.InterpreterContext;
+import org.apache.zeppelin.interpreter.InterpreterException;
import org.apache.zeppelin.interpreter.InterpreterResult;
import org.apache.zeppelin.interpreter.LazyOpenInterpreter;
import org.apache.zeppelin.interpreter.WrappedInterpreter;
@@ -42,7 +43,7 @@ public class PythonInterpreterPandasSql extends Interpreter {
super(property);
}
- PythonInterpreter getPythonInterpreter() {
+ PythonInterpreter getPythonInterpreter() throws InterpreterException {
LazyOpenInterpreter lazy = null;
PythonInterpreter python = null;
Interpreter p = getInterpreterInTheSameSessionByClassName(PythonInterpreter.class.getName());
@@ -62,7 +63,7 @@ public class PythonInterpreterPandasSql extends Interpreter {
}
@Override
- public void open() {
+ public void open() throws InterpreterException {
LOG.info("Open Python SQL interpreter instance: {}", this.toString());
try {
@@ -76,14 +77,15 @@ public class PythonInterpreterPandasSql extends Interpreter {
}
@Override
- public void close() {
+ public void close() throws InterpreterException {
LOG.info("Close Python SQL interpreter instance: {}", this.toString());
Interpreter python = getPythonInterpreter();
python.close();
}
@Override
- public InterpreterResult interpret(String st, InterpreterContext context) {
+ public InterpreterResult interpret(String st, InterpreterContext context)
+ throws InterpreterException {
LOG.info("Running SQL query: '{}' over Pandas DataFrame", st);
Interpreter python = getPythonInterpreter();
diff --git a/python/src/test/java/org/apache/zeppelin/python/IPythonInterpreterTest.java b/python/src/test/java/org/apache/zeppelin/python/IPythonInterpreterTest.java
index 137d622bf8..6a388c2b9b 100644
--- a/python/src/test/java/org/apache/zeppelin/python/IPythonInterpreterTest.java
+++ b/python/src/test/java/org/apache/zeppelin/python/IPythonInterpreterTest.java
@@ -23,6 +23,7 @@ import org.apache.zeppelin.display.ui.Select;
import org.apache.zeppelin.display.ui.TextBox;
import org.apache.zeppelin.interpreter.Interpreter;
import org.apache.zeppelin.interpreter.InterpreterContext;
+import org.apache.zeppelin.interpreter.InterpreterException;
import org.apache.zeppelin.interpreter.InterpreterGroup;
import org.apache.zeppelin.interpreter.InterpreterOutput;
import org.apache.zeppelin.interpreter.InterpreterOutputListener;
@@ -56,7 +57,7 @@ public class IPythonInterpreterTest {
private IPythonInterpreter interpreter;
@Before
- public void setUp() {
+ public void setUp() throws InterpreterException {
Properties properties = new Properties();
interpreter = new IPythonInterpreter(properties);
InterpreterGroup mockInterpreterGroup = mock(InterpreterGroup.class);
@@ -71,11 +72,11 @@ public class IPythonInterpreterTest {
@Test
- public void testIPython() throws IOException, InterruptedException {
+ public void testIPython() throws IOException, InterruptedException, InterpreterException {
testInterpreter(interpreter);
}
- public static void testInterpreter(final Interpreter interpreter) throws IOException, InterruptedException {
+ public static void testInterpreter(final Interpreter interpreter) throws IOException, InterruptedException, InterpreterException {
// to make this test can run under both python2 and python3
InterpreterResult result = interpreter.interpret("from __future__ import print_function", getInterpreterContext());
assertEquals(InterpreterResult.Code.SUCCESS, result.code());
@@ -261,7 +262,11 @@ public class IPythonInterpreterTest {
} catch (InterruptedException e) {
e.printStackTrace();
}
- interpreter.cancel(context2);
+ try {
+ interpreter.cancel(context2);
+ } catch (InterpreterException e) {
+ e.printStackTrace();
+ }
}
}.start();
result = interpreter.interpret("import time\ntime.sleep(10)", context2);
diff --git a/python/src/test/java/org/apache/zeppelin/python/PythonCondaInterpreterTest.java b/python/src/test/java/org/apache/zeppelin/python/PythonCondaInterpreterTest.java
index 897639627c..e6f5fca684 100644
--- a/python/src/test/java/org/apache/zeppelin/python/PythonCondaInterpreterTest.java
+++ b/python/src/test/java/org/apache/zeppelin/python/PythonCondaInterpreterTest.java
@@ -37,7 +37,7 @@ public class PythonCondaInterpreterTest {
private PythonInterpreter python;
@Before
- public void setUp() {
+ public void setUp() throws InterpreterException {
conda = spy(new PythonCondaInterpreter(new Properties()));
python = mock(PythonInterpreter.class);
@@ -57,7 +57,7 @@ public class PythonCondaInterpreterTest {
}
@Test
- public void testListEnv() throws IOException, InterruptedException {
+ public void testListEnv() throws IOException, InterruptedException, InterpreterException {
setMockCondaEnvList();
// list available env
@@ -72,7 +72,7 @@ public class PythonCondaInterpreterTest {
}
@Test
- public void testActivateEnv() throws IOException, InterruptedException {
+ public void testActivateEnv() throws IOException, InterruptedException, InterpreterException {
setMockCondaEnvList();
String envname = "env1";
InterpreterContext context = getInterpreterContext();
@@ -84,7 +84,7 @@ public class PythonCondaInterpreterTest {
}
@Test
- public void testDeactivate() {
+ public void testDeactivate() throws InterpreterException {
InterpreterContext context = getInterpreterContext();
conda.interpret("deactivate", context);
verify(python, times(1)).open();
diff --git a/python/src/test/java/org/apache/zeppelin/python/PythonDockerInterpreterTest.java b/python/src/test/java/org/apache/zeppelin/python/PythonDockerInterpreterTest.java
index 566b5e0b35..e5903949ee 100644
--- a/python/src/test/java/org/apache/zeppelin/python/PythonDockerInterpreterTest.java
+++ b/python/src/test/java/org/apache/zeppelin/python/PythonDockerInterpreterTest.java
@@ -41,7 +41,7 @@ public class PythonDockerInterpreterTest {
private PythonInterpreter python;
@Before
- public void setUp() {
+ public void setUp() throws InterpreterException {
docker = spy(new PythonDockerInterpreter(new Properties()));
python = mock(PythonInterpreter.class);
@@ -58,7 +58,7 @@ public class PythonDockerInterpreterTest {
}
@Test
- public void testActivateEnv() {
+ public void testActivateEnv() throws InterpreterException {
InterpreterContext context = getInterpreterContext();
docker.interpret("activate env", context);
verify(python, times(1)).open();
@@ -68,7 +68,7 @@ public class PythonDockerInterpreterTest {
}
@Test
- public void testDeactivate() {
+ public void testDeactivate() throws InterpreterException {
InterpreterContext context = getInterpreterContext();
docker.interpret("deactivate", context);
verify(python, times(1)).open();
diff --git a/python/src/test/java/org/apache/zeppelin/python/PythonInterpreterMatplotlibTest.java b/python/src/test/java/org/apache/zeppelin/python/PythonInterpreterMatplotlibTest.java
index d649e8979b..877e42881b 100644
--- a/python/src/test/java/org/apache/zeppelin/python/PythonInterpreterMatplotlibTest.java
+++ b/python/src/test/java/org/apache/zeppelin/python/PythonInterpreterMatplotlibTest.java
@@ -22,6 +22,7 @@ import org.apache.zeppelin.display.GUI;
import org.apache.zeppelin.interpreter.Interpreter;
import org.apache.zeppelin.interpreter.InterpreterContext;
import org.apache.zeppelin.interpreter.InterpreterContextRunner;
+import org.apache.zeppelin.interpreter.InterpreterException;
import org.apache.zeppelin.interpreter.InterpreterGroup;
import org.apache.zeppelin.interpreter.InterpreterOutput;
import org.apache.zeppelin.interpreter.InterpreterOutputListener;
@@ -83,7 +84,7 @@ public class PythonInterpreterMatplotlibTest implements InterpreterOutputListene
}
@Test
- public void dependenciesAreInstalled() {
+ public void dependenciesAreInstalled() throws InterpreterException {
// matplotlib
InterpreterResult ret = python.interpret("import matplotlib", context);
assertEquals(ret.message().toString(), InterpreterResult.Code.SUCCESS, ret.code());
@@ -94,7 +95,7 @@ public class PythonInterpreterMatplotlibTest implements InterpreterOutputListene
}
@Test
- public void showPlot() throws IOException {
+ public void showPlot() throws IOException, InterpreterException {
// Simple plot test
InterpreterResult ret;
ret = python.interpret("import matplotlib.pyplot as plt", context);
@@ -111,7 +112,7 @@ public class PythonInterpreterMatplotlibTest implements InterpreterOutputListene
@Test
// Test for when configuration is set to auto-close figures after show().
- public void testClose() throws IOException {
+ public void testClose() throws IOException, InterpreterException {
InterpreterResult ret;
InterpreterResult ret1;
InterpreterResult ret2;
@@ -145,7 +146,7 @@ public class PythonInterpreterMatplotlibTest implements InterpreterOutputListene
@Test
// Test for when configuration is set to not auto-close figures after show().
- public void testNoClose() throws IOException {
+ public void testNoClose() throws IOException, InterpreterException {
InterpreterResult ret;
InterpreterResult ret1;
InterpreterResult ret2;
diff --git a/python/src/test/java/org/apache/zeppelin/python/PythonInterpreterPandasSqlTest.java b/python/src/test/java/org/apache/zeppelin/python/PythonInterpreterPandasSqlTest.java
index 9e918c082f..5d667bd6bb 100644
--- a/python/src/test/java/org/apache/zeppelin/python/PythonInterpreterPandasSqlTest.java
+++ b/python/src/test/java/org/apache/zeppelin/python/PythonInterpreterPandasSqlTest.java
@@ -33,6 +33,7 @@ import org.apache.zeppelin.display.GUI;
import org.apache.zeppelin.interpreter.Interpreter;
import org.apache.zeppelin.interpreter.InterpreterContext;
import org.apache.zeppelin.interpreter.InterpreterContextRunner;
+import org.apache.zeppelin.interpreter.InterpreterException;
import org.apache.zeppelin.interpreter.InterpreterGroup;
import org.apache.zeppelin.interpreter.InterpreterOutput;
import org.apache.zeppelin.interpreter.InterpreterOutputListener;
@@ -107,18 +108,18 @@ public class PythonInterpreterPandasSqlTest implements InterpreterOutputListener
}
@After
- public void afterTest() throws IOException {
+ public void afterTest() throws IOException, InterpreterException {
sql.close();
}
@Test
- public void dependenciesAreInstalled() {
+ public void dependenciesAreInstalled() throws InterpreterException {
InterpreterResult ret = python.interpret("import pandas\nimport pandasql\nimport numpy\n", context);
assertEquals(ret.message().toString(), InterpreterResult.Code.SUCCESS, ret.code());
}
@Test
- public void errorMessageIfDependenciesNotInstalled() {
+ public void errorMessageIfDependenciesNotInstalled() throws InterpreterException {
InterpreterResult ret;
ret = sql.interpret("SELECT * from something", context);
@@ -128,7 +129,7 @@ public class PythonInterpreterPandasSqlTest implements InterpreterOutputListener
}
@Test
- public void sqlOverTestDataPrintsTable() throws IOException {
+ public void sqlOverTestDataPrintsTable() throws IOException, InterpreterException {
InterpreterResult ret;
// given
//String expectedTable = "name\tage\n\nmoon\t33\n\npark\t34";
@@ -152,7 +153,7 @@ public class PythonInterpreterPandasSqlTest implements InterpreterOutputListener
}
@Test
- public void badSqlSyntaxFails() throws IOException {
+ public void badSqlSyntaxFails() throws IOException, InterpreterException {
//when
InterpreterResult ret = sql.interpret("select wrong syntax", context);
@@ -162,7 +163,7 @@ public class PythonInterpreterPandasSqlTest implements InterpreterOutputListener
}
@Test
- public void showDataFrame() throws IOException {
+ public void showDataFrame() throws IOException, InterpreterException {
InterpreterResult ret;
ret = python.interpret("import pandas as pd", context);
ret = python.interpret("import numpy as np", context);
diff --git a/python/src/test/java/org/apache/zeppelin/python/PythonInterpreterTest.java b/python/src/test/java/org/apache/zeppelin/python/PythonInterpreterTest.java
index 195935d213..ef328f0bef 100644
--- a/python/src/test/java/org/apache/zeppelin/python/PythonInterpreterTest.java
+++ b/python/src/test/java/org/apache/zeppelin/python/PythonInterpreterTest.java
@@ -38,6 +38,7 @@ import org.apache.zeppelin.display.GUI;
import org.apache.zeppelin.interpreter.Interpreter;
import org.apache.zeppelin.interpreter.InterpreterContext;
import org.apache.zeppelin.interpreter.InterpreterContextRunner;
+import org.apache.zeppelin.interpreter.InterpreterException;
import org.apache.zeppelin.interpreter.InterpreterGroup;
import org.apache.zeppelin.interpreter.InterpreterOutput;
import org.apache.zeppelin.interpreter.InterpreterOutputListener;
@@ -64,7 +65,7 @@ public class PythonInterpreterTest implements InterpreterOutputListener {
}
@Before
- public void beforeTest() throws IOException {
+ public void beforeTest() throws IOException, InterpreterException {
cmdHistory = "";
// python interpreter
@@ -96,20 +97,20 @@ public class PythonInterpreterTest implements InterpreterOutputListener {
}
@Test
- public void testInterpret() throws InterruptedException, IOException {
+ public void testInterpret() throws InterruptedException, IOException, InterpreterException {
InterpreterResult result = pythonInterpreter.interpret("print (\"hi\")", context);
assertEquals(InterpreterResult.Code.SUCCESS, result.code());
}
@Test
- public void testInterpretInvalidSyntax() throws IOException {
+ public void testInterpretInvalidSyntax() throws IOException, InterpreterException {
InterpreterResult result = pythonInterpreter.interpret("for x in range(0,3): print (\"hi\")\n", context);
assertEquals(InterpreterResult.Code.SUCCESS, result.code());
assertTrue(new String(out.getOutputAt(0).toByteArray()).contains("hi\nhi\nhi"));
}
@Test
- public void testRedefinitionZeppelinContext() {
+ public void testRedefinitionZeppelinContext() throws InterpreterException {
String pyRedefinitionCode = "z = 1\n";
String pyRestoreCode = "z = __zeppelin__\n";
String pyValidCode = "z.input(\"test\")\n";
diff --git a/scalding/pom.xml b/scalding/pom.xml
index cc1015f21b..763afe0bb4 100644
--- a/scalding/pom.xml
+++ b/scalding/pom.xml
@@ -20,10 +20,10 @@
4.0.0
- zeppelin
+ interpreter-parent
org.apache.zeppelin
0.8.0-SNAPSHOT
- ..
+ ../interpreter-parent
org.apache.zeppelin
@@ -33,6 +33,7 @@
Zeppelin: Scalding interpreter
+ scalding
2.6.0
0.16.1-RC1
@@ -147,55 +148,14 @@
maven-enforcer-plugin
-
-
- enforce
- none
-
-
-
maven-dependency-plugin
-
-
- copy-dependencies
- package
-
- copy-dependencies
-
-
- ${project.build.directory}/../../interpreter/scalding
- false
- false
- true
- runtime
-
-
-
- copy-artifact
- package
-
- copy
-
-
- ${project.build.directory}/../../interpreter/scalding
- false
- false
- true
- runtime
-
-
- ${project.groupId}
- ${project.artifactId}
- ${project.version}
- ${project.packaging}
-
-
-
-
-
+
+ maven-resources-plugin
+
+
org.scala-tools
diff --git a/scalding/src/main/java/org/apache/zeppelin/scalding/ScaldingInterpreter.java b/scalding/src/main/java/org/apache/zeppelin/scalding/ScaldingInterpreter.java
index 7156c37e97..d3ebadaf05 100644
--- a/scalding/src/main/java/org/apache/zeppelin/scalding/ScaldingInterpreter.java
+++ b/scalding/src/main/java/org/apache/zeppelin/scalding/ScaldingInterpreter.java
@@ -69,7 +69,7 @@ public class ScaldingInterpreter extends Interpreter {
@Override
public void open() {
numOpenInstances = numOpenInstances + 1;
- String maxOpenInstancesStr = property.getProperty(MAX_OPEN_INSTANCES,
+ String maxOpenInstancesStr = getProperty(MAX_OPEN_INSTANCES,
MAX_OPEN_INSTANCES_DEFAULT);
int maxOpenInstances = 50;
try {
@@ -83,8 +83,8 @@ public class ScaldingInterpreter extends Interpreter {
return;
}
logger.info("Opening instance {}", numOpenInstances);
- logger.info("property: {}", property);
- String argsString = property.getProperty(ARGS_STRING, ARGS_STRING_DEFAULT);
+ logger.info("property: {}", getProperties());
+ String argsString = getProperty(ARGS_STRING, ARGS_STRING_DEFAULT);
String[] args;
if (argsString == null) {
args = new String[0];
@@ -121,7 +121,7 @@ public class ScaldingInterpreter extends Interpreter {
return new InterpreterResult(Code.SUCCESS);
}
InterpreterResult interpreterResult = new InterpreterResult(Code.ERROR);
- if (property.getProperty(ARGS_STRING).contains("hdfs")) {
+ if (getProperty(ARGS_STRING).contains("hdfs")) {
UserGroupInformation ugi = null;
try {
ugi = UserGroupInformation.createProxyUser(user, UserGroupInformation.getLoginUser());
diff --git a/scio/pom.xml b/scio/pom.xml
index 3d17dc88ef..27ccb0cc7b 100644
--- a/scio/pom.xml
+++ b/scio/pom.xml
@@ -20,10 +20,10 @@
4.0.0
- zeppelin
+ interpreter-parent
org.apache.zeppelin
0.8.0-SNAPSHOT
- ..
+ ../interpreter-parent
org.apache.zeppelin
@@ -34,6 +34,7 @@
Zeppelin Scio support
+ scio
0.2.4
14.0.1
@@ -106,12 +107,12 @@
maven-enforcer-plugin
-
-
- enforce
- none
-
-
+
+
+ maven-dependency-plugin
+
+
+ maven-resources-plugin
@@ -156,34 +157,6 @@
-
- org.apache.maven.plugins
- maven-dependency-plugin
-
-
- package
-
- copy
-
-
- ${project.build.directory}/../../interpreter/scio
- false
- false
- true
- runtime
-
-
- ${project.groupId}
- ${project.artifactId}
- ${project.version}
- ${project.packaging}
-
-
-
-
-
-
-
org.scala-tools
maven-scala-plugin
diff --git a/shell/pom.xml b/shell/pom.xml
index 58d890084f..0157d86f53 100644
--- a/shell/pom.xml
+++ b/shell/pom.xml
@@ -20,10 +20,10 @@
4.0.0
- zeppelin
+ interpreter-parent
org.apache.zeppelin
0.8.0-SNAPSHOT
- ..
+ ../interpreter-parent
org.apache.zeppelin
@@ -33,17 +33,18 @@
Zeppelin: Shell interpreter
+ sh
+
3.4
1.3
+ sh
${project.groupId}
zeppelin-interpreter
- ${project.version}
- provided
@@ -79,54 +80,12 @@
maven-enforcer-plugin
-
-
- enforce
- none
-
-
-
maven-dependency-plugin
-
-
- copy-dependencies
- package
-
- copy-dependencies
-
-
- ${project.build.directory}/../../interpreter/sh
- false
- false
- true
- runtime
-
-
-
- copy-artifact
- package
-
- copy
-
-
- ${project.build.directory}/../../interpreter/sh
- false
- false
- true
- runtime
-
-
- ${project.groupId}
- ${project.artifactId}
- ${project.version}
- ${project.packaging}
-
-
-
-
-
+
+
+ maven-resources-plugin
diff --git a/shell/src/main/java/org/apache/zeppelin/shell/ShellInterpreter.java b/shell/src/main/java/org/apache/zeppelin/shell/ShellInterpreter.java
index dbae6c9bf6..b7c0043dd1 100644
--- a/shell/src/main/java/org/apache/zeppelin/shell/ShellInterpreter.java
+++ b/shell/src/main/java/org/apache/zeppelin/shell/ShellInterpreter.java
@@ -174,8 +174,8 @@ public class ShellInterpreter extends KerberosInterpreter {
return false;
}
- public void createSecureConfiguration() {
- Properties properties = getProperty();
+ public void createSecureConfiguration() throws InterpreterException {
+ Properties properties = getProperties();
CommandLine cmdLine = CommandLine.parse(shell);
cmdLine.addArgument("-c", false);
String kinitCommand = String.format("kinit -k -t %s %s",
diff --git a/spark/src/main/java/org/apache/zeppelin/spark/IPySparkInterpreter.java b/spark/src/main/java/org/apache/zeppelin/spark/IPySparkInterpreter.java
index 56b3823b59..a0505692d5 100644
--- a/spark/src/main/java/org/apache/zeppelin/spark/IPySparkInterpreter.java
+++ b/spark/src/main/java/org/apache/zeppelin/spark/IPySparkInterpreter.java
@@ -21,12 +21,15 @@ import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.zeppelin.interpreter.Interpreter;
import org.apache.zeppelin.interpreter.InterpreterContext;
+import org.apache.zeppelin.interpreter.InterpreterException;
import org.apache.zeppelin.interpreter.LazyOpenInterpreter;
import org.apache.zeppelin.interpreter.WrappedInterpreter;
import org.apache.zeppelin.python.IPythonInterpreter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.io.IOException;
+import java.util.Map;
import java.util.Properties;
/**
@@ -43,8 +46,9 @@ public class IPySparkInterpreter extends IPythonInterpreter {
}
@Override
- public void open() {
- property.setProperty("zeppelin.python", PySparkInterpreter.getPythonExec(property));
+ public void open() throws InterpreterException {
+ setProperty("zeppelin.python",
+ PySparkInterpreter.getPythonExec(getProperties()));
sparkInterpreter = getSparkInterpreter();
SparkConf conf = sparkInterpreter.getSparkContext().getConf();
// only set PYTHONPATH in local or yarn-client mode.
@@ -57,7 +61,18 @@ public class IPySparkInterpreter extends IPythonInterpreter {
super.open();
}
- private SparkInterpreter getSparkInterpreter() {
+ @Override
+ protected Map setupIPythonEnv() throws IOException {
+ Map env = super.setupIPythonEnv();
+ // set PYSPARK_PYTHON
+ SparkConf conf = sparkInterpreter.getSparkContext().getConf();
+ if (conf.contains("spark.pyspark.python")) {
+ env.put("PYSPARK_PYTHON", conf.get("spark.pyspark.python"));
+ }
+ return env;
+ }
+
+ private SparkInterpreter getSparkInterpreter() throws InterpreterException {
LazyOpenInterpreter lazy = null;
SparkInterpreter spark = null;
Interpreter p = getInterpreterInTheSameSessionByClassName(SparkInterpreter.class.getName());
diff --git a/spark/src/main/java/org/apache/zeppelin/spark/PySparkInterpreter.java b/spark/src/main/java/org/apache/zeppelin/spark/PySparkInterpreter.java
index dd32059a2c..5df4ec6b01 100644
--- a/spark/src/main/java/org/apache/zeppelin/spark/PySparkInterpreter.java
+++ b/spark/src/main/java/org/apache/zeppelin/spark/PySparkInterpreter.java
@@ -86,11 +86,11 @@ public class PySparkInterpreter extends Interpreter implements ExecuteResultHand
File scriptFile = File.createTempFile("zeppelin_pyspark-", ".py");
scriptPath = scriptFile.getAbsolutePath();
} catch (IOException e) {
- throw new InterpreterException(e);
+ throw new RuntimeException(e);
}
}
- private void createPythonScript() {
+ private void createPythonScript() throws InterpreterException {
ClassLoader classLoader = getClass().getClassLoader();
File out = new File(scriptPath);
@@ -112,10 +112,10 @@ public class PySparkInterpreter extends Interpreter implements ExecuteResultHand
}
@Override
- public void open() {
+ public void open() throws InterpreterException {
// try IPySparkInterpreter first
iPySparkInterpreter = getIPySparkInterpreter();
- if (property.getProperty("zeppelin.pyspark.useIPython", "true").equals("true") &&
+ if (getProperty("zeppelin.pyspark.useIPython", "true").equals("true") &&
iPySparkInterpreter.checkIPythonPrerequisite()) {
try {
iPySparkInterpreter.open();
@@ -132,8 +132,7 @@ public class PySparkInterpreter extends Interpreter implements ExecuteResultHand
}
}
iPySparkInterpreter = null;
-
- if (property.getProperty("zeppelin.pyspark.useIPython", "true").equals("true")) {
+ if (getProperty("zeppelin.pyspark.useIPython", "true").equals("true")) {
// don't print it when it is in testing, just for easy output check in test.
try {
InterpreterContext.get().out.write(("IPython is not available, " +
@@ -202,7 +201,7 @@ public class PySparkInterpreter extends Interpreter implements ExecuteResultHand
}
}
- private Map setupPySparkEnv() throws IOException {
+ private Map setupPySparkEnv() throws IOException, InterpreterException {
Map env = EnvironmentUtils.getProcEnvironment();
// only set PYTHONPATH in local or yarn-client mode.
@@ -229,6 +228,11 @@ public class PySparkInterpreter extends Interpreter implements ExecuteResultHand
}
LOGGER.info("PYTHONPATH: " + env.get("PYTHONPATH"));
+
+ // set PYSPARK_PYTHON
+ if (getSparkConf().contains("spark.pyspark.python")) {
+ env.put("PYSPARK_PYTHON", getSparkConf().get("spark.pyspark.python"));
+ }
return env;
}
@@ -246,7 +250,7 @@ public class PySparkInterpreter extends Interpreter implements ExecuteResultHand
return pythonExec;
}
- private void createGatewayServerAndStartScript() {
+ private void createGatewayServerAndStartScript() throws InterpreterException {
// create python script
createPythonScript();
@@ -255,7 +259,7 @@ public class PySparkInterpreter extends Interpreter implements ExecuteResultHand
gatewayServer = new GatewayServer(this, port);
gatewayServer.start();
- String pythonExec = getPythonExec(property);
+ String pythonExec = getPythonExec(getProperties());
LOGGER.info("pythonExec: " + pythonExec);
CommandLine cmd = CommandLine.parse(pythonExec);
cmd.addArgument(scriptPath, false);
@@ -295,7 +299,7 @@ public class PySparkInterpreter extends Interpreter implements ExecuteResultHand
}
}
- private int findRandomOpenPortOnAllLocalInterfaces() {
+ private int findRandomOpenPortOnAllLocalInterfaces() throws InterpreterException {
int port;
try (ServerSocket socket = new ServerSocket(0);) {
port = socket.getLocalPort();
@@ -394,7 +398,8 @@ public class PySparkInterpreter extends Interpreter implements ExecuteResultHand
}
@Override
- public InterpreterResult interpret(String st, InterpreterContext context) {
+ public InterpreterResult interpret(String st, InterpreterContext context)
+ throws InterpreterException {
SparkInterpreter sparkInterpreter = getSparkInterpreter();
sparkInterpreter.populateSparkWebUrl(context);
if (sparkInterpreter.isUnsupportedSparkVersion()) {
@@ -500,7 +505,7 @@ public class PySparkInterpreter extends Interpreter implements ExecuteResultHand
}
@Override
- public void cancel(InterpreterContext context) {
+ public void cancel(InterpreterContext context) throws InterpreterException {
if (iPySparkInterpreter != null) {
iPySparkInterpreter.cancel(context);
return;
@@ -520,7 +525,7 @@ public class PySparkInterpreter extends Interpreter implements ExecuteResultHand
}
@Override
- public int getProgress(InterpreterContext context) {
+ public int getProgress(InterpreterContext context) throws InterpreterException {
if (iPySparkInterpreter != null) {
return iPySparkInterpreter.getProgress(context);
}
@@ -531,7 +536,7 @@ public class PySparkInterpreter extends Interpreter implements ExecuteResultHand
@Override
public List completion(String buf, int cursor,
- InterpreterContext interpreterContext) {
+ InterpreterContext interpreterContext) throws InterpreterException {
if (iPySparkInterpreter != null) {
return iPySparkInterpreter.completion(buf, cursor, interpreterContext);
}
@@ -632,7 +637,7 @@ public class PySparkInterpreter extends Interpreter implements ExecuteResultHand
}
- private SparkInterpreter getSparkInterpreter() {
+ private SparkInterpreter getSparkInterpreter() throws InterpreterException {
LazyOpenInterpreter lazy = null;
SparkInterpreter spark = null;
Interpreter p = getInterpreterInTheSameSessionByClassName(SparkInterpreter.class.getName());
@@ -666,7 +671,7 @@ public class PySparkInterpreter extends Interpreter implements ExecuteResultHand
return iPySpark;
}
- public SparkZeppelinContext getZeppelinContext() {
+ public SparkZeppelinContext getZeppelinContext() throws InterpreterException {
SparkInterpreter sparkIntp = getSparkInterpreter();
if (sparkIntp != null) {
return getSparkInterpreter().getZeppelinContext();
@@ -675,7 +680,7 @@ public class PySparkInterpreter extends Interpreter implements ExecuteResultHand
}
}
- public JavaSparkContext getJavaSparkContext() {
+ public JavaSparkContext getJavaSparkContext() throws InterpreterException {
SparkInterpreter intp = getSparkInterpreter();
if (intp == null) {
return null;
@@ -684,7 +689,7 @@ public class PySparkInterpreter extends Interpreter implements ExecuteResultHand
}
}
- public Object getSparkSession() {
+ public Object getSparkSession() throws InterpreterException {
SparkInterpreter intp = getSparkInterpreter();
if (intp == null) {
return null;
@@ -693,7 +698,7 @@ public class PySparkInterpreter extends Interpreter implements ExecuteResultHand
}
}
- public SparkConf getSparkConf() {
+ public SparkConf getSparkConf() throws InterpreterException {
JavaSparkContext sc = getJavaSparkContext();
if (sc == null) {
return null;
@@ -702,7 +707,7 @@ public class PySparkInterpreter extends Interpreter implements ExecuteResultHand
}
}
- public SQLContext getSQLContext() {
+ public SQLContext getSQLContext() throws InterpreterException {
SparkInterpreter intp = getSparkInterpreter();
if (intp == null) {
return null;
diff --git a/spark/src/main/java/org/apache/zeppelin/spark/SparkInterpreter.java b/spark/src/main/java/org/apache/zeppelin/spark/SparkInterpreter.java
index 18da0344f0..5a5110f9fe 100644
--- a/spark/src/main/java/org/apache/zeppelin/spark/SparkInterpreter.java
+++ b/spark/src/main/java/org/apache/zeppelin/spark/SparkInterpreter.java
@@ -353,7 +353,7 @@ public class SparkInterpreter extends Interpreter {
public boolean isYarnMode() {
String master = getProperty("master");
if (master == null) {
- master = getProperty().getProperty("spark.master", "local[*]");
+ master = getProperty("spark.master", "local[*]");
}
return master.startsWith("yarn");
}
@@ -376,7 +376,7 @@ public class SparkInterpreter extends Interpreter {
}
conf.set("spark.scheduler.mode", "FAIR");
- Properties intpProperty = getProperty();
+ Properties intpProperty = getProperties();
for (Object k : intpProperty.keySet()) {
String key = (String) k;
String val = toString(intpProperty.get(key));
@@ -509,7 +509,7 @@ public class SparkInterpreter extends Interpreter {
}
conf.set("spark.scheduler.mode", "FAIR");
- Properties intpProperty = getProperty();
+ Properties intpProperty = getProperties();
for (Object k : intpProperty.keySet()) {
String key = (String) k;
String val = toString(intpProperty.get(key));
@@ -543,19 +543,19 @@ public class SparkInterpreter extends Interpreter {
}
@Override
- public void open() {
+ public void open() throws InterpreterException {
this.enableSupportedVersionCheck = java.lang.Boolean.parseBoolean(
- property.getProperty("zeppelin.spark.enableSupportedVersionCheck", "true"));
+ getProperty("zeppelin.spark.enableSupportedVersionCheck", "true"));
// set properties and do login before creating any spark stuff for secured cluster
if (isYarnMode()) {
System.setProperty("SPARK_YARN_MODE", "true");
}
- if (getProperty().containsKey("spark.yarn.keytab") &&
- getProperty().containsKey("spark.yarn.principal")) {
+ if (getProperties().containsKey("spark.yarn.keytab") &&
+ getProperties().containsKey("spark.yarn.principal")) {
try {
- String keytab = getProperty().getProperty("spark.yarn.keytab");
- String principal = getProperty().getProperty("spark.yarn.principal");
+ String keytab = getProperties().getProperty("spark.yarn.keytab");
+ String principal = getProperties().getProperty("spark.yarn.principal");
UserGroupInformation.loginUserFromKeytab(principal, keytab);
} catch (IOException e) {
throw new RuntimeException("Can not pass kerberos authentication", e);
@@ -963,7 +963,7 @@ public class SparkInterpreter extends Interpreter {
sparkUrl = getSparkUIUrl();
Map infos = new java.util.HashMap<>();
infos.put("url", sparkUrl);
- String uiEnabledProp = property.getProperty("spark.ui.enabled", "true");
+ String uiEnabledProp = getProperty("spark.ui.enabled", "true");
java.lang.Boolean uiEnabled = java.lang.Boolean.parseBoolean(
uiEnabledProp.trim());
if (!uiEnabled) {
diff --git a/spark/src/main/java/org/apache/zeppelin/spark/SparkRInterpreter.java b/spark/src/main/java/org/apache/zeppelin/spark/SparkRInterpreter.java
index ca52f790f6..1bdd4dc07b 100644
--- a/spark/src/main/java/org/apache/zeppelin/spark/SparkRInterpreter.java
+++ b/spark/src/main/java/org/apache/zeppelin/spark/SparkRInterpreter.java
@@ -54,7 +54,7 @@ public class SparkRInterpreter extends Interpreter {
}
@Override
- public void open() {
+ public void open() throws InterpreterException {
String rCmdPath = getProperty("zeppelin.R.cmd");
String sparkRLibPath;
@@ -105,7 +105,8 @@ public class SparkRInterpreter extends Interpreter {
}
@Override
- public InterpreterResult interpret(String lines, InterpreterContext interpreterContext) {
+ public InterpreterResult interpret(String lines, InterpreterContext interpreterContext)
+ throws InterpreterException {
SparkInterpreter sparkInterpreter = getSparkInterpreter();
sparkInterpreter.populateSparkWebUrl(interpreterContext);
@@ -220,7 +221,7 @@ public class SparkRInterpreter extends Interpreter {
return new ArrayList<>();
}
- private SparkInterpreter getSparkInterpreter() {
+ private SparkInterpreter getSparkInterpreter() throws InterpreterException {
LazyOpenInterpreter lazy = null;
SparkInterpreter spark = null;
Interpreter p = getInterpreterInTheSameSessionByClassName(SparkInterpreter.class.getName());
diff --git a/spark/src/main/java/org/apache/zeppelin/spark/SparkSqlInterpreter.java b/spark/src/main/java/org/apache/zeppelin/spark/SparkSqlInterpreter.java
index 134a65f39c..9709f9eea9 100644
--- a/spark/src/main/java/org/apache/zeppelin/spark/SparkSqlInterpreter.java
+++ b/spark/src/main/java/org/apache/zeppelin/spark/SparkSqlInterpreter.java
@@ -59,7 +59,7 @@ public class SparkSqlInterpreter extends Interpreter {
this.maxResult = Integer.parseInt(getProperty(MAX_RESULTS));
}
- private SparkInterpreter getSparkInterpreter() {
+ private SparkInterpreter getSparkInterpreter() throws InterpreterException {
LazyOpenInterpreter lazy = null;
SparkInterpreter spark = null;
Interpreter p = getInterpreterInTheSameSessionByClassName(SparkInterpreter.class.getName());
@@ -86,7 +86,8 @@ public class SparkSqlInterpreter extends Interpreter {
public void close() {}
@Override
- public InterpreterResult interpret(String st, InterpreterContext context) {
+ public InterpreterResult interpret(String st, InterpreterContext context)
+ throws InterpreterException {
SQLContext sqlc = null;
SparkInterpreter sparkInterpreter = getSparkInterpreter();
@@ -134,7 +135,7 @@ public class SparkSqlInterpreter extends Interpreter {
}
@Override
- public void cancel(InterpreterContext context) {
+ public void cancel(InterpreterContext context) throws InterpreterException {
SparkInterpreter sparkInterpreter = getSparkInterpreter();
SQLContext sqlc = sparkInterpreter.getSQLContext();
SparkContext sc = sqlc.sparkContext();
@@ -149,7 +150,7 @@ public class SparkSqlInterpreter extends Interpreter {
@Override
- public int getProgress(InterpreterContext context) {
+ public int getProgress(InterpreterContext context) throws InterpreterException {
SparkInterpreter sparkInterpreter = getSparkInterpreter();
return sparkInterpreter.getProgress(context);
}
diff --git a/spark/src/main/java/org/apache/zeppelin/spark/SparkZeppelinContext.java b/spark/src/main/java/org/apache/zeppelin/spark/SparkZeppelinContext.java
index 413c690711..09b8d440cc 100644
--- a/spark/src/main/java/org/apache/zeppelin/spark/SparkZeppelinContext.java
+++ b/spark/src/main/java/org/apache/zeppelin/spark/SparkZeppelinContext.java
@@ -79,7 +79,7 @@ public class SparkZeppelinContext extends BaseZeppelinContext {
}
if (supportedClasses.isEmpty()) {
- throw new InterpreterException("Can not load Dataset/DataFrame/SchemaRDD class");
+ throw new RuntimeException("Can not load Dataset/DataFrame/SchemaRDD class");
}
}
@@ -112,7 +112,7 @@ public class SparkZeppelinContext extends BaseZeppelinContext {
} catch (NoSuchMethodException | SecurityException | IllegalAccessException
| IllegalArgumentException | InvocationTargetException | ClassCastException e) {
sc.clearJobGroup();
- throw new InterpreterException(e);
+ throw new RuntimeException(e);
}
List columns = null;
@@ -129,7 +129,7 @@ public class SparkZeppelinContext extends BaseZeppelinContext {
.asJava();
} catch (NoSuchMethodException | SecurityException | IllegalAccessException
| IllegalArgumentException | InvocationTargetException e) {
- throw new InterpreterException(e);
+ throw new RuntimeException(e);
}
StringBuilder msg = new StringBuilder();
@@ -165,7 +165,7 @@ public class SparkZeppelinContext extends BaseZeppelinContext {
}
} catch (NoSuchMethodException | SecurityException | IllegalAccessException
| IllegalArgumentException | InvocationTargetException e) {
- throw new InterpreterException(e);
+ throw new RuntimeException(e);
}
if (rows.length > maxResult) {
diff --git a/spark/src/main/java/org/apache/zeppelin/spark/ZeppelinR.java b/spark/src/main/java/org/apache/zeppelin/spark/ZeppelinR.java
index b46001aa0e..130d849975 100644
--- a/spark/src/main/java/org/apache/zeppelin/spark/ZeppelinR.java
+++ b/spark/src/main/java/org/apache/zeppelin/spark/ZeppelinR.java
@@ -117,7 +117,7 @@ public class ZeppelinR implements ExecuteResultHandler {
File scriptFile = File.createTempFile("zeppelin_sparkr-", ".R");
scriptPath = scriptFile.getAbsolutePath();
} catch (IOException e) {
- throw new InterpreterException(e);
+ throw new RuntimeException(e);
}
}
@@ -125,7 +125,7 @@ public class ZeppelinR implements ExecuteResultHandler {
* Start R repl
* @throws IOException
*/
- public void open() throws IOException {
+ public void open() throws IOException, InterpreterException {
createRScript();
zeppelinR.put(hashCode(), this);
@@ -170,7 +170,7 @@ public class ZeppelinR implements ExecuteResultHandler {
* @param expr
* @return
*/
- public Object eval(String expr) {
+ public Object eval(String expr) throws InterpreterException {
synchronized (this) {
rRequestObject = new Request("eval", expr, null);
return request();
@@ -182,7 +182,7 @@ public class ZeppelinR implements ExecuteResultHandler {
* @param key
* @param value
*/
- public void set(String key, Object value) {
+ public void set(String key, Object value) throws InterpreterException {
synchronized (this) {
rRequestObject = new Request("set", key, value);
request();
@@ -194,7 +194,7 @@ public class ZeppelinR implements ExecuteResultHandler {
* @param key
* @return
*/
- public Object get(String key) {
+ public Object get(String key) throws InterpreterException {
synchronized (this) {
rRequestObject = new Request("get", key, null);
return request();
@@ -206,7 +206,7 @@ public class ZeppelinR implements ExecuteResultHandler {
* @param key
* @return
*/
- public String getS0(String key) {
+ public String getS0(String key) throws InterpreterException {
synchronized (this) {
rRequestObject = new Request("getS", key, null);
return (String) request();
@@ -217,7 +217,7 @@ public class ZeppelinR implements ExecuteResultHandler {
* Send request to r repl and return response
* @return responseValue
*/
- private Object request() throws RuntimeException {
+ private Object request() throws RuntimeException, InterpreterException {
if (!rScriptRunning) {
throw new RuntimeException("r repl is not running");
}
@@ -332,7 +332,7 @@ public class ZeppelinR implements ExecuteResultHandler {
/**
* Create R script in tmp dir
*/
- private void createRScript() {
+ private void createRScript() throws InterpreterException {
ClassLoader classLoader = getClass().getClassLoader();
File out = new File(scriptPath);
diff --git a/spark/src/test/java/org/apache/zeppelin/spark/IPySparkInterpreterTest.java b/spark/src/test/java/org/apache/zeppelin/spark/IPySparkInterpreterTest.java
index 3f7cf752d4..faf0473092 100644
--- a/spark/src/test/java/org/apache/zeppelin/spark/IPySparkInterpreterTest.java
+++ b/spark/src/test/java/org/apache/zeppelin/spark/IPySparkInterpreterTest.java
@@ -24,6 +24,7 @@ import org.apache.zeppelin.display.GUI;
import org.apache.zeppelin.interpreter.Interpreter;
import org.apache.zeppelin.interpreter.InterpreterContext;
import org.apache.zeppelin.interpreter.InterpreterContextRunner;
+import org.apache.zeppelin.interpreter.InterpreterException;
import org.apache.zeppelin.interpreter.InterpreterGroup;
import org.apache.zeppelin.interpreter.InterpreterOutput;
import org.apache.zeppelin.interpreter.InterpreterOutputListener;
@@ -55,7 +56,7 @@ public class IPySparkInterpreterTest {
private InterpreterGroup intpGroup;
@Before
- public void setup() {
+ public void setup() throws InterpreterException {
Properties p = new Properties();
p.setProperty("spark.master", "local[4]");
p.setProperty("master", "local[4]");
@@ -90,7 +91,7 @@ public class IPySparkInterpreterTest {
}
@Test
- public void testBasics() throws InterruptedException, IOException {
+ public void testBasics() throws InterruptedException, IOException, InterpreterException {
// all the ipython test should pass too.
IPythonInterpreterTest.testInterpreter(iPySparkInterpreter);
diff --git a/spark/src/test/java/org/apache/zeppelin/spark/PySparkInterpreterMatplotlibTest.java b/spark/src/test/java/org/apache/zeppelin/spark/PySparkInterpreterMatplotlibTest.java
index d6950372f0..692447e698 100644
--- a/spark/src/test/java/org/apache/zeppelin/spark/PySparkInterpreterMatplotlibTest.java
+++ b/spark/src/test/java/org/apache/zeppelin/spark/PySparkInterpreterMatplotlibTest.java
@@ -64,7 +64,7 @@ public class PySparkInterpreterMatplotlibTest {
* normally handles this in real use cases.
*/
@Override
- public InterpreterResult interpret(String st, InterpreterContext context) {
+ public InterpreterResult interpret(String st, InterpreterContext context) throws InterpreterException {
context.out.clear();
InterpreterResult result = super.interpret(st, context);
List resultMessages = null;
@@ -140,7 +140,7 @@ public class PySparkInterpreterMatplotlibTest {
}
@Test
- public void dependenciesAreInstalled() {
+ public void dependenciesAreInstalled() throws InterpreterException {
// matplotlib
InterpreterResult ret = pyspark.interpret("import matplotlib", context);
assertEquals(ret.message().toString(), InterpreterResult.Code.SUCCESS, ret.code());
@@ -151,7 +151,7 @@ public class PySparkInterpreterMatplotlibTest {
}
@Test
- public void showPlot() {
+ public void showPlot() throws InterpreterException {
// Simple plot test
InterpreterResult ret;
ret = pyspark.interpret("import matplotlib.pyplot as plt", context);
@@ -168,7 +168,7 @@ public class PySparkInterpreterMatplotlibTest {
@Test
// Test for when configuration is set to auto-close figures after show().
- public void testClose() {
+ public void testClose() throws InterpreterException {
InterpreterResult ret;
InterpreterResult ret1;
InterpreterResult ret2;
@@ -195,7 +195,7 @@ public class PySparkInterpreterMatplotlibTest {
@Test
// Test for when configuration is set to not auto-close figures after show().
- public void testNoClose() {
+ public void testNoClose() throws InterpreterException {
InterpreterResult ret;
InterpreterResult ret1;
InterpreterResult ret2;
@@ -222,7 +222,7 @@ public class PySparkInterpreterMatplotlibTest {
@Test
// Test angular mode
- public void testAngular() {
+ public void testAngular() throws InterpreterException {
InterpreterResult ret;
ret = pyspark.interpret("import matplotlib.pyplot as plt", context);
ret = pyspark.interpret("plt.close()", context);
diff --git a/spark/src/test/java/org/apache/zeppelin/spark/PySparkInterpreterTest.java b/spark/src/test/java/org/apache/zeppelin/spark/PySparkInterpreterTest.java
index 7a4abd61d8..a95c5efb07 100644
--- a/spark/src/test/java/org/apache/zeppelin/spark/PySparkInterpreterTest.java
+++ b/spark/src/test/java/org/apache/zeppelin/spark/PySparkInterpreterTest.java
@@ -112,7 +112,7 @@ public class PySparkInterpreterTest {
}
@Test
- public void testBasicIntp() {
+ public void testBasicIntp() throws InterpreterException {
if (getSparkVersionNumber() > 11) {
assertEquals(InterpreterResult.Code.SUCCESS,
pySparkInterpreter.interpret("a = 1\n", context).code());
@@ -136,7 +136,7 @@ public class PySparkInterpreterTest {
}
@Test
- public void testCompletion() {
+ public void testCompletion() throws InterpreterException {
if (getSparkVersionNumber() > 11) {
List completions = pySparkInterpreter.completion("sc.", "sc.".length(), null);
assertTrue(completions.size() > 0);
@@ -144,7 +144,7 @@ public class PySparkInterpreterTest {
}
@Test
- public void testRedefinitionZeppelinContext() {
+ public void testRedefinitionZeppelinContext() throws InterpreterException {
if (getSparkVersionNumber() > 11) {
String redefinitionCode = "z = 1\n";
String restoreCode = "z = __zeppelin__\n";
@@ -162,7 +162,12 @@ public class PySparkInterpreterTest {
@Override
public void run() {
String code = "import time\nwhile True:\n time.sleep(1)" ;
- InterpreterResult ret = pySparkInterpreter.interpret(code, context);
+ InterpreterResult ret = null;
+ try {
+ ret = pySparkInterpreter.interpret(code, context);
+ } catch (InterpreterException e) {
+ e.printStackTrace();
+ }
assertNotNull(ret);
Pattern expectedMessage = Pattern.compile("KeyboardInterrupt");
Matcher m = expectedMessage.matcher(ret.message().toString());
@@ -171,7 +176,7 @@ public class PySparkInterpreterTest {
}
@Test
- public void testCancelIntp() throws InterruptedException {
+ public void testCancelIntp() throws InterruptedException, InterpreterException {
if (getSparkVersionNumber() > 11) {
assertEquals(InterpreterResult.Code.SUCCESS,
pySparkInterpreter.interpret("a = 1\n", context).code());
diff --git a/spark/src/test/java/org/apache/zeppelin/spark/SparkInterpreterTest.java b/spark/src/test/java/org/apache/zeppelin/spark/SparkInterpreterTest.java
index ece292b829..aaf13c321c 100644
--- a/spark/src/test/java/org/apache/zeppelin/spark/SparkInterpreterTest.java
+++ b/spark/src/test/java/org/apache/zeppelin/spark/SparkInterpreterTest.java
@@ -213,7 +213,7 @@ public class SparkInterpreterTest {
}
@Test
- public void testSparkSql() throws IOException {
+ public void testSparkSql() throws IOException, InterpreterException {
repl.interpret("case class Person(name:String, age:Int)\n", context);
repl.interpret("val people = sc.parallelize(Seq(Person(\"moon\", 33), Person(\"jobs\", 51), Person(\"gates\", 51), Person(\"park\", 34)))\n", context);
assertEquals(Code.SUCCESS, repl.interpret("people.take(3)", context).code());
@@ -243,7 +243,7 @@ public class SparkInterpreterTest {
@Test
public void emptyConfigurationVariablesOnlyForNonSparkProperties() {
- Properties intpProperty = repl.getProperty();
+ Properties intpProperty = repl.getProperties();
SparkConf sparkConf = repl.getSparkContext().getConf();
for (Object oKey : intpProperty.keySet()) {
String key = (String) oKey;
@@ -256,7 +256,7 @@ public class SparkInterpreterTest {
}
@Test
- public void shareSingleSparkContext() throws InterruptedException, IOException {
+ public void shareSingleSparkContext() throws InterruptedException, IOException, InterpreterException {
// create another SparkInterpreter
SparkInterpreter repl2 = new SparkInterpreter(getSparkTestProperties(tmpDir));
repl2.setInterpreterGroup(intpGroup);
@@ -272,7 +272,7 @@ public class SparkInterpreterTest {
}
@Test
- public void testEnableImplicitImport() throws IOException {
+ public void testEnableImplicitImport() throws IOException, InterpreterException {
if (getSparkVersionNumber(repl) >= 13) {
// Set option of importing implicits to "true", and initialize new Spark repl
Properties p = getSparkTestProperties(tmpDir);
@@ -289,7 +289,7 @@ public class SparkInterpreterTest {
}
@Test
- public void testDisableImplicitImport() throws IOException {
+ public void testDisableImplicitImport() throws IOException, InterpreterException {
if (getSparkVersionNumber(repl) >= 13) {
// Set option of importing implicits to "false", and initialize new Spark repl
// this test should return error status when creating DataFrame from sequence
diff --git a/spark/src/test/java/org/apache/zeppelin/spark/SparkSqlInterpreterTest.java b/spark/src/test/java/org/apache/zeppelin/spark/SparkSqlInterpreterTest.java
index ebb5e9a911..3e33f440b1 100644
--- a/spark/src/test/java/org/apache/zeppelin/spark/SparkSqlInterpreterTest.java
+++ b/spark/src/test/java/org/apache/zeppelin/spark/SparkSqlInterpreterTest.java
@@ -85,7 +85,7 @@ public class SparkSqlInterpreterTest {
}
@Test
- public void test() {
+ public void test() throws InterpreterException {
repl.interpret("case class Test(name:String, age:Int)", context);
repl.interpret("val test = sc.parallelize(Seq(Test(\"moon\", 33), Test(\"jobs\", 51), Test(\"gates\", 51), Test(\"park\", 34)))", context);
if (isDataFrameSupported()) {
@@ -107,7 +107,7 @@ public class SparkSqlInterpreterTest {
}
@Test
- public void testStruct() {
+ public void testStruct() throws InterpreterException {
repl.interpret("case class Person(name:String, age:Int)", context);
repl.interpret("case class People(group:String, person:Person)", context);
repl.interpret(
@@ -124,7 +124,7 @@ public class SparkSqlInterpreterTest {
}
@Test
- public void test_null_value_in_row() {
+ public void test_null_value_in_row() throws InterpreterException {
repl.interpret("import org.apache.spark.sql._", context);
if (isDataFrameSupported()) {
repl.interpret(
@@ -162,7 +162,7 @@ public class SparkSqlInterpreterTest {
}
@Test
- public void testMaxResults() {
+ public void testMaxResults() throws InterpreterException {
repl.interpret("case class P(age:Int)", context);
repl.interpret(
"val gr = sc.parallelize(Seq(P(1),P(2),P(3),P(4),P(5),P(6),P(7),P(8),P(9),P(10),P(11)))",
diff --git a/zeppelin-distribution/src/bin_license/LICENSE b/zeppelin-distribution/src/bin_license/LICENSE
index 3a6d0aac88..ab120f235f 100644
--- a/zeppelin-distribution/src/bin_license/LICENSE
+++ b/zeppelin-distribution/src/bin_license/LICENSE
@@ -217,6 +217,7 @@ The following components are provided under Apache License.
(Apache 2.0) frontend-maven-plugin 1.3 (com.github.eirslett:frontend-maven-plugin:1.3 - https://github.com/eirslett/frontend-maven-plugin/blob/frontend-plugins-1.3/LICENSE
(Apache 2.0) frontend-plugin-core 1.3 (com.github.eirslett:frontend-plugin-core) - https://github.com/eirslett/frontend-maven-plugin/blob/frontend-plugins-1.3/LICENSE
(Apache 2.0) mongo-java-driver 3.4.1 (org.mongodb:mongo-java-driver:3.4.1) - https://github.com/mongodb/mongo-java-driver/blob/master/LICENSE.txt
+ (Apache 2.0) Neo4j Java Driver (https://github.com/neo4j/neo4j-java-driver) - https://github.com/neo4j/neo4j-java-driver/blob/1.4.3/LICENSE.txt
========================================================================
MIT licenses
@@ -273,6 +274,7 @@ The text of each license is also included at licenses/LICENSE-[project]-[version
(The MIT License) headroom.js 0.9.3 (https://github.com/WickyNilliams/headroom.js) - https://github.com/WickyNilliams/headroom.js/blob/master/LICENSE
(The MIT License) angular-viewport-watch 0.135 (https://github.com/wix/angular-viewport-watch) - https://github.com/wix/angular-viewport-watch/blob/master/LICENSE
(The MIT License) ansi-up 2.0.2 (https://github.com/drudru/ansi_up) - https://github.com/drudru/ansi_up#license
+ (The MIT License) bcpkix-jdk15on 1.52 (org.bouncycastle:bcpkix-jdk15on:1.52 https://github.com/bcgit/bc-java) - https://github.com/bcgit/bc-java/blob/master/LICENSE.html
========================================================================
BSD-style licenses
diff --git a/zeppelin-interpreter/pom.xml b/zeppelin-interpreter/pom.xml
index 384b9d1c59..3bb50c732f 100644
--- a/zeppelin-interpreter/pom.xml
+++ b/zeppelin-interpreter/pom.xml
@@ -66,6 +66,11 @@
gson-extras
+
+ commons-configuration
+ commons-configuration
+
+
org.apache.commons
commons-exec
@@ -132,6 +137,12 @@
${aether.version}
+
+ org.bouncycastle
+ bcpkix-jdk15on
+ 1.52
+
+
org.apache.maven
maven-aether-provider
@@ -226,4 +237,79 @@
test
+
+
+
+
+
+
+ maven-enforcer-plugin
+
+
+ enforce
+ none
+
+
+
+
+
+ maven-dependency-plugin
+
+
+ copy-dependencies
+ package
+
+ copy-dependencies
+
+
+ ${basedir}/interpreter/${project.name}
+ false
+ false
+ true
+ runtime
+
+
+
+ copy-artifact
+ package
+
+ copy
+
+
+ ${basedir}/interpreter/${project.name}
+ false
+ false
+ true
+
+
+ ${project.groupId}
+ ${project.artifactId}
+ ${project.version}
+ ${project.packaging}
+
+
+
+
+
+
+
+
+ maven-resources-plugin
+
+
+ copy-resources
+ package
+
+ resources
+
+
+ ${basedir}/interpreter/{project.name}
+
+
+
+
+
+
+
+
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java
similarity index 98%
rename from zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java
rename to zeppelin-interpreter/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java
index 2dec19cbf5..3a82bc5898 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java
@@ -443,6 +443,10 @@ public class ZeppelinConfiguration extends XMLConfiguration {
return getBoolean(ConfVars.ZEPPELIN_CREDENTIALS_PERSIST);
}
+ public String getCredentialsEncryptKey() {
+ return getString(ConfVars.ZEPPELIN_CREDENTIALS_ENCRYPT_KEY);
+ }
+
public String getCredentialsPath() {
return getRelativeDir(String.format("%s/credentials.json", getConfDir()));
}
@@ -623,7 +627,8 @@ public class ZeppelinConfiguration extends XMLConfiguration {
+ "org.apache.zeppelin.bigquery.BigQueryInterpreter,"
+ "org.apache.zeppelin.beam.BeamInterpreter,"
+ "org.apache.zeppelin.scio.ScioInterpreter,"
- + "org.apache.zeppelin.groovy.GroovyInterpreter"
+ + "org.apache.zeppelin.groovy.GroovyInterpreter,"
+ + "org.apache.zeppelin.neo4j.Neo4jCypherInterpreter"
),
ZEPPELIN_INTERPRETER_JSON("zeppelin.interpreter.setting", "interpreter-setting.json"),
ZEPPELIN_INTERPRETER_DIR("zeppelin.interpreter.dir", "interpreter"),
@@ -634,7 +639,7 @@ public class ZeppelinConfiguration extends XMLConfiguration {
ZEPPELIN_INTERPRETER_MAX_POOL_SIZE("zeppelin.interpreter.max.poolsize", 10),
ZEPPELIN_INTERPRETER_GROUP_ORDER("zeppelin.interpreter.group.order", "spark,md,angular,sh,"
+ "livy,alluxio,file,psql,flink,python,ignite,lens,cassandra,geode,kylin,elasticsearch,"
- + "scalding,jdbc,hbase,bigquery,beam,pig,scio,groovy"),
+ + "scalding,jdbc,hbase,bigquery,beam,pig,scio,groovy,neo4j"),
ZEPPELIN_INTERPRETER_OUTPUT_LIMIT("zeppelin.interpreter.output.limit", 1024 * 100),
ZEPPELIN_ENCODING("zeppelin.encoding", "UTF-8"),
ZEPPELIN_NOTEBOOK_DIR("zeppelin.notebook.dir", "notebook"),
@@ -680,6 +685,7 @@ public class ZeppelinConfiguration extends XMLConfiguration {
ZEPPELIN_ALLOWED_ORIGINS("zeppelin.server.allowed.origins", "*"),
ZEPPELIN_ANONYMOUS_ALLOWED("zeppelin.anonymous.allowed", true),
ZEPPELIN_CREDENTIALS_PERSIST("zeppelin.credentials.persist", true),
+ ZEPPELIN_CREDENTIALS_ENCRYPT_KEY("zeppelin.credentials.encryptKey", null),
ZEPPELIN_WEBSOCKET_MAX_TEXT_MESSAGE_SIZE("zeppelin.websocket.max.text.message.size", "1024000"),
ZEPPELIN_SERVER_DEFAULT_DIR_ALLOWED("zeppelin.server.default.dir.allowed", false),
ZEPPELIN_SERVER_XFRAME_OPTIONS("zeppelin.server.xframe.options", "SAMEORIGIN"),
@@ -687,8 +693,8 @@ public class ZeppelinConfiguration extends XMLConfiguration {
ZEPPELIN_SERVER_STRICT_TRANSPORT("zeppelin.server.strict.transport", "max-age=631138519"),
ZEPPELIN_SERVER_X_XSS_PROTECTION("zeppelin.server.xxss.protection", "1"),
- ZEPPELIN_HDFS_KEYTAB("zeppelin.hdfs.keytab", ""),
- ZEPPELIN_HDFS_PRINCIPAL("zeppelin.hdfs.principal", ""),
+ ZEPPELIN_SERVER_KERBEROS_KEYTAB("zeppelin.server.kerberos.keytab", ""),
+ ZEPPELIN_SERVER_KERBEROS_PRINCIPAL("zeppelin.server.kerberos.principal", ""),
ZEPPELIN_INTERPRETER_CALLBACK_PORTRANGE("zeppelin.interpreter.callback.portRange", ":");
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/BaseZeppelinContext.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/BaseZeppelinContext.java
index 12376f0dd7..9503962259 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/BaseZeppelinContext.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/BaseZeppelinContext.java
@@ -168,7 +168,7 @@ public abstract class BaseZeppelinContext {
interpreterContext.out.write(o.toString());
}
} catch (IOException e) {
- throw new InterpreterException(e);
+ throw new RuntimeException(e);
}
}
@@ -229,14 +229,14 @@ public abstract class BaseZeppelinContext {
public void run(String noteId, String paragraphId, InterpreterContext context,
boolean checkCurrentParagraph) {
if (paragraphId.equals(context.getParagraphId()) && checkCurrentParagraph) {
- throw new InterpreterException("Can not run current Paragraph");
+ throw new RuntimeException("Can not run current Paragraph");
}
List runners =
getInterpreterContextRunner(noteId, paragraphId, context);
if (runners.size() <= 0) {
- throw new InterpreterException("Paragraph " + paragraphId + " not found " + runners.size());
+ throw new RuntimeException("Paragraph " + paragraphId + " not found " + runners.size());
}
for (InterpreterContextRunner r : runners) {
@@ -255,7 +255,7 @@ public abstract class BaseZeppelinContext {
List runners = getInterpreterContextRunner(noteId, context);
if (runners.size() <= 0) {
- throw new InterpreterException("Note " + noteId + " not found " + runners.size());
+ throw new RuntimeException("Note " + noteId + " not found " + runners.size());
}
for (InterpreterContextRunner r : runners) {
@@ -346,12 +346,12 @@ public abstract class BaseZeppelinContext {
boolean checkCurrentParagraph) {
List runners = getInterpreterContextRunner(noteId, context);
if (idx >= runners.size()) {
- throw new InterpreterException("Index out of bound");
+ throw new RuntimeException("Index out of bound");
}
InterpreterContextRunner runner = runners.get(idx);
if (runner.getParagraphId().equals(context.getParagraphId()) && checkCurrentParagraph) {
- throw new InterpreterException("Can not run current Paragraph: " + runner.getParagraphId());
+ throw new RuntimeException("Can not run current Paragraph: " + runner.getParagraphId());
}
runner.run();
@@ -377,7 +377,7 @@ public abstract class BaseZeppelinContext {
Integer idx = (Integer) idOrIdx;
run(noteId, idx, context);
} else {
- throw new InterpreterException("Paragraph " + idOrIdx + " not found");
+ throw new RuntimeException("Paragraph " + idOrIdx + " not found");
}
}
}
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/ClassloaderInterpreter.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/ClassloaderInterpreter.java
index a1dafd9721..f8afa45737 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/ClassloaderInterpreter.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/ClassloaderInterpreter.java
@@ -51,7 +51,8 @@ public class ClassloaderInterpreter
}
@Override
- public InterpreterResult interpret(String st, InterpreterContext context) {
+ public InterpreterResult interpret(String st, InterpreterContext context)
+ throws InterpreterException {
ClassLoader oldcl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(cl);
try {
@@ -68,7 +69,7 @@ public class ClassloaderInterpreter
@Override
- public void open() {
+ public void open() throws InterpreterException {
ClassLoader oldcl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(cl);
try {
@@ -82,7 +83,7 @@ public class ClassloaderInterpreter
}
@Override
- public void close() {
+ public void close() throws InterpreterException {
ClassLoader oldcl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(cl);
try {
@@ -96,7 +97,7 @@ public class ClassloaderInterpreter
}
@Override
- public void cancel(InterpreterContext context) {
+ public void cancel(InterpreterContext context) throws InterpreterException {
ClassLoader oldcl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(cl);
try {
@@ -110,13 +111,11 @@ public class ClassloaderInterpreter
}
@Override
- public FormType getFormType() {
+ public FormType getFormType() throws InterpreterException {
ClassLoader oldcl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(cl);
try {
return intp.getFormType();
- } catch (Exception e) {
- throw new InterpreterException(e);
} finally {
cl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(oldcl);
@@ -124,7 +123,7 @@ public class ClassloaderInterpreter
}
@Override
- public int getProgress(InterpreterContext context) {
+ public int getProgress(InterpreterContext context) throws InterpreterException {
ClassLoader oldcl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(cl);
try {
@@ -143,8 +142,6 @@ public class ClassloaderInterpreter
Thread.currentThread().setContextClassLoader(cl);
try {
return intp.getScheduler();
- } catch (Exception e) {
- throw new InterpreterException(e);
} finally {
cl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(oldcl);
@@ -153,14 +150,12 @@ public class ClassloaderInterpreter
@Override
public List completion(String buf, int cursor,
- InterpreterContext interpreterContext) {
+ InterpreterContext interpreterContext) throws InterpreterException {
ClassLoader oldcl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(cl);
try {
List completion = intp.completion(buf, cursor, interpreterContext);
return completion;
- } catch (Exception e) {
- throw new InterpreterException(e);
} finally {
cl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(oldcl);
@@ -174,8 +169,6 @@ public class ClassloaderInterpreter
Thread.currentThread().setContextClassLoader(cl);
try {
return intp.getClassName();
- } catch (Exception e) {
- throw new InterpreterException(e);
} finally {
cl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(oldcl);
@@ -188,8 +181,6 @@ public class ClassloaderInterpreter
Thread.currentThread().setContextClassLoader(cl);
try {
intp.setInterpreterGroup(interpreterGroup);
- } catch (Exception e) {
- throw new InterpreterException(e);
} finally {
cl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(oldcl);
@@ -202,8 +193,6 @@ public class ClassloaderInterpreter
Thread.currentThread().setContextClassLoader(cl);
try {
return intp.getInterpreterGroup();
- } catch (Exception e) {
- throw new InterpreterException(e);
} finally {
cl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(oldcl);
@@ -216,8 +205,6 @@ public class ClassloaderInterpreter
Thread.currentThread().setContextClassLoader(cl);
try {
intp.setClassloaderUrls(urls);
- } catch (Exception e) {
- throw new InterpreterException(e);
} finally {
cl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(oldcl);
@@ -230,8 +217,6 @@ public class ClassloaderInterpreter
Thread.currentThread().setContextClassLoader(cl);
try {
return intp.getClassloaderUrls();
- } catch (Exception e) {
- throw new InterpreterException(e);
} finally {
cl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(oldcl);
@@ -239,13 +224,11 @@ public class ClassloaderInterpreter
}
@Override
- public void setProperty(Properties property) {
+ public void setProperties(Properties properties) {
ClassLoader oldcl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(cl);
try {
- intp.setProperty(property);
- } catch (Exception e) {
- throw new InterpreterException(e);
+ intp.setProperties(properties);
} finally {
cl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(oldcl);
@@ -253,13 +236,11 @@ public class ClassloaderInterpreter
}
@Override
- public Properties getProperty() {
+ public Properties getProperties() {
ClassLoader oldcl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(cl);
try {
- return intp.getProperty();
- } catch (Exception e) {
- throw new InterpreterException(e);
+ return intp.getProperties();
} finally {
cl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(oldcl);
@@ -272,8 +253,6 @@ public class ClassloaderInterpreter
Thread.currentThread().setContextClassLoader(cl);
try {
return intp.getProperty(key);
- } catch (Exception e) {
- throw new InterpreterException(e);
} finally {
cl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(oldcl);
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/Interpreter.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/Interpreter.java
index 05599a01a3..386de4178c 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/Interpreter.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/Interpreter.java
@@ -31,6 +31,7 @@ import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.reflect.FieldUtils;
import org.apache.zeppelin.annotation.Experimental;
import org.apache.zeppelin.annotation.ZeppelinApi;
+import org.apache.zeppelin.interpreter.launcher.InterpreterLauncher;
import org.apache.zeppelin.interpreter.thrift.InterpreterCompletion;
import org.apache.zeppelin.scheduler.Scheduler;
import org.apache.zeppelin.scheduler.SchedulerFactory;
@@ -55,20 +56,21 @@ public abstract class Interpreter {
* open() is called only once
*/
@ZeppelinApi
- public abstract void open();
+ public abstract void open() throws InterpreterException;
/**
* Closes interpreter. You may want to free your resources up here.
* close() is called only once
*/
@ZeppelinApi
- public abstract void close();
+ public abstract void close() throws InterpreterException;
/**
* Run precode if exists.
*/
@ZeppelinApi
- public InterpreterResult executePrecode(InterpreterContext interpreterContext) {
+ public InterpreterResult executePrecode(InterpreterContext interpreterContext)
+ throws InterpreterException {
String simpleName = this.getClass().getSimpleName();
String precode = getProperty(String.format("zeppelin.%s.precode", simpleName));
if (StringUtils.isNotBlank(precode)) {
@@ -83,13 +85,15 @@ public abstract class Interpreter {
* @param st statements to run
*/
@ZeppelinApi
- public abstract InterpreterResult interpret(String st, InterpreterContext context);
+ public abstract InterpreterResult interpret(String st,
+ InterpreterContext context)
+ throws InterpreterException;
/**
* Optionally implement the canceling routine to abort interpret() method
*/
@ZeppelinApi
- public abstract void cancel(InterpreterContext context);
+ public abstract void cancel(InterpreterContext context) throws InterpreterException;
/**
* Dynamic form handling
@@ -99,7 +103,7 @@ public abstract class Interpreter {
* FormType.NATIVE handles form in API
*/
@ZeppelinApi
- public abstract FormType getFormType();
+ public abstract FormType getFormType() throws InterpreterException;
/**
* get interpret() method running process in percentage.
@@ -107,7 +111,7 @@ public abstract class Interpreter {
* @return number between 0-100
*/
@ZeppelinApi
- public abstract int getProgress(InterpreterContext context);
+ public abstract int getProgress(InterpreterContext context) throws InterpreterException;
/**
* Get completion list based on cursor position.
@@ -120,7 +124,7 @@ public abstract class Interpreter {
*/
@ZeppelinApi
public List completion(String buf, int cursor,
- InterpreterContext interpreterContext) {
+ InterpreterContext interpreterContext) throws InterpreterException {
return null;
}
@@ -144,22 +148,22 @@ public abstract class Interpreter {
public static Logger logger = LoggerFactory.getLogger(Interpreter.class);
private InterpreterGroup interpreterGroup;
private URL[] classloaderUrls;
- protected Properties property;
- private String userName;
+ protected Properties properties;
+ protected String userName;
@ZeppelinApi
- public Interpreter(Properties property) {
- this.property = property;
+ public Interpreter(Properties properties) {
+ this.properties = properties;
}
- public void setProperty(Properties property) {
- this.property = property;
+ public void setProperties(Properties properties) {
+ this.properties = properties;
}
@ZeppelinApi
- public Properties getProperty() {
+ public Properties getProperties() {
Properties p = new Properties();
- p.putAll(property);
+ p.putAll(properties);
RegisteredInterpreter registeredInterpreter = Interpreter.findRegisteredInterpreterByClassName(
getClassName());
@@ -183,11 +187,22 @@ public abstract class Interpreter {
@ZeppelinApi
public String getProperty(String key) {
- logger.debug("key: {}, value: {}", key, getProperty().getProperty(key));
+ logger.debug("key: {}, value: {}", key, getProperties().getProperty(key));
- return getProperty().getProperty(key);
+ return getProperties().getProperty(key);
}
+ @ZeppelinApi
+ public String getProperty(String key, String defaultValue) {
+ logger.debug("key: {}, value: {}", key, getProperties().getProperty(key, defaultValue));
+
+ return getProperties().getProperty(key, defaultValue);
+ }
+
+ @ZeppelinApi
+ public void setProperty(String key, String value) {
+ properties.setProperty(key, value);
+ }
public String getClassName() {
return this.getClass().getName();
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/InterpreterException.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/InterpreterException.java
index ebd184ecfb..8b8a229765 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/InterpreterException.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/InterpreterException.java
@@ -17,11 +17,12 @@
package org.apache.zeppelin.interpreter;
+
/**
* Runtime Exception for interpreters.
*
*/
-public class InterpreterException extends RuntimeException {
+public class InterpreterException extends Exception {
public InterpreterException(Throwable e) {
super(e);
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/InterpreterGroup.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/InterpreterGroup.java
index 5428cdbb53..6acd601b87 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/InterpreterGroup.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/InterpreterGroup.java
@@ -26,7 +26,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
-import java.util.Random;
+import java.security.SecureRandom;
import java.util.concurrent.ConcurrentHashMap;
/**
@@ -70,7 +70,7 @@ public class InterpreterGroup {
}
private static String generateId() {
- return "InterpreterGroup_" + System.currentTimeMillis() + "_" + new Random().nextInt();
+ return "InterpreterGroup_" + System.currentTimeMillis() + "_" + new SecureRandom().nextInt();
}
public String getId() {
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/InterpreterOption.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/InterpreterOption.java
index 37a0d99c4a..e8a92255fc 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/InterpreterOption.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/InterpreterOption.java
@@ -28,7 +28,8 @@ public class InterpreterOption {
public static final transient String SCOPED = "scoped";
public static final transient String ISOLATED = "isolated";
- boolean remote;
+ // always set it as true, keep this field just for backward compatibility
+ boolean remote = true;
String host = null;
int port = -1;
@@ -77,14 +78,9 @@ public class InterpreterOption {
}
public InterpreterOption() {
- this(false);
}
- public InterpreterOption(boolean remote) {
- this(remote, SHARED, SHARED);
- }
-
- public InterpreterOption(boolean remote, String perUser, String perNote) {
+ public InterpreterOption(String perUser, String perNote) {
if (perUser == null) {
throw new NullPointerException("perUser can not be null.");
}
@@ -92,7 +88,6 @@ public class InterpreterOption {
throw new NullPointerException("perNote can not be null.");
}
- this.remote = remote;
this.perUser = perUser;
this.perNote = perNote;
}
@@ -112,14 +107,6 @@ public class InterpreterOption {
return option;
}
- public boolean isRemote() {
- return remote;
- }
-
- public void setRemote(boolean remote) {
- this.remote = remote;
- }
-
public String getHost() {
return host;
}
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/LazyOpenInterpreter.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/LazyOpenInterpreter.java
index 96f88eeb5c..8e55c31202 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/LazyOpenInterpreter.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/LazyOpenInterpreter.java
@@ -44,13 +44,13 @@ public class LazyOpenInterpreter
}
@Override
- public void setProperty(Properties property) {
- intp.setProperty(property);
+ public void setProperties(Properties properties) {
+ intp.setProperties(properties);
}
@Override
- public Properties getProperty() {
- return intp.getProperty();
+ public Properties getProperties() {
+ return intp.getProperties();
}
@Override
@@ -59,7 +59,7 @@ public class LazyOpenInterpreter
}
@Override
- public synchronized void open() {
+ public synchronized void open() throws InterpreterException {
if (opened == true) {
return;
}
@@ -73,12 +73,13 @@ public class LazyOpenInterpreter
}
@Override
- public InterpreterResult executePrecode(InterpreterContext interpreterContext) {
+ public InterpreterResult executePrecode(InterpreterContext interpreterContext)
+ throws InterpreterException {
return intp.executePrecode(interpreterContext);
}
@Override
- public void close() {
+ public void close() throws InterpreterException {
synchronized (intp) {
if (opened == true) {
intp.close();
@@ -94,7 +95,8 @@ public class LazyOpenInterpreter
}
@Override
- public InterpreterResult interpret(String st, InterpreterContext context) {
+ public InterpreterResult interpret(String st, InterpreterContext context)
+ throws InterpreterException {
open();
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
try {
@@ -105,18 +107,18 @@ public class LazyOpenInterpreter
}
@Override
- public void cancel(InterpreterContext context) {
+ public void cancel(InterpreterContext context) throws InterpreterException {
open();
intp.cancel(context);
}
@Override
- public FormType getFormType() {
+ public FormType getFormType() throws InterpreterException {
return intp.getFormType();
}
@Override
- public int getProgress(InterpreterContext context) {
+ public int getProgress(InterpreterContext context) throws InterpreterException {
if (opened) {
return intp.getProgress(context);
} else {
@@ -131,7 +133,7 @@ public class LazyOpenInterpreter
@Override
public List completion(String buf, int cursor,
- InterpreterContext interpreterContext) {
+ InterpreterContext interpreterContext) throws InterpreterException {
open();
List completion = intp.completion(buf, cursor, interpreterContext);
return completion;
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/graph/GraphResult.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/graph/GraphResult.java
new file mode 100644
index 0000000000..df1b9a3ae6
--- /dev/null
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/graph/GraphResult.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.interpreter.graph;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.zeppelin.interpreter.InterpreterResult;
+import org.apache.zeppelin.tabledata.Node;
+import org.apache.zeppelin.tabledata.Relationship;
+
+import com.google.gson.Gson;
+
+/**
+ * The intepreter result template for Networks
+ *
+ */
+public class GraphResult extends InterpreterResult {
+
+ /**
+ * The Graph structure parsed from the front-end
+ *
+ */
+ public static class Graph {
+ private Collection nodes;
+
+ private Collection edges;
+
+ /**
+ * The node types in the whole graph, and the related colors
+ *
+ */
+ private Map labels;
+
+ /**
+ * The relationship types in the whole graph
+ *
+ */
+ private Set types;
+
+ /**
+ * Is a directed graph
+ */
+ private boolean directed;
+
+ public Graph() {}
+
+ public Graph(Collection nodes, Collection edges,
+ Map labels, Set types, boolean directed) {
+ super();
+ this.setNodes(nodes);
+ this.setEdges(edges);
+ this.setLabels(labels);
+ this.setTypes(types);
+ this.setDirected(directed);
+ }
+
+ public Collection getNodes() {
+ return nodes;
+ }
+
+ public void setNodes(Collection nodes) {
+ this.nodes = nodes;
+ }
+
+ public Collection getEdges() {
+ return edges;
+ }
+
+ public void setEdges(Collection edges) {
+ this.edges = edges;
+ }
+
+ public Map getLabels() {
+ return labels;
+ }
+
+ public void setLabels(Map labels) {
+ this.labels = labels;
+ }
+
+ public Set getTypes() {
+ return types;
+ }
+
+ public void setTypes(Set types) {
+ this.types = types;
+ }
+
+ public boolean isDirected() {
+ return directed;
+ }
+
+ public void setDirected(boolean directed) {
+ this.directed = directed;
+ }
+
+ }
+
+ private static final Gson gson = new Gson();
+
+ public GraphResult(Code code, Graph graphObject) {
+ super(code, Type.NETWORK, gson.toJson(graphObject));
+ }
+
+}
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/launcher/InterpreterClient.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/launcher/InterpreterClient.java
new file mode 100644
index 0000000000..b991079fec
--- /dev/null
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/launcher/InterpreterClient.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.interpreter.launcher;
+
+/**
+ * Interface to InterpreterClient which is created by InterpreterLauncher. This is the component
+ * that is used to for the communication fromzeppelin-server process to zeppelin interpreter process
+ */
+public interface InterpreterClient {
+
+}
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/launcher/InterpreterLaunchContext.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/launcher/InterpreterLaunchContext.java
new file mode 100644
index 0000000000..db8f8dd2fa
--- /dev/null
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/launcher/InterpreterLaunchContext.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.interpreter.launcher;
+
+import org.apache.zeppelin.conf.ZeppelinConfiguration;
+import org.apache.zeppelin.interpreter.InterpreterOption;
+import org.apache.zeppelin.interpreter.InterpreterRunner;
+
+import java.util.Properties;
+
+/**
+ * Context class for Interpreter Launch
+ */
+public class InterpreterLaunchContext {
+
+ private Properties properties;
+ private InterpreterOption option;
+ private InterpreterRunner runner;
+ private String interpreterGroupId;
+ private String interpreterGroupName;
+
+ public InterpreterLaunchContext(Properties properties,
+ InterpreterOption option,
+ InterpreterRunner runner,
+ String interpreterGroupId,
+ String interpreterGroupName) {
+ this.properties = properties;
+ this.option = option;
+ this.runner = runner;
+ this.interpreterGroupId = interpreterGroupId;
+ this.interpreterGroupName = interpreterGroupName;
+ }
+
+ public Properties getProperties() {
+ return properties;
+ }
+
+ public InterpreterOption getOption() {
+ return option;
+ }
+
+ public InterpreterRunner getRunner() {
+ return runner;
+ }
+
+ public String getInterpreterGroupId() {
+ return interpreterGroupId;
+ }
+
+ public String getInterpreterGroupName() {
+ return interpreterGroupName;
+ }
+}
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/launcher/InterpreterLauncher.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/launcher/InterpreterLauncher.java
new file mode 100644
index 0000000000..5d0acf3515
--- /dev/null
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/launcher/InterpreterLauncher.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.interpreter.launcher;
+
+import org.apache.zeppelin.conf.ZeppelinConfiguration;
+
+import java.io.IOException;
+import java.util.Properties;
+
+/**
+ * Component to Launch interpreter process.
+ */
+public abstract class InterpreterLauncher {
+
+ protected ZeppelinConfiguration zConf;
+ protected Properties properties;
+
+ public InterpreterLauncher(ZeppelinConfiguration zConf) {
+ this.zConf = zConf;
+ }
+
+ public abstract InterpreterClient launch(InterpreterLaunchContext context) throws IOException;
+}
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterContextRunner.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterContextRunner.java
index 8d16ec52b1..74b8db6d9d 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterContextRunner.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterContextRunner.java
@@ -33,6 +33,6 @@ public class RemoteInterpreterContextRunner extends InterpreterContextRunner {
public void run() {
// this class should be used only for gson deserialize abstract class
// code should not reach here
- throw new InterpreterException("Assert");
+ throw new RuntimeException("Assert");
}
}
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterServer.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterServer.java
index 7f476e8026..cb0488cc07 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterServer.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterServer.java
@@ -207,7 +207,11 @@ public class RemoteInterpreterServer
if (interpreterGroup != null) {
for (List session : interpreterGroup.values()) {
for (Interpreter interpreter : session) {
- interpreter.close();
+ try {
+ interpreter.close();
+ } catch (InterpreterException e) {
+ logger.warn("Fail to close interpreter", e);
+ }
}
}
}
@@ -356,7 +360,11 @@ public class RemoteInterpreterServer
public void open(String sessionId, String className) throws TException {
logger.info(String.format("Open Interpreter %s for session %s ", className, sessionId));
Interpreter intp = getInterpreter(sessionId, className);
- intp.open();
+ try {
+ intp.open();
+ } catch (InterpreterException e) {
+ throw new TException("Fail to open interpreter", e);
+ }
}
@Override
@@ -388,7 +396,11 @@ public class RemoteInterpreterServer
while (it.hasNext()) {
Interpreter inp = it.next();
if (inp.getClassName().equals(className)) {
- inp.close();
+ try {
+ inp.close();
+ } catch (InterpreterException e) {
+ logger.warn("Fail to close interpreter", e);
+ }
it.remove();
break;
}
@@ -655,7 +667,11 @@ public class RemoteInterpreterServer
if (job != null) {
job.setStatus(Status.ABORT);
} else {
- intp.cancel(convert(interpreterContext, null));
+ try {
+ intp.cancel(convert(interpreterContext, null));
+ } catch (InterpreterException e) {
+ throw new TException("Fail to cancel", e);
+ }
}
}
@@ -672,7 +688,11 @@ public class RemoteInterpreterServer
throw new TException("No interpreter {} existed for session {}".format(
className, sessionId));
}
- return intp.getProgress(convert(interpreterContext, null));
+ try {
+ return intp.getProgress(convert(interpreterContext, null));
+ } catch (InterpreterException e) {
+ throw new TException("Fail to getProgress", e);
+ }
}
}
@@ -680,7 +700,11 @@ public class RemoteInterpreterServer
@Override
public String getFormType(String sessionId, String className) throws TException {
Interpreter intp = getInterpreter(sessionId, className);
- return intp.getFormType().toString();
+ try {
+ return intp.getFormType().toString();
+ } catch (InterpreterException e) {
+ throw new TException(e);
+ }
}
@Override
@@ -688,8 +712,11 @@ public class RemoteInterpreterServer
String className, String buf, int cursor, RemoteInterpreterContext remoteInterpreterContext)
throws TException {
Interpreter intp = getInterpreter(sessionId, className);
- List completion = intp.completion(buf, cursor, convert(remoteInterpreterContext, null));
- return completion;
+ try {
+ return intp.completion(buf, cursor, convert(remoteInterpreterContext, null));
+ } catch (InterpreterException e) {
+ throw new TException("Fail to get completion", e);
+ }
}
private InterpreterContext convert(RemoteInterpreterContext ric) {
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/tabledata/GraphEntity.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/tabledata/GraphEntity.java
new file mode 100644
index 0000000000..320b144726
--- /dev/null
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/tabledata/GraphEntity.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.tabledata;
+
+import java.util.Map;
+
+/**
+ * The base network entity
+ *
+ */
+public abstract class GraphEntity {
+
+ private long id;
+
+ /**
+ * The data of the entity
+ *
+ */
+ private Map data;
+
+ /**
+ * The primary type of the entity
+ */
+ private String label;
+
+ public GraphEntity() {}
+
+ public GraphEntity(long id, Map data, String label) {
+ super();
+ this.setId(id);
+ this.setData(data);
+ this.setLabel(label);
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public Map getData() {
+ return data;
+ }
+
+ public void setData(Map data) {
+ this.data = data;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+}
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/tabledata/Node.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/tabledata/Node.java
new file mode 100644
index 0000000000..2efabc4089
--- /dev/null
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/tabledata/Node.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.tabledata;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * The Zeppelin Node Entity
+ *
+ */
+public class Node extends GraphEntity {
+
+ /**
+ * The labels (types) attached to a node
+ */
+ private Set labels;
+
+ public Node() {}
+
+
+ public Node(long id, Map data, Set labels) {
+ super(id, data, labels.iterator().next());
+ }
+
+ public Set getLabels() {
+ return labels;
+ }
+
+ public void setLabels(Set labels) {
+ this.labels = labels;
+ }
+
+}
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/tabledata/Relationship.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/tabledata/Relationship.java
new file mode 100644
index 0000000000..aa8ddb7854
--- /dev/null
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/tabledata/Relationship.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.tabledata;
+
+import java.util.Map;
+
+/**
+ * The Zeppelin Relationship entity
+ *
+ */
+public class Relationship extends GraphEntity {
+
+ /**
+ * Source node ID
+ */
+ private long source;
+
+ /**
+ * End node ID
+ */
+ private long target;
+
+ public Relationship() {}
+
+ public Relationship(long id, Map data, long source,
+ long target, String label) {
+ super(id, data, label);
+ this.setSource(source);
+ this.setTarget(target);
+ }
+
+ public long getSource() {
+ return source;
+ }
+
+ public void setSource(long startNodeId) {
+ this.source = startNodeId;
+ }
+
+ public long getTarget() {
+ return target;
+ }
+
+ public void setTarget(long endNodeId) {
+ this.target = endNodeId;
+ }
+
+}
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/user/Credentials.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/user/Credentials.java
index e80a89f0e7..d345e3c507 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/user/Credentials.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/user/Credentials.java
@@ -47,7 +47,21 @@ public class Credentials {
private Boolean credentialsPersist = true;
File credentialsFile;
- public Credentials(Boolean credentialsPersist, String credentialsPath) {
+ private Encryptor encryptor;
+
+ /**
+ * Wrapper fro user credentials. It can load credentials from a file if credentialsPath is
+ * supplied, and will encrypt the file if an encryptKey is supplied.
+ *
+ * @param credentialsPersist
+ * @param credentialsPath
+ * @param encryptKey
+ */
+ public Credentials(Boolean credentialsPersist, String credentialsPath, String encryptKey) {
+ if (encryptKey != null) {
+ this.encryptor = new Encryptor(encryptKey);
+ }
+
this.credentialsPersist = credentialsPersist;
if (credentialsPath != null) {
credentialsFile = new File(credentialsPath);
@@ -119,6 +133,11 @@ public class Credentials {
fis.close();
String json = sb.toString();
+
+ if (encryptor != null) {
+ json = encryptor.decrypt(json);
+ }
+
CredentialsInfoSaving info = CredentialsInfoSaving.fromJson(json);
this.credentialsMap = info.credentialsMap;
} catch (IOException e) {
@@ -146,6 +165,11 @@ public class Credentials {
FileOutputStream fos = new FileOutputStream(credentialsFile, false);
OutputStreamWriter out = new OutputStreamWriter(fos);
+
+ if (encryptor != null) {
+ jsonString = encryptor.encrypt(jsonString);
+ }
+
out.append(jsonString);
out.close();
fos.close();
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/user/Encryptor.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/user/Encryptor.java
new file mode 100644
index 0000000000..cf04b372bd
--- /dev/null
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/user/Encryptor.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.user;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+
+import org.bouncycastle.crypto.BufferedBlockCipher;
+import org.bouncycastle.crypto.InvalidCipherTextException;
+import org.bouncycastle.crypto.engines.AESEngine;
+import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
+import org.bouncycastle.crypto.paddings.ZeroBytePadding;
+import org.bouncycastle.crypto.params.KeyParameter;
+import org.bouncycastle.util.encoders.Base64;
+
+/**
+ * Encrypt/decrypt arrays of bytes!
+ */
+public class Encryptor {
+ private final BufferedBlockCipher encryptCipher;
+ private final BufferedBlockCipher decryptCipher;
+
+ public Encryptor(String encryptKey) {
+ encryptCipher = new PaddedBufferedBlockCipher(new AESEngine(), new ZeroBytePadding());
+ encryptCipher.init(true, new KeyParameter(encryptKey.getBytes()));
+
+ decryptCipher = new PaddedBufferedBlockCipher(new AESEngine(), new ZeroBytePadding());
+ decryptCipher.init(false, new KeyParameter(encryptKey.getBytes()));
+ }
+
+
+ public String encrypt(String inputString) throws IOException {
+ byte[] input = inputString.getBytes();
+ byte[] result = new byte[encryptCipher.getOutputSize(input.length)];
+ int size = encryptCipher.processBytes(input, 0, input.length, result, 0);
+
+ try {
+ size += encryptCipher.doFinal(result, size);
+
+ byte[] out = new byte[size];
+ System.arraycopy(result, 0, out, 0, size);
+ return new String(Base64.encode(out));
+ } catch (InvalidCipherTextException e) {
+ throw new IOException("Cannot encrypt: " + e.getMessage(), e);
+ }
+ }
+
+ public String decrypt(String base64Input) throws IOException {
+ byte[] input = Base64.decode(base64Input);
+ byte[] result = new byte[decryptCipher.getOutputSize(input.length)];
+ int size = decryptCipher.processBytes(input, 0, input.length, result, 0);
+
+ try {
+ size += decryptCipher.doFinal(result, size);
+
+ byte[] out = new byte[size];
+ System.arraycopy(result, 0, out, 0, size);
+ return new String(out);
+ } catch (InvalidCipherTextException e) {
+ throw new IOException("Cannot decrypt: " + e.getMessage(), e);
+ }
+ }
+}
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/util/IdHashes.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/util/IdHashes.java
index 14c03a11cf..052aaefd21 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/util/IdHashes.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/util/IdHashes.java
@@ -20,7 +20,7 @@ package org.apache.zeppelin.util;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
-import java.util.Random;
+import java.security.SecureRandom;
/**
* Generate Tiny ID.
@@ -71,6 +71,6 @@ public class IdHashes {
}
public static String generateId() {
- return encode(System.currentTimeMillis() + new Random().nextInt());
+ return encode(System.currentTimeMillis() + new SecureRandom().nextInt());
}
}
diff --git a/zeppelin-interpreter/src/test/java/org/apache/zeppelin/interpreter/InterpreterTest.java b/zeppelin-interpreter/src/test/java/org/apache/zeppelin/interpreter/InterpreterTest.java
index 31c92256d8..d341b5864d 100644
--- a/zeppelin-interpreter/src/test/java/org/apache/zeppelin/interpreter/InterpreterTest.java
+++ b/zeppelin-interpreter/src/test/java/org/apache/zeppelin/interpreter/InterpreterTest.java
@@ -33,8 +33,8 @@ public class InterpreterTest {
p.put("p1", "v1");
Interpreter intp = new DummyInterpreter(p);
- assertEquals(1, intp.getProperty().size());
- assertEquals("v1", intp.getProperty().get("p1"));
+ assertEquals(1, intp.getProperties().size());
+ assertEquals("v1", intp.getProperties().get("p1"));
assertEquals("v1", intp.getProperty("p1"));
}
@@ -45,10 +45,10 @@ public class InterpreterTest {
Interpreter intp = new DummyInterpreter(p);
Properties overriddenProperty = new Properties();
overriddenProperty.put("p1", "v2");
- intp.setProperty(overriddenProperty);
+ intp.setProperties(overriddenProperty);
- assertEquals(1, intp.getProperty().size());
- assertEquals("v2", intp.getProperty().get("p1"));
+ assertEquals(1, intp.getProperties().size());
+ assertEquals("v2", intp.getProperties().get("p1"));
assertEquals("v2", intp.getProperty("p1"));
}
diff --git a/zeppelin-interpreter/src/test/java/org/apache/zeppelin/interpreter/LazyOpenInterpreterTest.java b/zeppelin-interpreter/src/test/java/org/apache/zeppelin/interpreter/LazyOpenInterpreterTest.java
index 26e835f56d..8e325f2b5b 100644
--- a/zeppelin-interpreter/src/test/java/org/apache/zeppelin/interpreter/LazyOpenInterpreterTest.java
+++ b/zeppelin-interpreter/src/test/java/org/apache/zeppelin/interpreter/LazyOpenInterpreterTest.java
@@ -28,7 +28,7 @@ public class LazyOpenInterpreterTest {
Interpreter interpreter = mock(Interpreter.class);
@Test
- public void isOpenTest() {
+ public void isOpenTest() throws InterpreterException {
InterpreterResult interpreterResult = new InterpreterResult(InterpreterResult.Code.SUCCESS, "");
when(interpreter.interpret(any(String.class), any(InterpreterContext.class))).thenReturn(interpreterResult);
diff --git a/zeppelin-interpreter/src/test/java/org/apache/zeppelin/user/CredentialsTest.java b/zeppelin-interpreter/src/test/java/org/apache/zeppelin/user/CredentialsTest.java
index 259516f976..4516bea845 100644
--- a/zeppelin-interpreter/src/test/java/org/apache/zeppelin/user/CredentialsTest.java
+++ b/zeppelin-interpreter/src/test/java/org/apache/zeppelin/user/CredentialsTest.java
@@ -27,7 +27,7 @@ public class CredentialsTest {
@Test
public void testDefaultProperty() throws IOException {
- Credentials credentials = new Credentials(false, null);
+ Credentials credentials = new Credentials(false, null, null);
UserCredentials userCredentials = new UserCredentials();
UsernamePassword up1 = new UsernamePassword("user2", "password");
userCredentials.putUsernamePassword("hive(vertica)", up1);
diff --git a/zeppelin-interpreter/src/test/java/org/apache/zeppelin/user/EncryptorTest.java b/zeppelin-interpreter/src/test/java/org/apache/zeppelin/user/EncryptorTest.java
new file mode 100644
index 0000000000..9950be6a63
--- /dev/null
+++ b/zeppelin-interpreter/src/test/java/org/apache/zeppelin/user/EncryptorTest.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.user;
+
+import java.io.IOException;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+public class EncryptorTest {
+
+ @Test
+ public void testEncryption() throws IOException {
+ Encryptor encryptor = new Encryptor("foobar1234567890");
+
+ String input = "test";
+
+ String encrypted = encryptor.encrypt(input);
+ assertNotEquals(input, encrypted);
+
+ String decrypted = encryptor.decrypt(encrypted);
+ assertEquals(input, decrypted);
+ }
+}
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/InterpreterRestApi.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/InterpreterRestApi.java
index c1dba5c417..e2a10e62b3 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/InterpreterRestApi.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/InterpreterRestApi.java
@@ -123,7 +123,7 @@ public class InterpreterRestApi {
request.getOption(), request.getProperties());
logger.info("new setting created with {}", interpreterSetting.getId());
return new JsonResponse<>(Status.OK, "", interpreterSetting).build();
- } catch (InterpreterException | IOException e) {
+ } catch (IOException e) {
logger.error("Exception in InterpreterRestApi while creating ", e);
return new JsonResponse<>(Status.NOT_FOUND, e.getMessage(), ExceptionUtils.getStackTrace(e))
.build();
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java
index c170a09901..42234fe29a 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java
@@ -41,10 +41,7 @@ import org.apache.zeppelin.notebook.Paragraph;
import org.apache.zeppelin.rest.exception.BadRequestException;
import org.apache.zeppelin.rest.exception.NotFoundException;
import org.apache.zeppelin.rest.exception.ForbiddenException;
-import org.apache.zeppelin.rest.message.CronRequest;
-import org.apache.zeppelin.rest.message.NewNoteRequest;
-import org.apache.zeppelin.rest.message.NewParagraphRequest;
-import org.apache.zeppelin.rest.message.RunParagraphWithParametersRequest;
+import org.apache.zeppelin.rest.message.*;
import org.apache.zeppelin.search.SearchService;
import org.apache.zeppelin.server.JsonResponse;
import org.apache.zeppelin.socket.NotebookServer;
@@ -496,6 +493,37 @@ public class NotebookRestApi {
return new JsonResponse<>(Status.OK, "", p).build();
}
+ /**
+ * Update paragraph
+ *
+ * @param message json containing the "text" and optionally the "title" of the paragraph, e.g.
+ * {"text" : "updated text", "title" : "Updated title" }
+ *
+ */
+ @PUT
+ @Path("{noteId}/paragraph/{paragraphId}")
+ @ZeppelinApi
+ public Response updateParagraph(@PathParam("noteId") String noteId,
+ @PathParam("paragraphId") String paragraphId,
+ String message) throws IOException {
+ String user = SecurityUtils.getPrincipal();
+ LOG.info("{} will update paragraph {} {}", user, noteId, paragraphId);
+
+ Note note = notebook.getNote(noteId);
+ checkIfNoteIsNotNull(note);
+ checkIfUserCanWrite(noteId, "Insufficient privileges you cannot update this paragraph");
+ Paragraph p = note.getParagraph(paragraphId);
+ checkIfParagraphIsNotNull(p);
+
+ UpdateParagraphRequest updatedParagraph = gson.fromJson(message, UpdateParagraphRequest.class);
+ p.setText(updatedParagraph.getText());
+ if (updatedParagraph.getTitle() != null) { p.setTitle(updatedParagraph.getTitle()); }
+ AuthenticationInfo subject = new AuthenticationInfo(user);
+ note.persist(subject);
+ notebookServer.broadcastParagraph(note, p);
+ return new JsonResponse<>(Status.OK, "").build();
+ }
+
@PUT
@Path("{noteId}/paragraph/{paragraphId}/config")
@ZeppelinApi
@@ -514,7 +542,6 @@ public class NotebookRestApi {
configureParagraph(p, newConfig, user);
AuthenticationInfo subject = new AuthenticationInfo(user);
note.persist(subject);
-
return new JsonResponse<>(Status.OK, "", p).build();
}
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/UpdateParagraphRequest.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/UpdateParagraphRequest.java
new file mode 100644
index 0000000000..3b4a6f68cc
--- /dev/null
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/UpdateParagraphRequest.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.rest.message;
+
+/**
+ * UpdateParagraphRequest
+ */
+public class UpdateParagraphRequest {
+ String title;
+ String text;
+
+ public UpdateParagraphRequest() {
+
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public String getText() {
+ return text;
+ }
+
+
+}
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/server/ZeppelinServer.java b/zeppelin-server/src/main/java/org/apache/zeppelin/server/ZeppelinServer.java
index c103eeb93a..f27bfbe27e 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/server/ZeppelinServer.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/server/ZeppelinServer.java
@@ -132,7 +132,10 @@ public class ZeppelinServer extends Application {
this.notebookRepo = new NotebookRepoSync(conf);
this.noteSearchService = new LuceneSearch();
this.notebookAuthorization = NotebookAuthorization.init(conf);
- this.credentials = new Credentials(conf.credentialsPersist(), conf.getCredentialsPath());
+ this.credentials = new Credentials(
+ conf.credentialsPersist(),
+ conf.getCredentialsPath(),
+ conf.getCredentialsEncryptKey());
notebook = new Notebook(conf,
notebookRepo, schedulerFactory, replFactory, interpreterSettingManager, notebookWsServer,
noteSearchService, notebookAuthorization, credentials);
@@ -152,7 +155,7 @@ public class ZeppelinServer extends Application {
} catch (Exception e) {
LOG.error(e.getMessage(), e);
}
-
+
// to update notebook from application event from remote process.
heliumApplicationFactory.setNotebook(notebook);
// to update fire websocket event on application event.
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java
index 5093cb838f..2a64665b0c 100644
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java
@@ -27,6 +27,7 @@ import com.google.common.collect.Sets;
import org.apache.commons.httpclient.methods.DeleteMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.lang3.StringUtils;
import org.apache.zeppelin.notebook.Note;
import org.apache.zeppelin.notebook.Paragraph;
@@ -651,6 +652,43 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
}
+ @Test
+ public void testUpdateParagraph() throws IOException {
+ Note note = ZeppelinServer.notebook.createNote(anonymous);
+
+ String jsonRequest = "{\"title\": \"title1\", \"text\": \"text1\"}";
+ PostMethod post = httpPost("/notebook/" + note.getId() + "/paragraph", jsonRequest);
+ Map resp = gson.fromJson(post.getResponseBodyAsString(), new TypeToken>() {}.getType());
+ post.releaseConnection();
+
+ String newParagraphId = (String) resp.get("body");
+ Paragraph newParagraph = ZeppelinServer.notebook.getNote(note.getId()).getParagraph(newParagraphId);
+
+ assertEquals("title1", newParagraph.getTitle());
+ assertEquals("text1", newParagraph.getText());
+
+ String updateRequest = "{\"text\": \"updated text\"}";
+ PutMethod put = httpPut("/notebook/" + note.getId() + "/paragraph/" + newParagraphId, updateRequest);
+ assertThat("Test update method:", put, isAllowed());
+ put.releaseConnection();
+
+ Paragraph updatedParagraph = ZeppelinServer.notebook.getNote(note.getId()).getParagraph(newParagraphId);
+
+ assertEquals("title1", updatedParagraph.getTitle());
+ assertEquals("updated text", updatedParagraph.getText());
+
+ String updateBothRequest = "{\"title\": \"updated title\", \"text\" : \"updated text 2\" }";
+ PutMethod updatePut = httpPut("/notebook/" + note.getId() + "/paragraph/" + newParagraphId, updateBothRequest);
+ updatePut.releaseConnection();
+
+ Paragraph updatedBothParagraph = ZeppelinServer.notebook.getNote(note.getId()).getParagraph(newParagraphId);
+
+ assertEquals("updated title", updatedBothParagraph.getTitle());
+ assertEquals("updated text 2", updatedBothParagraph.getText());
+
+ ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
+ }
+
@Test
public void testGetParagraph() throws IOException {
Note note = ZeppelinServer.notebook.createNote(anonymous);
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinSparkClusterTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinSparkClusterTest.java
index 3e464498ad..2fa584b9c4 100644
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinSparkClusterTest.java
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinSparkClusterTest.java
@@ -27,6 +27,7 @@ import java.util.List;
import java.util.Map;
import org.apache.commons.io.FileUtils;
+import org.apache.zeppelin.interpreter.InterpreterException;
import org.apache.zeppelin.interpreter.InterpreterResult;
import org.apache.zeppelin.interpreter.InterpreterSetting;
import org.apache.zeppelin.notebook.Note;
@@ -171,7 +172,7 @@ public class ZeppelinSparkClusterTest extends AbstractTestRestApi {
}
@Test
- public void sparkRTest() throws IOException {
+ public void sparkRTest() throws IOException, InterpreterException {
// create new note
Note note = ZeppelinServer.notebook.createNote(anonymous);
int sparkVersion = getSparkVersionNumber(note);
@@ -426,7 +427,7 @@ public class ZeppelinSparkClusterTest extends AbstractTestRestApi {
}
@Test
- public void pySparkDepLoaderTest() throws IOException {
+ public void pySparkDepLoaderTest() throws IOException, InterpreterException {
// create new note
Note note = ZeppelinServer.notebook.createNote(anonymous);
int sparkVersionNumber = getSparkVersionNumber(note);
diff --git a/zeppelin-web/e2e/searchBlock.spec.js b/zeppelin-web/e2e/searchBlock.spec.js
index 4a0ea48ca3..570673b838 100644
--- a/zeppelin-web/e2e/searchBlock.spec.js
+++ b/zeppelin-web/e2e/searchBlock.spec.js
@@ -99,7 +99,7 @@ describe('Search block e2e Test', function() {
waitVisibility(element(by.repeater('currentParagraph in note.paragraphs')))
browser.switchTo().activeElement().sendKeys(testData.textInFirstP)
let addBelow = element(
- by.xpath('//div[@class="new-paragraph" and @ng-click="insertNew(\'below\');"]'))
+ by.xpath('//div[@class="new-paragraph last-paragraph" and @ng-click="insertNew(\'below\');"]'))
clickAndWait(addBelow)
browser.switchTo().activeElement().sendKeys(testData.textInSecondP)
}
@@ -123,7 +123,6 @@ describe('Search block e2e Test', function() {
}
/*Tests*/
-
it('shortcut works', function() {
waitVisibility(element(by.repeater('currentParagraph in note.paragraphs')))
openSearchBoxByShortcut()
diff --git a/zeppelin-web/webpack.config.js b/zeppelin-web/webpack.config.js
index 6fba4b1a30..3c349240ca 100644
--- a/zeppelin-web/webpack.config.js
+++ b/zeppelin-web/webpack.config.js
@@ -120,6 +120,7 @@ module.exports = function makeWebpackConfig () {
* Reference: http://webpack.github.io/docs/configuration.html#devtool
* Type of sourcemap to use per build type
*/
+ config.devtool = 'eval-source-map';
if (isTest) {
config.devtool = 'inline-source-map';
} else if (isProd) {
@@ -127,7 +128,6 @@ module.exports = function makeWebpackConfig () {
} else {
config.devtool = 'eval-source-map';
}
- config.devtool = 'source-map';
/**
* Loaders
@@ -196,14 +196,6 @@ module.exports = function makeWebpackConfig () {
}
]})
}],
- postLoaders: [
- {
- // COVERAGE
- test: /\.js$/,
- exclude: /(node_modules|bower_components|\.test\.js)/,
- loader: 'istanbul-instrumenter'
- }
- ]
};
/**
@@ -250,6 +242,17 @@ module.exports = function makeWebpackConfig () {
})
)
}
+
+ if (isTest) {
+ config.module.postLoaders = [
+ {
+ // COVERAGE
+ test: /\.js$/,
+ exclude: /(node_modules|bower_components|\.test\.js)/,
+ loader: 'istanbul-instrumenter'
+ }
+ ]
+ }
// Add build specific plugins
if (isProd) {
diff --git a/zeppelin-zengine/pom.xml b/zeppelin-zengine/pom.xml
index c67df6b44a..d1a227052c 100644
--- a/zeppelin-zengine/pom.xml
+++ b/zeppelin-zengine/pom.xml
@@ -70,11 +70,6 @@
slf4j-log4j12
-
- commons-configuration
- commons-configuration
-
-
commons-io
commons-io
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterFactory.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterFactory.java
index f020919442..7233239838 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterFactory.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterFactory.java
@@ -77,7 +77,7 @@ public class InterpreterFactory {
return interpreter;
}
}
- throw new InterpreterException(replName + " interpreter not found");
+ return null;
} else {
// first assume replName is 'name' of interpreter. ('groupName' is ommitted)
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterInfoSaving.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterInfoSaving.java
index d7593d54e9..3d9c2c348a 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterInfoSaving.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterInfoSaving.java
@@ -63,11 +63,6 @@ public class InterpreterInfoSaving implements JsonSerializable {
if (infoSaving != null && infoSaving.interpreterSettings != null) {
for (InterpreterSetting interpreterSetting : infoSaving.interpreterSettings.values()) {
- // Always use separate interpreter process
- // While we decided to turn this feature on always (without providing
- // enable/disable option on GUI).
- // previously created setting should turn this feature on here.
- interpreterSetting.getOption().setRemote(true);
interpreterSetting.convertPermissionsFromUsersToOwners(
jsonObject.getAsJsonObject("interpreterSettings")
.getAsJsonObject(interpreterSetting.getId()));
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSetting.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSetting.java
index 3a808c51d1..a82d5bf0e7 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSetting.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSetting.java
@@ -18,7 +18,6 @@
package org.apache.zeppelin.interpreter;
import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.gson.JsonArray;
@@ -34,19 +33,22 @@ import org.apache.zeppelin.dep.DependencyResolver;
import org.apache.zeppelin.display.AngularObjectRegistry;
import org.apache.zeppelin.display.AngularObjectRegistryListener;
import org.apache.zeppelin.helium.ApplicationEventListener;
+import org.apache.zeppelin.interpreter.launcher.InterpreterLaunchContext;
+import org.apache.zeppelin.interpreter.launcher.InterpreterLauncher;
+import org.apache.zeppelin.interpreter.launcher.ShellScriptLauncher;
+import org.apache.zeppelin.interpreter.launcher.SparkInterpreterLauncher;
import org.apache.zeppelin.interpreter.remote.RemoteAngularObjectRegistry;
import org.apache.zeppelin.interpreter.remote.RemoteInterpreter;
-import org.apache.zeppelin.interpreter.remote.RemoteInterpreterManagedProcess;
+import org.apache.zeppelin.interpreter.remote.RemoteInterpreterEventPoller;
import org.apache.zeppelin.interpreter.remote.RemoteInterpreterProcess;
import org.apache.zeppelin.interpreter.remote.RemoteInterpreterProcessListener;
-import org.apache.zeppelin.interpreter.remote.RemoteInterpreterRunningProcess;
import org.apache.zeppelin.interpreter.remote.RemoteInterpreterUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileNotFoundException;
-import java.io.FilenameFilter;
+import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
@@ -58,7 +60,6 @@ import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import java.util.NoSuchElementException;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@@ -105,7 +106,7 @@ public class InterpreterSetting {
private List interpreterInfos;
private List dependencies = new ArrayList<>();
- private InterpreterOption option = new InterpreterOption(true);
+ private InterpreterOption option = new InterpreterOption();
@SerializedName("runner")
private InterpreterRunner interpreterRunner;
@@ -132,8 +133,10 @@ public class InterpreterSetting {
private transient ZeppelinConfiguration conf = new ZeppelinConfiguration();
- private transient Map cleanCl =
- Collections.synchronizedMap(new HashMap());
+ // TODO(zjffdu) ShellScriptLauncher is the only launcher implemention for now. It could be other
+ // launcher in future when we have other launcher implementation. e.g. third party launcher
+ // service like livy
+ private transient InterpreterLauncher launcher;
///////////////////////////////////////////////////////////////////////////////////////////
@@ -245,6 +248,7 @@ public class InterpreterSetting {
}
void postProcessing() {
+// createLauncher();
this.status = Status.READY;
}
@@ -268,6 +272,14 @@ public class InterpreterSetting {
this.conf = o.getConf();
}
+ private void createLauncher() {
+ if (group.equals("spark")) {
+ this.launcher = new SparkInterpreterLauncher(this.conf);
+ } else {
+ this.launcher = new ShellScriptLauncher(this.conf);
+ }
+ }
+
public AngularObjectRegistryListener getAngularObjectRegistryListener() {
return angularObjectRegistryListener;
}
@@ -616,13 +628,8 @@ public class InterpreterSetting {
List interpreterInfos = getInterpreterInfos();
for (InterpreterInfo info : interpreterInfos) {
Interpreter interpreter = null;
- if (option.isRemote()) {
- interpreter = new RemoteInterpreter(getJavaProperties(), sessionId,
- info.getClassName(), user);
- } else {
- interpreter = createLocalInterpreter(info.getClassName());
- }
-
+ interpreter = new RemoteInterpreter(getJavaProperties(), sessionId,
+ info.getClassName(), user);
if (info.isDefaultInterpreter()) {
interpreters.add(0, interpreter);
} else {
@@ -634,210 +641,16 @@ public class InterpreterSetting {
return interpreters;
}
- // Create Interpreter in ZeppelinServer for non-remote mode
- private Interpreter createLocalInterpreter(String className)
- throws InterpreterException {
- LOGGER.info("Create Local Interpreter {} from {}", className, interpreterDir);
-
- ClassLoader oldcl = Thread.currentThread().getContextClassLoader();
- try {
-
- URLClassLoader ccl = cleanCl.get(interpreterDir);
- if (ccl == null) {
- // classloader fallback
- ccl = URLClassLoader.newInstance(new URL[]{}, oldcl);
- }
-
- boolean separateCL = true;
- try { // check if server's classloader has driver already.
- Class cls = this.getClass().forName(className);
- if (cls != null) {
- separateCL = false;
- }
- } catch (Exception e) {
- LOGGER.error("exception checking server classloader driver", e);
- }
-
- URLClassLoader cl;
-
- if (separateCL == true) {
- cl = URLClassLoader.newInstance(new URL[]{}, ccl);
- } else {
- cl = ccl;
- }
- Thread.currentThread().setContextClassLoader(cl);
-
- Class replClass = (Class) cl.loadClass(className);
- Constructor constructor =
- replClass.getConstructor(new Class[]{Properties.class});
- Interpreter repl = constructor.newInstance(getJavaProperties());
- repl.setClassloaderUrls(ccl.getURLs());
- LazyOpenInterpreter intp = new LazyOpenInterpreter(new ClassloaderInterpreter(repl, cl));
- return intp;
- } catch (SecurityException e) {
- throw new InterpreterException(e);
- } catch (NoSuchMethodException e) {
- throw new InterpreterException(e);
- } catch (IllegalArgumentException e) {
- throw new InterpreterException(e);
- } catch (InstantiationException e) {
- throw new InterpreterException(e);
- } catch (IllegalAccessException e) {
- throw new InterpreterException(e);
- } catch (InvocationTargetException e) {
- throw new InterpreterException(e);
- } catch (ClassNotFoundException e) {
- throw new InterpreterException(e);
- } finally {
- Thread.currentThread().setContextClassLoader(oldcl);
- }
- }
-
- RemoteInterpreterProcess createInterpreterProcess() {
- RemoteInterpreterProcess remoteInterpreterProcess = null;
- int connectTimeout =
- conf.getInt(ZeppelinConfiguration.ConfVars.ZEPPELIN_INTERPRETER_CONNECT_TIMEOUT);
- String localRepoPath = conf.getInterpreterLocalRepoPath() + "/" + id;
- if (option.isExistingProcess()) {
- // TODO(zjffdu) remove the existing process approach seems no one is using this.
- // use the existing process
- remoteInterpreterProcess = new RemoteInterpreterRunningProcess(
- connectTimeout,
- remoteInterpreterProcessListener,
- appEventListener,
- option.getHost(),
- option.getPort());
- } else {
- // create new remote process
- remoteInterpreterProcess = new RemoteInterpreterManagedProcess(
- interpreterRunner != null ? interpreterRunner.getPath() :
- conf.getInterpreterRemoteRunnerPath(), conf.getCallbackPortRange(),
- interpreterDir, localRepoPath,
- getEnvFromInterpreterProperty(), connectTimeout,
- remoteInterpreterProcessListener, appEventListener, group);
- }
- return remoteInterpreterProcess;
- }
-
- private boolean isSparkConf(String key, String value) {
- return !StringUtils.isEmpty(key) && key.startsWith("spark.") && !StringUtils.isEmpty(value);
- }
-
- private Map getEnvFromInterpreterProperty() {
- Map env = new HashMap();
- Properties javaProperties = getJavaProperties();
- Properties sparkProperties = new Properties();
- String sparkMaster = getSparkMaster();
- for (String key : javaProperties.stringPropertyNames()) {
- if (RemoteInterpreterUtils.isEnvString(key)) {
- env.put(key, javaProperties.getProperty(key));
- }
- if (isSparkConf(key, javaProperties.getProperty(key))) {
- sparkProperties.setProperty(key, toShellFormat(javaProperties.getProperty(key)));
- }
- }
-
- setupPropertiesForPySpark(sparkProperties);
- setupPropertiesForSparkR(sparkProperties, System.getenv("SPARK_HOME"));
- if (isYarnMode() && getDeployMode().equals("cluster")) {
- env.put("SPARK_YARN_CLUSTER", "true");
- }
-
- StringBuilder sparkConfBuilder = new StringBuilder();
- if (sparkMaster != null) {
- sparkConfBuilder.append(" --master " + sparkMaster);
- }
- if (isYarnMode() && getDeployMode().equals("cluster")) {
- sparkConfBuilder.append(" --files " + conf.getConfDir() + "/log4j_yarn_cluster.properties");
- }
- for (String name : sparkProperties.stringPropertyNames()) {
- sparkConfBuilder.append(" --conf " + name + "=" + sparkProperties.getProperty(name));
- }
-
- env.put("ZEPPELIN_SPARK_CONF", sparkConfBuilder.toString());
- LOGGER.debug("getEnvFromInterpreterProperty: " + env);
- return env;
- }
-
- private void setupPropertiesForPySpark(Properties sparkProperties) {
- if (isYarnMode()) {
- sparkProperties.setProperty("spark.yarn.isPython", "true");
- }
- }
-
- private void mergeSparkProperty(Properties sparkProperties, String propertyName,
- String propertyValue) {
- if (sparkProperties.containsKey(propertyName)) {
- String oldPropertyValue = sparkProperties.getProperty(propertyName);
- sparkProperties.setProperty(propertyName, oldPropertyValue + "," + propertyValue);
- } else {
- sparkProperties.setProperty(propertyName, propertyValue);
- }
- }
-
- private void setupPropertiesForSparkR(Properties sparkProperties,
- String sparkHome) {
- File sparkRBasePath = null;
- if (sparkHome == null) {
- if (!getSparkMaster().startsWith("local")) {
- throw new RuntimeException("SPARK_HOME is not specified for non-local mode");
- }
- String zeppelinHome = conf.getString(ZeppelinConfiguration.ConfVars.ZEPPELIN_HOME);
- sparkRBasePath = new File(zeppelinHome,
- "interpreter" + File.separator + "spark" + File.separator + "R");
- } else {
- sparkRBasePath = new File(sparkHome, "R" + File.separator + "lib");
- }
-
- File sparkRPath = new File(sparkRBasePath, "sparkr.zip");
- if (sparkRPath.exists() && sparkRPath.isFile()) {
- mergeSparkProperty(sparkProperties, "spark.yarn.dist.archives", sparkRPath.getAbsolutePath());
- } else {
- LOGGER.warn("sparkr.zip is not found, SparkR may not work.");
- }
- }
-
- private String getSparkMaster() {
- String master = getJavaProperties().getProperty("master");
- if (master == null) {
- master = getJavaProperties().getProperty("spark.master", "local[*]");
- }
- return master;
- }
-
- private String getDeployMode() {
- String master = getSparkMaster();
- if (master.equals("yarn-client")) {
- return "client";
- } else if (master.equals("yarn-cluster")) {
- return "cluster";
- } else if (master.startsWith("local")) {
- return "client";
- } else {
- String deployMode = getJavaProperties().getProperty("spark.submit.deployMode");
- if (deployMode == null) {
- throw new RuntimeException("master is set as yarn, but spark.submit.deployMode " +
- "is not specified");
- }
- if (!deployMode.equals("client") && !deployMode.equals("cluster")) {
- throw new RuntimeException("Invalid value for spark.submit.deployMode: " + deployMode);
- }
- return deployMode;
- }
- }
-
- private boolean isYarnMode() {
- return getSparkMaster().startsWith("yarn");
- }
-
- private String toShellFormat(String value) {
- if (value.contains("\'") && value.contains("\"")) {
- throw new RuntimeException("Spark property value could not contain both \" and '");
- } else if (value.contains("\'")) {
- return "\"" + value + "\"";
- } else {
- return "\'" + value + "\'";
+ synchronized RemoteInterpreterProcess createInterpreterProcess() throws IOException {
+ if (launcher == null) {
+ createLauncher();
}
+ InterpreterLaunchContext launchContext = new
+ InterpreterLaunchContext(getJavaProperties(), option, interpreterRunner, id, name);
+ RemoteInterpreterProcess process = (RemoteInterpreterProcess) launcher.launch(launchContext);
+ process.setRemoteInterpreterEventPoller(
+ new RemoteInterpreterEventPoller(remoteInterpreterProcessListener, appEventListener));
+ return process;
}
private List getOrCreateSession(String user, String noteId) {
@@ -881,18 +694,11 @@ public class InterpreterSetting {
return null;
}
- private ManagedInterpreterGroup createInterpreterGroup(String groupId)
- throws InterpreterException {
+ private ManagedInterpreterGroup createInterpreterGroup(String groupId) {
AngularObjectRegistry angularObjectRegistry;
ManagedInterpreterGroup interpreterGroup = new ManagedInterpreterGroup(groupId, this);
- if (option.isRemote()) {
- angularObjectRegistry =
- new RemoteAngularObjectRegistry(groupId, angularObjectRegistryListener, interpreterGroup);
- } else {
- angularObjectRegistry = new AngularObjectRegistry(id, angularObjectRegistryListener);
- // TODO(moon) : create distributed resource pool for local interpreters and set
- }
-
+ angularObjectRegistry =
+ new RemoteAngularObjectRegistry(groupId, angularObjectRegistryListener, interpreterGroup);
interpreterGroup.setAngularObjectRegistry(angularObjectRegistry);
return interpreterGroup;
}
@@ -1010,7 +816,8 @@ public class InterpreterSetting {
);
newProperties.put(key, property);
} else {
- throw new RuntimeException("Can not convert this type of property: " + value.getClass());
+ throw new RuntimeException("Can not convert this type of property: " +
+ value.getClass());
}
}
return newProperties;
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java
index 73bababdf5..f34195d706 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java
@@ -124,7 +124,7 @@ public class InterpreterSettingManager {
remoteInterpreterProcessListener,
ApplicationEventListener appEventListener)
throws IOException {
- this(zeppelinConfiguration, new InterpreterOption(true),
+ this(zeppelinConfiguration, new InterpreterOption(),
angularObjectRegistryListener,
remoteInterpreterProcessListener,
appEventListener);
@@ -192,8 +192,15 @@ public class InterpreterSettingManager {
Map mergedProperties =
new HashMap<>(InterpreterSetting.convertInterpreterProperties(
interpreterSettingTemplate.getProperties()));
- mergedProperties.putAll(InterpreterSetting.convertInterpreterProperties(
- savedInterpreterSetting.getProperties()));
+ Map savedProperties = InterpreterSetting
+ .convertInterpreterProperties(savedInterpreterSetting.getProperties());
+ for (Map.Entry entry : savedProperties.entrySet()) {
+ // only merge properties whose value is not empty
+ if (entry.getValue().getValue() != null && !
+ StringUtils.isBlank(entry.getValue().toString())) {
+ mergedProperties.put(entry.getKey(), entry.getValue());
+ }
+ }
savedInterpreterSetting.setProperties(mergedProperties);
// merge InterpreterInfo
savedInterpreterSetting.setInterpreterInfos(
@@ -737,11 +744,12 @@ public class InterpreterSettingManager {
}
/**
- * Change interpreter property and restart
+ * Change interpreter properties and restart
*/
public void setPropertyAndRestart(String id, InterpreterOption option,
Map properties,
- List dependencies) throws IOException {
+ List dependencies)
+ throws InterpreterException, IOException {
synchronized (interpreterSettings) {
InterpreterSetting intpSetting = interpreterSettings.get(id);
if (intpSetting != null) {
@@ -754,7 +762,7 @@ public class InterpreterSettingManager {
saveToFile();
} catch (Exception e) {
loadFromFile();
- throw e;
+ throw new IOException(e);
}
} else {
throw new InterpreterException("Interpreter setting id " + id + " not found");
@@ -763,7 +771,7 @@ public class InterpreterSettingManager {
}
// restart in note page
- public void restart(String settingId, String noteId, String user) {
+ public void restart(String settingId, String noteId, String user) throws InterpreterException {
InterpreterSetting intpSetting = interpreterSettings.get(settingId);
Preconditions.checkNotNull(intpSetting);
synchronized (interpreterSettings) {
@@ -787,7 +795,7 @@ public class InterpreterSettingManager {
}
}
- public void restart(String id) {
+ public void restart(String id) throws InterpreterException {
restart(id, "", "anonymous");
}
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/ManagedInterpreterGroup.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/ManagedInterpreterGroup.java
index 1d7d916b6e..ff9cb1c47f 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/ManagedInterpreterGroup.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/ManagedInterpreterGroup.java
@@ -25,6 +25,7 @@ import org.apache.zeppelin.scheduler.SchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.io.IOException;
import java.util.Collection;
import java.util.List;
@@ -52,7 +53,7 @@ public class ManagedInterpreterGroup extends InterpreterGroup {
return interpreterSetting;
}
- public synchronized RemoteInterpreterProcess getOrCreateInterpreterProcess() {
+ public synchronized RemoteInterpreterProcess getOrCreateInterpreterProcess() throws IOException {
if (remoteInterpreterProcess == null) {
LOGGER.info("Create InterperterProcess for InterpreterGroup: " + getId());
remoteInterpreterProcess = interpreterSetting.createInterpreterProcess();
@@ -112,7 +113,11 @@ public class ManagedInterpreterGroup extends InterpreterGroup {
LOGGER.info("Job " + job.getJobName() + " aborted ");
}
- interpreter.close();
+ try {
+ interpreter.close();
+ } catch (InterpreterException e) {
+ LOGGER.warn("Fail to close interpreter " + interpreter.getClassName(), e);
+ }
//TODO(zjffdu) move the close of schedule to Interpreter
if (null != scheduler) {
SchedulerFactory.singleton().removeScheduler(scheduler.getName());
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/launcher/ShellScriptLauncher.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/launcher/ShellScriptLauncher.java
new file mode 100644
index 0000000000..f419967dee
--- /dev/null
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/launcher/ShellScriptLauncher.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.interpreter.launcher;
+
+import org.apache.zeppelin.conf.ZeppelinConfiguration;
+import org.apache.zeppelin.interpreter.InterpreterOption;
+import org.apache.zeppelin.interpreter.InterpreterRunner;
+import org.apache.zeppelin.interpreter.remote.RemoteInterpreterManagedProcess;
+import org.apache.zeppelin.interpreter.remote.RemoteInterpreterRunningProcess;
+import org.apache.zeppelin.interpreter.remote.RemoteInterpreterUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * Interpreter Launcher which use shell script to launch the interpreter process.
+ *
+ */
+public class ShellScriptLauncher extends InterpreterLauncher {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ShellScriptLauncher.class);
+
+ public ShellScriptLauncher(ZeppelinConfiguration zConf) {
+ super(zConf);
+ }
+
+ @Override
+ public InterpreterClient launch(InterpreterLaunchContext context) {
+ LOGGER.info("Launching Interpreter: " + context.getInterpreterGroupName());
+ this.properties = context.getProperties();
+ InterpreterOption option = context.getOption();
+ InterpreterRunner runner = context.getRunner();
+ String groupName = context.getInterpreterGroupName();
+
+ int connectTimeout =
+ zConf.getInt(ZeppelinConfiguration.ConfVars.ZEPPELIN_INTERPRETER_CONNECT_TIMEOUT);
+ if (option.isExistingProcess()) {
+ return new RemoteInterpreterRunningProcess(
+ connectTimeout,
+ option.getHost(),
+ option.getPort());
+ } else {
+ // create new remote process
+ String localRepoPath = zConf.getInterpreterLocalRepoPath() + "/"
+ + context.getInterpreterGroupId();
+ return new RemoteInterpreterManagedProcess(
+ runner != null ? runner.getPath() : zConf.getInterpreterRemoteRunnerPath(),
+ zConf.getCallbackPortRange(),
+ zConf.getInterpreterDir() + "/" + groupName, localRepoPath,
+ buildEnvFromProperties(), connectTimeout, groupName);
+ }
+ }
+
+ protected Map buildEnvFromProperties() {
+ Map env = new HashMap<>();
+ for (Object key : properties.keySet()) {
+ if (RemoteInterpreterUtils.isEnvString((String) key)) {
+ env.put((String) key, properties.getProperty((String) key));
+ }
+ }
+ return env;
+ }
+}
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/launcher/SparkInterpreterLauncher.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/launcher/SparkInterpreterLauncher.java
new file mode 100644
index 0000000000..32a0530af1
--- /dev/null
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/launcher/SparkInterpreterLauncher.java
@@ -0,0 +1,205 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.interpreter.launcher;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.zeppelin.conf.ZeppelinConfiguration;
+import org.apache.zeppelin.interpreter.remote.RemoteInterpreterUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * Spark specific launcher.
+ */
+public class SparkInterpreterLauncher extends ShellScriptLauncher {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(SparkInterpreterLauncher.class);
+
+ public SparkInterpreterLauncher(ZeppelinConfiguration zConf) {
+ super(zConf);
+ }
+
+ @Override
+ protected Map buildEnvFromProperties() {
+ Map env = new HashMap();
+ Properties sparkProperties = new Properties();
+ String sparkMaster = getSparkMaster(properties);
+ for (String key : properties.stringPropertyNames()) {
+ if (RemoteInterpreterUtils.isEnvString(key)) {
+ env.put(key, properties.getProperty(key));
+ }
+ if (isSparkConf(key, properties.getProperty(key))) {
+ sparkProperties.setProperty(key, toShellFormat(properties.getProperty(key)));
+ }
+ }
+
+ setupPropertiesForPySpark(sparkProperties);
+ setupPropertiesForSparkR(sparkProperties);
+ if (isYarnMode() && getDeployMode().equals("cluster")) {
+ env.put("ZEPPELIN_SPARK_YARN_CLUSTER", "true");
+ }
+
+ StringBuilder sparkConfBuilder = new StringBuilder();
+ if (sparkMaster != null) {
+ sparkConfBuilder.append(" --master " + sparkMaster);
+ }
+ if (isYarnMode() && getDeployMode().equals("cluster")) {
+ sparkConfBuilder.append(" --files " + zConf.getConfDir() + "/log4j_yarn_cluster.properties");
+ }
+ for (String name : sparkProperties.stringPropertyNames()) {
+ sparkConfBuilder.append(" --conf " + name + "=" + sparkProperties.getProperty(name));
+ }
+
+ env.put("ZEPPELIN_SPARK_CONF", sparkConfBuilder.toString());
+
+ // set these env in the order of
+ // 1. interpreter-setting
+ // 2. zeppelin-env.sh
+ // It is encouraged to set env in interpreter setting, but just for backward compatability,
+ // we also fallback to zeppelin-env.sh if it is not specified in interpreter setting.
+ for (String envName : new String[]{"SPARK_HOME", "SPARK_CONF_DIR", "HADOOP_CONF_DIR"}) {
+ String envValue = getEnv(envName);
+ if (envValue != null) {
+ env.put(envName, envValue);
+ }
+ }
+ LOGGER.debug("buildEnvFromProperties: " + env);
+ return env;
+
+ }
+
+
+ /**
+ * get environmental variable in the following order
+ *
+ * 1. interpreter setting
+ * 2. zeppelin-env.sh
+ *
+ */
+ private String getEnv(String envName) {
+ String env = properties.getProperty(envName);
+ if (env == null) {
+ env = System.getenv(envName);
+ }
+ return env;
+ }
+
+ private boolean isSparkConf(String key, String value) {
+ return !StringUtils.isEmpty(key) && key.startsWith("spark.") && !StringUtils.isEmpty(value);
+ }
+
+ private void setupPropertiesForPySpark(Properties sparkProperties) {
+ if (isYarnMode()) {
+ sparkProperties.setProperty("spark.yarn.isPython", "true");
+ }
+ }
+
+ private void mergeSparkProperty(Properties sparkProperties, String propertyName,
+ String propertyValue) {
+ if (sparkProperties.containsKey(propertyName)) {
+ String oldPropertyValue = sparkProperties.getProperty(propertyName);
+ sparkProperties.setProperty(propertyName, oldPropertyValue + "," + propertyValue);
+ } else {
+ sparkProperties.setProperty(propertyName, propertyValue);
+ }
+ }
+
+ private void setupPropertiesForSparkR(Properties sparkProperties) {
+ String sparkHome = getEnv("SPARK_HOME");
+ File sparkRBasePath = null;
+ if (sparkHome == null) {
+ if (!getSparkMaster(properties).startsWith("local")) {
+ throw new RuntimeException("SPARK_HOME is not specified in interpreter-setting" +
+ " for non-local mode, if you specify it in zeppelin-env.sh, please move that into " +
+ " interpreter setting");
+ }
+ String zeppelinHome = zConf.getString(ZeppelinConfiguration.ConfVars.ZEPPELIN_HOME);
+ sparkRBasePath = new File(zeppelinHome,
+ "interpreter" + File.separator + "spark" + File.separator + "R");
+ } else {
+ sparkRBasePath = new File(sparkHome, "R" + File.separator + "lib");
+ }
+
+ File sparkRPath = new File(sparkRBasePath, "sparkr.zip");
+ if (sparkRPath.exists() && sparkRPath.isFile()) {
+ mergeSparkProperty(sparkProperties, "spark.yarn.dist.archives", sparkRPath.getAbsolutePath());
+ } else {
+ LOGGER.warn("sparkr.zip is not found, SparkR may not work.");
+ }
+ }
+
+ /**
+ * Order to look for spark master
+ * 1. master in interpreter setting
+ * 2. spark.master interpreter setting
+ * 3. use local[*]
+ * @param properties
+ * @return
+ */
+ private String getSparkMaster(Properties properties) {
+ String master = properties.getProperty("master");
+ if (master == null) {
+ master = properties.getProperty("spark.master");
+ if (master == null) {
+ master = "local[*]";
+ }
+ }
+ return master;
+ }
+
+ private String getDeployMode() {
+ String master = getSparkMaster(properties);
+ if (master.equals("yarn-client")) {
+ return "client";
+ } else if (master.equals("yarn-cluster")) {
+ return "cluster";
+ } else if (master.startsWith("local")) {
+ return "client";
+ } else {
+ String deployMode = properties.getProperty("spark.submit.deployMode");
+ if (deployMode == null) {
+ throw new RuntimeException("master is set as yarn, but spark.submit.deployMode " +
+ "is not specified");
+ }
+ if (!deployMode.equals("client") && !deployMode.equals("cluster")) {
+ throw new RuntimeException("Invalid value for spark.submit.deployMode: " + deployMode);
+ }
+ return deployMode;
+ }
+ }
+
+ private boolean isYarnMode() {
+ return getSparkMaster(properties).startsWith("yarn");
+ }
+
+ private String toShellFormat(String value) {
+ if (value.contains("\'") && value.contains("\"")) {
+ throw new RuntimeException("Spark property value could not contain both \" and '");
+ } else if (value.contains("\'")) {
+ return "\"" + value + "\"";
+ } else {
+ return "\'" + value + "\'";
+ }
+ }
+
+}
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/InterpreterContextRunnerPool.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/InterpreterContextRunnerPool.java
index 064abd5370..7653824579 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/InterpreterContextRunnerPool.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/InterpreterContextRunnerPool.java
@@ -82,7 +82,7 @@ public class InterpreterContextRunnerPool {
}
}
- throw new InterpreterException("Can not run paragraph " + paragraphId + " on " + noteId);
+ throw new RuntimeException("Can not run paragraph " + paragraphId + " on " + noteId);
}
}
}
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreter.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreter.java
index 54bf9e12db..b479799e24 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreter.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreter.java
@@ -28,6 +28,7 @@ import org.apache.zeppelin.display.Input;
import org.apache.zeppelin.interpreter.Interpreter;
import org.apache.zeppelin.interpreter.InterpreterContext;
import org.apache.zeppelin.interpreter.InterpreterContextRunner;
+import org.apache.zeppelin.interpreter.InterpreterException;
import org.apache.zeppelin.interpreter.InterpreterResult;
import org.apache.zeppelin.interpreter.ManagedInterpreterGroup;
import org.apache.zeppelin.interpreter.thrift.InterpreterCompletion;
@@ -42,6 +43,7 @@ import org.apache.zeppelin.scheduler.SchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -90,7 +92,7 @@ public class RemoteInterpreter extends Interpreter {
return this.sessionId;
}
- public synchronized RemoteInterpreterProcess getOrCreateInterpreterProcess() {
+ public synchronized RemoteInterpreterProcess getOrCreateInterpreterProcess() throws IOException {
if (this.interpreterProcess != null) {
return this.interpreterProcess;
}
@@ -113,7 +115,7 @@ public class RemoteInterpreter extends Interpreter {
}
@Override
- public void open() {
+ public void open() throws InterpreterException {
synchronized (this) {
if (!isOpened) {
// create all the interpreters of the same session first, then Open the internal interpreter
@@ -123,7 +125,11 @@ public class RemoteInterpreter extends Interpreter {
// also see method Interpreter.getInterpreterInTheSameSessionByClassName
for (Interpreter interpreter : getInterpreterGroup()
.getOrCreateSession(userName, sessionId)) {
- ((RemoteInterpreter) interpreter).internal_create();
+ try {
+ ((RemoteInterpreter) interpreter).internal_create();
+ } catch (IOException e) {
+ throw new InterpreterException(e);
+ }
}
interpreterProcess.callRemoteFunction(new RemoteInterpreterProcess.RemoteFunction() {
@@ -147,7 +153,7 @@ public class RemoteInterpreter extends Interpreter {
}
}
- private void internal_create() {
+ private void internal_create() throws IOException {
synchronized (this) {
if (!isCreated) {
RemoteInterpreterProcess interpreterProcess = getOrCreateInterpreterProcess();
@@ -156,7 +162,7 @@ public class RemoteInterpreter extends Interpreter {
public Void call(Client client) throws Exception {
LOGGER.info("Create RemoteInterpreter {}", getClassName());
client.createInterpreter(getInterpreterGroup().getId(), sessionId,
- className, (Map) property, userName);
+ className, (Map) getProperties(), userName);
return null;
}
});
@@ -167,9 +173,14 @@ public class RemoteInterpreter extends Interpreter {
@Override
- public void close() {
+ public void close() throws InterpreterException {
if (isOpened) {
- RemoteInterpreterProcess interpreterProcess = getOrCreateInterpreterProcess();
+ RemoteInterpreterProcess interpreterProcess = null;
+ try {
+ interpreterProcess = getOrCreateInterpreterProcess();
+ } catch (IOException e) {
+ throw new InterpreterException(e);
+ }
interpreterProcess.callRemoteFunction(new RemoteInterpreterProcess.RemoteFunction() {
@Override
public Void call(Client client) throws Exception {
@@ -184,13 +195,19 @@ public class RemoteInterpreter extends Interpreter {
}
@Override
- public InterpreterResult interpret(final String st, final InterpreterContext context) {
+ public InterpreterResult interpret(final String st, final InterpreterContext context)
+ throws InterpreterException {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("st:\n{}", st);
}
final FormType form = getFormType();
- RemoteInterpreterProcess interpreterProcess = getOrCreateInterpreterProcess();
+ RemoteInterpreterProcess interpreterProcess = null;
+ try {
+ interpreterProcess = getOrCreateInterpreterProcess();
+ } catch (IOException e) {
+ throw new InterpreterException(e);
+ }
InterpreterContextRunnerPool interpreterContextRunnerPool = interpreterProcess
.getInterpreterContextRunnerPool();
List runners = context.getRunners();
@@ -238,12 +255,17 @@ public class RemoteInterpreter extends Interpreter {
}
@Override
- public void cancel(final InterpreterContext context) {
+ public void cancel(final InterpreterContext context) throws InterpreterException {
if (!isOpened) {
LOGGER.warn("Cancel is called when RemoterInterpreter is not opened for " + className);
return;
}
- RemoteInterpreterProcess interpreterProcess = getOrCreateInterpreterProcess();
+ RemoteInterpreterProcess interpreterProcess = null;
+ try {
+ interpreterProcess = getOrCreateInterpreterProcess();
+ } catch (IOException e) {
+ throw new InterpreterException(e);
+ }
interpreterProcess.callRemoteFunction(new RemoteInterpreterProcess.RemoteFunction() {
@Override
public Void call(Client client) throws Exception {
@@ -254,7 +276,7 @@ public class RemoteInterpreter extends Interpreter {
}
@Override
- public FormType getFormType() {
+ public FormType getFormType() throws InterpreterException {
if (formType != null) {
return formType;
}
@@ -265,7 +287,12 @@ public class RemoteInterpreter extends Interpreter {
open();
}
}
- RemoteInterpreterProcess interpreterProcess = getOrCreateInterpreterProcess();
+ RemoteInterpreterProcess interpreterProcess = null;
+ try {
+ interpreterProcess = getOrCreateInterpreterProcess();
+ } catch (IOException e) {
+ throw new InterpreterException(e);
+ }
FormType type = interpreterProcess.callRemoteFunction(
new RemoteInterpreterProcess.RemoteFunction() {
@Override
@@ -277,13 +304,19 @@ public class RemoteInterpreter extends Interpreter {
return type;
}
+
@Override
- public int getProgress(final InterpreterContext context) {
+ public int getProgress(final InterpreterContext context) throws InterpreterException {
if (!isOpened) {
LOGGER.warn("getProgress is called when RemoterInterpreter is not opened for " + className);
return 0;
}
- RemoteInterpreterProcess interpreterProcess = getOrCreateInterpreterProcess();
+ RemoteInterpreterProcess interpreterProcess = null;
+ try {
+ interpreterProcess = getOrCreateInterpreterProcess();
+ } catch (IOException e) {
+ throw new InterpreterException(e);
+ }
return interpreterProcess.callRemoteFunction(
new RemoteInterpreterProcess.RemoteFunction() {
@Override
@@ -296,12 +329,18 @@ public class RemoteInterpreter extends Interpreter {
@Override
public List completion(final String buf, final int cursor,
- final InterpreterContext interpreterContext) {
+ final InterpreterContext interpreterContext)
+ throws InterpreterException {
if (!isOpened) {
LOGGER.warn("completion is called when RemoterInterpreter is not opened for " + className);
return new ArrayList<>();
}
- RemoteInterpreterProcess interpreterProcess = getOrCreateInterpreterProcess();
+ RemoteInterpreterProcess interpreterProcess = null;
+ try {
+ interpreterProcess = getOrCreateInterpreterProcess();
+ } catch (IOException e) {
+ throw new InterpreterException(e);
+ }
return interpreterProcess.callRemoteFunction(
new RemoteInterpreterProcess.RemoteFunction>() {
@Override
@@ -317,7 +356,12 @@ public class RemoteInterpreter extends Interpreter {
LOGGER.warn("getStatus is called when RemoteInterpreter is not opened for " + className);
return Job.Status.UNKNOWN.name();
}
- RemoteInterpreterProcess interpreterProcess = getOrCreateInterpreterProcess();
+ RemoteInterpreterProcess interpreterProcess = null;
+ try {
+ interpreterProcess = getOrCreateInterpreterProcess();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
return interpreterProcess.callRemoteFunction(
new RemoteInterpreterProcess.RemoteFunction() {
@Override
@@ -331,7 +375,7 @@ public class RemoteInterpreter extends Interpreter {
@Override
public Scheduler getScheduler() {
int maxConcurrency = Integer.parseInt(
- property.getProperty("zeppelin.interpreter.max.poolsize",
+ getProperty("zeppelin.interpreter.max.poolsize",
ZeppelinConfiguration.ConfVars.ZEPPELIN_INTERPRETER_MAX_POOL_SIZE.getIntValue() + ""));
Scheduler s = new RemoteScheduler(
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterManagedProcess.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterManagedProcess.java
index d21a9623d0..6e26e58f8d 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterManagedProcess.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterManagedProcess.java
@@ -17,6 +17,7 @@
package org.apache.zeppelin.interpreter.remote;
+import com.google.common.annotations.VisibleForTesting;
import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.ExecuteException;
@@ -73,11 +74,8 @@ public class RemoteInterpreterManagedProcess extends RemoteInterpreterProcess
String localRepoDir,
Map env,
int connectTimeout,
- RemoteInterpreterProcessListener listener,
- ApplicationEventListener appListener,
String interpreterGroupName) {
- super(new RemoteInterpreterEventPoller(listener, appListener),
- connectTimeout);
+ super(connectTimeout);
this.interpreterRunner = intpRunner;
this.portRange = portRange;
this.env = env;
@@ -86,23 +84,6 @@ public class RemoteInterpreterManagedProcess extends RemoteInterpreterProcess
this.interpreterGroupName = interpreterGroupName;
}
- RemoteInterpreterManagedProcess(String intpRunner,
- String intpDir,
- String localRepoDir,
- Map env,
- RemoteInterpreterEventPoller remoteInterpreterEventPoller,
- int connectTimeout,
- String interpreterGroupName) {
- super(remoteInterpreterEventPoller,
- connectTimeout);
- this.interpreterRunner = intpRunner;
- this.portRange = ":";
- this.env = env;
- this.interpreterDir = intpDir;
- this.localRepoDir = localRepoDir;
- this.interpreterGroupName = interpreterGroupName;
- }
-
@Override
public String getHost() {
return "localhost";
@@ -124,7 +105,7 @@ public class RemoteInterpreterManagedProcess extends RemoteInterpreterProcess
callbackHost = RemoteInterpreterUtils.findAvailableHostAddress();
callbackPort = RemoteInterpreterUtils.findRandomAvailablePortOnAllLocalInterfaces();
} catch (IOException e1) {
- throw new InterpreterException(e1);
+ throw new RuntimeException(e1);
}
logger.info("Thrift server for callback will start. Port: {}", callbackPort);
@@ -206,7 +187,7 @@ public class RemoteInterpreterManagedProcess extends RemoteInterpreterProcess
executor.execute(cmdLine, procEnv, this);
} catch (IOException e) {
running.set(false);
- throw new InterpreterException(e);
+ throw new RuntimeException(e);
}
try {
@@ -217,7 +198,7 @@ public class RemoteInterpreterManagedProcess extends RemoteInterpreterProcess
}
if (!running.get()) {
callbackServer.stop();
- throw new InterpreterException("Cannot run interpreter");
+ throw new RuntimeException(new String(cmdOut.toByteArray()));
}
} catch (InterruptedException e) {
logger.error("Remote interpreter is not accessible");
@@ -227,7 +208,7 @@ public class RemoteInterpreterManagedProcess extends RemoteInterpreterProcess
public void stop() {
// shutdown EventPoller first.
- this.remoteInterpreterEventPoller.shutdown();
+ this.getRemoteInterpreterEventPoller().shutdown();
if (callbackServer.isServing()) {
callbackServer.stop();
}
@@ -266,6 +247,31 @@ public class RemoteInterpreterManagedProcess extends RemoteInterpreterProcess
running.set(false);
}
+ @VisibleForTesting
+ public Map getEnv() {
+ return env;
+ }
+
+ @VisibleForTesting
+ public String getLocalRepoDir() {
+ return localRepoDir;
+ }
+
+ @VisibleForTesting
+ public String getInterpreterDir() {
+ return interpreterDir;
+ }
+
+ @VisibleForTesting
+ public String getInterpreterGroupName() {
+ return interpreterGroupName;
+ }
+
+ @VisibleForTesting
+ public String getInterpreterRunner() {
+ return interpreterRunner;
+ }
+
public boolean isRunning() {
return running.get();
}
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterProcess.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterProcess.java
index e45f15b109..88cc4894be 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterProcess.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterProcess.java
@@ -21,6 +21,7 @@ import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.thrift.TException;
import org.apache.zeppelin.helium.ApplicationEventListener;
import org.apache.zeppelin.interpreter.InterpreterException;
+import org.apache.zeppelin.interpreter.launcher.InterpreterClient;
import org.apache.zeppelin.interpreter.thrift.RemoteInterpreterService.Client;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -28,27 +29,17 @@ import org.slf4j.LoggerFactory;
/**
* Abstract class for interpreter process
*/
-public abstract class RemoteInterpreterProcess {
+public abstract class RemoteInterpreterProcess implements InterpreterClient {
private static final Logger logger = LoggerFactory.getLogger(RemoteInterpreterProcess.class);
private GenericObjectPool clientPool;
- protected final RemoteInterpreterEventPoller remoteInterpreterEventPoller;
+ private RemoteInterpreterEventPoller remoteInterpreterEventPoller;
private final InterpreterContextRunnerPool interpreterContextRunnerPool;
private int connectTimeout;
public RemoteInterpreterProcess(
- int connectTimeout,
- RemoteInterpreterProcessListener listener,
- ApplicationEventListener appListener) {
- this(new RemoteInterpreterEventPoller(listener, appListener),
- connectTimeout);
- this.remoteInterpreterEventPoller.setInterpreterProcess(this);
- }
-
- RemoteInterpreterProcess(RemoteInterpreterEventPoller remoteInterpreterEventPoller,
- int connectTimeout) {
+ int connectTimeout) {
this.interpreterContextRunnerPool = new InterpreterContextRunnerPool();
- this.remoteInterpreterEventPoller = remoteInterpreterEventPoller;
this.connectTimeout = connectTimeout;
}
@@ -56,6 +47,10 @@ public abstract class RemoteInterpreterProcess {
return remoteInterpreterEventPoller;
}
+ public void setRemoteInterpreterEventPoller(RemoteInterpreterEventPoller eventPoller) {
+ this.remoteInterpreterEventPoller = eventPoller;
+ }
+
public abstract String getHost();
public abstract int getPort();
public abstract void start(String userName, Boolean isUserImpersonate);
@@ -147,9 +142,9 @@ public abstract class RemoteInterpreterProcess {
}
} catch (TException e) {
broken = true;
- throw new InterpreterException(e);
+ throw new RuntimeException(e);
} catch (Exception e1) {
- throw new InterpreterException(e1);
+ throw new RuntimeException(e1);
} finally {
if (client != null) {
releaseClient(client, broken);
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterRunningProcess.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterRunningProcess.java
index bb176bea59..d8715a0d49 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterRunningProcess.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterRunningProcess.java
@@ -30,12 +30,10 @@ public class RemoteInterpreterRunningProcess extends RemoteInterpreterProcess {
public RemoteInterpreterRunningProcess(
int connectTimeout,
- RemoteInterpreterProcessListener listener,
- ApplicationEventListener appListener,
String host,
int port
) {
- super(connectTimeout, listener, appListener);
+ super(connectTimeout);
this.host = host;
this.port = port;
}
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Note.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Note.java
index 03c50468c5..b5dda67342 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Note.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Note.java
@@ -627,7 +627,7 @@ public class Note implements ParagraphJobListener, JsonSerializable {
if (intp == null) {
String intpExceptionMsg =
p.getJobName() + "'s Interpreter " + requiredReplName + " not found";
- InterpreterException intpException = new InterpreterException(intpExceptionMsg);
+ RuntimeException intpException = new RuntimeException(intpExceptionMsg);
InterpreterResult intpResult =
new InterpreterResult(InterpreterResult.Code.ERROR, intpException.getMessage());
p.setReturn(intpResult, intpException);
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java
index 4652fcd804..77fd04ca7b 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java
@@ -892,7 +892,11 @@ public class Notebook implements NoteEventListener {
if (releaseResource) {
for (InterpreterSetting setting : notebook.getInterpreterSettingManager()
.getInterpreterSettings(note.getId())) {
- notebook.getInterpreterSettingManager().restart(setting.getId());
+ try {
+ notebook.getInterpreterSettingManager().restart(setting.getId());
+ } catch (InterpreterException e) {
+ logger.error("Fail to restart interpreter: " + setting.getId(), e);
+ }
}
}
}
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Paragraph.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Paragraph.java
index 161dc307a5..701943a821 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Paragraph.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Paragraph.java
@@ -26,7 +26,7 @@ import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import java.util.Random;
+import java.security.SecureRandom;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
@@ -139,8 +139,7 @@ public class Paragraph extends Job implements Cloneable, JsonSerializable {
}
private static String generateId() {
- return "paragraph_" + System.currentTimeMillis() + "_" + new Random(System.currentTimeMillis())
- .nextInt();
+ return "paragraph_" + System.currentTimeMillis() + "_" + new SecureRandom().nextInt();
}
public Map getUserParagraphMap() {
@@ -313,15 +312,14 @@ public class Paragraph extends Job implements Cloneable, JsonSerializable {
String replName = getRequiredReplName(trimmedBuffer);
String body = getScriptBody(trimmedBuffer);
- Interpreter repl = getRepl(replName);
- if (repl == null) {
- return null;
- }
-
InterpreterContext interpreterContext = getInterpreterContextWithoutRunner(null);
- List completion = repl.completion(body, cursor, interpreterContext);
- return completion;
+ try {
+ Interpreter repl = getRepl(replName);
+ return repl.completion(body, cursor, interpreterContext);
+ } catch (InterpreterException e) {
+ throw new RuntimeException("Fail to get completion", e);
+ }
}
public int calculateCursorPosition(String buffer, String trimmedBuffer, int cursor) {
@@ -363,11 +361,15 @@ public class Paragraph extends Job implements Cloneable, JsonSerializable {
@Override
public int progress() {
String replName = getRequiredReplName();
- Interpreter repl = getRepl(replName);
- if (repl != null) {
+
+ try {
+ Interpreter repl = getRepl(replName);
+ if (repl == null) {
+ return 0;
+ }
return repl.getProgress(getInterpreterContext(null));
- } else {
- return 0;
+ } catch (InterpreterException e) {
+ throw new RuntimeException("Fail to get progress", e);
}
}
@@ -495,10 +497,8 @@ public class Paragraph extends Job implements Cloneable, JsonSerializable {
protected boolean jobAbort() {
Interpreter repl = getRepl(getRequiredReplName());
if (repl == null) {
- // when interpreters are already destroyed
return true;
}
-
Scheduler scheduler = repl.getScheduler();
if (scheduler == null) {
return true;
@@ -508,7 +508,11 @@ public class Paragraph extends Job implements Cloneable, JsonSerializable {
if (job != null) {
job.setStatus(Status.ABORT);
} else {
- repl.cancel(getInterpreterContextWithoutRunner(null));
+ try {
+ repl.cancel(getInterpreterContextWithoutRunner(null));
+ } catch (InterpreterException e) {
+ throw new RuntimeException(e);
+ }
}
return true;
}
@@ -739,12 +743,7 @@ public class Paragraph extends Job implements Cloneable, JsonSerializable {
}
private boolean isValidInterpreter(String replName) {
- try {
- return factory.getInterpreter(user, note.getId(), replName) != null;
- } catch (InterpreterException e) {
- // ignore this exception, it would be recaught when running paragraph.
- return false;
- }
+ return factory.getInterpreter(user, note.getId(), replName) != null;
}
public void updateRuntimeInfos(String label, String tooltip, Map infos,
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/FileSystemNotebookRepo.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/FileSystemNotebookRepo.java
index 150ac26ce9..ba858e6925 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/FileSystemNotebookRepo.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/FileSystemNotebookRepo.java
@@ -20,7 +20,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
-import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.List;
@@ -50,8 +49,10 @@ public class FileSystemNotebookRepo implements NotebookRepo {
this.isSecurityEnabled = UserGroupInformation.isSecurityEnabled();
if (isSecurityEnabled) {
- String keytab = zConf.getString(ZeppelinConfiguration.ConfVars.ZEPPELIN_HDFS_KEYTAB);
- String principal = zConf.getString(ZeppelinConfiguration.ConfVars.ZEPPELIN_HDFS_PRINCIPAL);
+ String keytab = zConf.getString(
+ ZeppelinConfiguration.ConfVars.ZEPPELIN_SERVER_KERBEROS_KEYTAB);
+ String principal = zConf.getString(
+ ZeppelinConfiguration.ConfVars.ZEPPELIN_SERVER_KERBEROS_PRINCIPAL);
if (StringUtils.isBlank(keytab) || StringUtils.isBlank(principal)) {
throw new IOException("keytab and principal can not be empty, keytab: " + keytab
+ ", principal: " + principal);
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/security/Authentication.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/security/Authentication.java
index fd5142bd48..38d8b5005a 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/security/Authentication.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/security/Authentication.java
@@ -47,7 +47,6 @@ public class Authentication implements Runnable {
// Cipher is an AES in CBC mode
private static final String CIPHER_ALGORITHM = "AES";
private static final String CIPHER_MODE = "AES/CBC/PKCS5PADDING";
- private static final String KEY = "AbtEr99DxsWWbJkP";
private static final int ivSize = 16;
private static final String ZEPPELIN_CONF_ANONYMOUS_ALLOWED = "zeppelin.anonymous.allowed";
@@ -198,7 +197,7 @@ public class Authentication implements Runnable {
private Key generateKey() {
try {
KeyGenerator kgen = KeyGenerator.getInstance(CIPHER_ALGORITHM);
- kgen.init(128, new SecureRandom(toBytes(KEY)));
+ kgen.init(128, new SecureRandom());
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
return new SecretKeySpec(enCodeFormat, CIPHER_ALGORITHM);
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/utility/IdHashes.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/utility/IdHashes.java
index 98aaac8a75..7b0d804de9 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/utility/IdHashes.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/utility/IdHashes.java
@@ -18,9 +18,9 @@
package org.apache.zeppelin.notebook.utility;
import java.math.BigInteger;
+import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
-import java.util.Random;
/**
* Generate Tiny ID.
@@ -71,6 +71,6 @@ public class IdHashes {
}
public static String generateId() {
- return encode(System.currentTimeMillis() + new Random().nextInt());
+ return encode(System.currentTimeMillis() + new SecureRandom().nextInt());
}
}
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumApplicationFactoryTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumApplicationFactoryTest.java
index bf494908a0..f23d43380d 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumApplicationFactoryTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumApplicationFactoryTest.java
@@ -19,6 +19,7 @@ package org.apache.zeppelin.helium;
import org.apache.zeppelin.conf.ZeppelinConfiguration;
import org.apache.zeppelin.interpreter.AbstractInterpreterTest;
import org.apache.zeppelin.interpreter.Interpreter;
+import org.apache.zeppelin.interpreter.InterpreterException;
import org.apache.zeppelin.interpreter.InterpreterResultMessage;
import org.apache.zeppelin.interpreter.InterpreterSetting;
import org.apache.zeppelin.notebook.ApplicationState;
@@ -77,7 +78,7 @@ public class HeliumApplicationFactoryTest extends AbstractInterpreterTest implem
this,
search,
notebookAuthorization,
- new Credentials(false, null));
+ new Credentials(false, null, null));
heliumAppFactory.setNotebook(notebook);
@@ -241,7 +242,7 @@ public class HeliumApplicationFactoryTest extends AbstractInterpreterTest implem
@Test
- public void testUnloadOnInterpreterRestart() throws IOException {
+ public void testUnloadOnInterpreterRestart() throws IOException, InterpreterException {
// given
HeliumPackage pkg1 = new HeliumPackage(HeliumType.APPLICATION,
"name1",
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/EchoInterpreter.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/EchoInterpreter.java
index e7a04f3b5f..cf1713ff1b 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/EchoInterpreter.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/EchoInterpreter.java
@@ -41,7 +41,7 @@ public class EchoInterpreter extends Interpreter {
@Override
public InterpreterResult interpret(String st, InterpreterContext context) {
- if (Boolean.parseBoolean(property.getProperty("zeppelin.interpreter.echo.fail", "false"))) {
+ if (Boolean.parseBoolean(getProperty("zeppelin.interpreter.echo.fail", "false"))) {
return new InterpreterResult(InterpreterResult.Code.ERROR);
} else {
return new InterpreterResult(InterpreterResult.Code.SUCCESS, st);
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterFactoryTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterFactoryTest.java
index f3137d9c89..abbaa3520e 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterFactoryTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterFactoryTest.java
@@ -52,10 +52,10 @@ public class InterpreterFactoryTest extends AbstractInterpreterTest {
assertEquals(DoubleEchoInterpreter.class.getName(), remoteInterpreter.getClassName());
}
- @Test(expected = InterpreterException.class)
+ @Test
public void testUnknownRepl1() throws IOException {
interpreterSettingManager.setInterpreterBinding("user1", "note1", interpreterSettingManager.getSettingIds());
- interpreterFactory.getInterpreter("user1", "note1", "test.unknown_repl");
+ assertNull(interpreterFactory.getInterpreter("user1", "note1", "test.unknown_repl"));
}
@Test
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterSettingManagerTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterSettingManagerTest.java
index 0bcdb6fd5a..605476fe32 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterSettingManagerTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterSettingManagerTest.java
@@ -96,7 +96,7 @@ public class InterpreterSettingManagerTest extends AbstractInterpreterTest {
}
@Test
- public void testCreateUpdateRemoveSetting() throws IOException {
+ public void testCreateUpdateRemoveSetting() throws IOException, InterpreterException {
// create new interpreter setting
InterpreterOption option = new InterpreterOption();
option.setPerNote("scoped");
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterSettingTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterSettingTest.java
index 3c061a99a4..e3e47d3b5c 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterSettingTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterSettingTest.java
@@ -32,7 +32,6 @@ public class InterpreterSettingTest {
public void testCreateInterpreters() {
InterpreterOption interpreterOption = new InterpreterOption();
interpreterOption.setPerUser(InterpreterOption.SHARED);
- interpreterOption.setRemote(false);
InterpreterInfo interpreterInfo1 = new InterpreterInfo(EchoInterpreter.class.getName(), "echo", true, new HashMap());
InterpreterInfo interpreterInfo2 = new InterpreterInfo(DoubleEchoInterpreter.class.getName(), "double_echo", false, new HashMap());
List interpreterInfos = new ArrayList<>();
@@ -64,7 +63,6 @@ public class InterpreterSettingTest {
public void testSharedMode() {
InterpreterOption interpreterOption = new InterpreterOption();
interpreterOption.setPerUser(InterpreterOption.SHARED);
- interpreterOption.setRemote(false);
InterpreterInfo interpreterInfo1 = new InterpreterInfo(EchoInterpreter.class.getName(), "echo", true, new HashMap());
InterpreterInfo interpreterInfo2 = new InterpreterInfo(DoubleEchoInterpreter.class.getName(), "double_echo", false, new HashMap());
List interpreterInfos = new ArrayList<>();
@@ -101,7 +99,6 @@ public class InterpreterSettingTest {
public void testPerUserScopedMode() {
InterpreterOption interpreterOption = new InterpreterOption();
interpreterOption.setPerUser(InterpreterOption.SCOPED);
- interpreterOption.setRemote(true);
InterpreterInfo interpreterInfo1 = new InterpreterInfo(EchoInterpreter.class.getName(), "echo", true, new HashMap());
InterpreterInfo interpreterInfo2 = new InterpreterInfo(DoubleEchoInterpreter.class.getName(), "double_echo", false, new HashMap());
List interpreterInfos = new ArrayList<>();
@@ -138,7 +135,6 @@ public class InterpreterSettingTest {
public void testPerNoteScopedMode() {
InterpreterOption interpreterOption = new InterpreterOption();
interpreterOption.setPerNote(InterpreterOption.SCOPED);
- interpreterOption.setRemote(true);
InterpreterInfo interpreterInfo1 = new InterpreterInfo(EchoInterpreter.class.getName(), "echo", true, new HashMap());
InterpreterInfo interpreterInfo2 = new InterpreterInfo(DoubleEchoInterpreter.class.getName(), "double_echo", false, new HashMap());
List interpreterInfos = new ArrayList<>();
@@ -175,7 +171,6 @@ public class InterpreterSettingTest {
public void testPerUserIsolatedMode() {
InterpreterOption interpreterOption = new InterpreterOption();
interpreterOption.setPerUser(InterpreterOption.ISOLATED);
- interpreterOption.setRemote(true);
InterpreterInfo interpreterInfo1 = new InterpreterInfo(EchoInterpreter.class.getName(), "echo", true, new HashMap());
InterpreterInfo interpreterInfo2 = new InterpreterInfo(DoubleEchoInterpreter.class.getName(), "double_echo", false, new HashMap());
List interpreterInfos = new ArrayList<>();
@@ -212,7 +207,6 @@ public class InterpreterSettingTest {
public void testPerNoteIsolatedMode() {
InterpreterOption interpreterOption = new InterpreterOption();
interpreterOption.setPerNote(InterpreterOption.ISOLATED);
- interpreterOption.setRemote(true);
InterpreterInfo interpreterInfo1 = new InterpreterInfo(EchoInterpreter.class.getName(), "echo", true, new HashMap());
InterpreterInfo interpreterInfo2 = new InterpreterInfo(DoubleEchoInterpreter.class.getName(), "double_echo", false, new HashMap());
List interpreterInfos = new ArrayList<>();
@@ -249,7 +243,6 @@ public class InterpreterSettingTest {
InterpreterOption interpreterOption = new InterpreterOption();
interpreterOption.setPerUser(InterpreterOption.ISOLATED);
interpreterOption.setPerNote(InterpreterOption.SCOPED);
- interpreterOption.setRemote(true);
InterpreterInfo interpreterInfo1 = new InterpreterInfo(EchoInterpreter.class.getName(), "echo", true, new HashMap());
InterpreterInfo interpreterInfo2 = new InterpreterInfo(DoubleEchoInterpreter.class.getName(), "double_echo", false, new HashMap());
List interpreterInfos = new ArrayList<>();
@@ -301,7 +294,6 @@ public class InterpreterSettingTest {
InterpreterOption interpreterOption = new InterpreterOption();
interpreterOption.setPerUser(InterpreterOption.ISOLATED);
interpreterOption.setPerNote(InterpreterOption.ISOLATED);
- interpreterOption.setRemote(true);
InterpreterInfo interpreterInfo1 = new InterpreterInfo(EchoInterpreter.class.getName(), "echo", true, new HashMap());
InterpreterInfo interpreterInfo2 = new InterpreterInfo(DoubleEchoInterpreter.class.getName(), "double_echo", false, new HashMap());
List interpreterInfos = new ArrayList<>();
@@ -358,7 +350,6 @@ public class InterpreterSettingTest {
InterpreterOption interpreterOption = new InterpreterOption();
interpreterOption.setPerUser(InterpreterOption.SCOPED);
interpreterOption.setPerNote(InterpreterOption.SCOPED);
- interpreterOption.setRemote(true);
InterpreterInfo interpreterInfo1 = new InterpreterInfo(EchoInterpreter.class.getName(), "echo", true, new HashMap());
InterpreterInfo interpreterInfo2 = new InterpreterInfo(DoubleEchoInterpreter.class.getName(), "double_echo", false, new HashMap());
List interpreterInfos = new ArrayList<>();
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/ManagedInterpreterGroupTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/ManagedInterpreterGroupTest.java
index a5d7bd4359..74bd201085 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/ManagedInterpreterGroupTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/ManagedInterpreterGroupTest.java
@@ -41,7 +41,6 @@ public class ManagedInterpreterGroupTest {
public void setUp() throws IOException, RepositoryException {
InterpreterOption interpreterOption = new InterpreterOption();
interpreterOption.setPerUser(InterpreterOption.SCOPED);
- interpreterOption.setRemote(false);
InterpreterInfo interpreterInfo1 = new InterpreterInfo(EchoInterpreter.class.getName(), "echo", true, new HashMap());
InterpreterInfo interpreterInfo2 = new InterpreterInfo(DoubleEchoInterpreter.class.getName(), "double_echo", false, new HashMap());
List interpreterInfos = new ArrayList<>();
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/SleepInterpreter.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/SleepInterpreter.java
index 9deafcfa00..7a904c6bfb 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/SleepInterpreter.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/SleepInterpreter.java
@@ -46,7 +46,7 @@ public class SleepInterpreter extends Interpreter {
@Override
public Scheduler getScheduler() {
- if (Boolean.parseBoolean(property.getProperty("zeppelin.SleepInterpreter.parallel", "false"))) {
+ if (Boolean.parseBoolean(getProperty("zeppelin.SleepInterpreter.parallel", "false"))) {
return SchedulerFactory.singleton().createOrGetParallelScheduler(
"Parallel-" + SleepInterpreter.class.getName(), 10);
}
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/SparkInterpreterModeTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/SparkInterpreterModeTest.java
index 24a9aeed22..930a26d9b6 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/SparkInterpreterModeTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/SparkInterpreterModeTest.java
@@ -44,7 +44,7 @@ public class SparkInterpreterModeTest {
}
}
- private void testInterpreterBasics() throws IOException {
+ private void testInterpreterBasics() throws IOException, InterpreterException {
// test SparkInterpreter
interpreterSettingManager.setInterpreterBinding("user1", "note1", interpreterSettingManager.getInterpreterSettingIds());
Interpreter sparkInterpreter = interpreterFactory.getInterpreter("user1", "note1", "spark.spark");
@@ -75,7 +75,7 @@ public class SparkInterpreterModeTest {
}
@Test
- public void testLocalMode() throws IOException, YarnException {
+ public void testLocalMode() throws IOException, YarnException, InterpreterException {
InterpreterSetting sparkInterpreterSetting = interpreterSettingManager.getInterpreterSettingByName("spark");
sparkInterpreterSetting.setProperty("master", "local[*]");
sparkInterpreterSetting.setProperty("SPARK_HOME", System.getenv("SPARK_HOME"));
@@ -94,7 +94,7 @@ public class SparkInterpreterModeTest {
}
@Test
- public void testYarnClientMode() throws IOException, YarnException, InterruptedException {
+ public void testYarnClientMode() throws IOException, YarnException, InterruptedException, InterpreterException {
InterpreterSetting sparkInterpreterSetting = interpreterSettingManager.getInterpreterSettingByName("spark");
sparkInterpreterSetting.setProperty("master", "yarn-client");
sparkInterpreterSetting.setProperty("HADOOP_CONF_DIR", hadoopCluster.getConfigPath());
@@ -116,7 +116,7 @@ public class SparkInterpreterModeTest {
}
@Test
- public void testYarnClusterMode() throws IOException, YarnException, InterruptedException {
+ public void testYarnClusterMode() throws IOException, YarnException, InterruptedException, InterpreterException {
InterpreterSetting sparkInterpreterSetting = interpreterSettingManager.getInterpreterSettingByName("spark");
sparkInterpreterSetting.setProperty("master", "yarn-cluster");
sparkInterpreterSetting.setProperty("HADOOP_CONF_DIR", hadoopCluster.getConfigPath());
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/launcher/ShellScriptLauncherTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/launcher/ShellScriptLauncherTest.java
new file mode 100644
index 0000000000..9708ee7d56
--- /dev/null
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/launcher/ShellScriptLauncherTest.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.interpreter.launcher;
+
+import org.apache.zeppelin.conf.ZeppelinConfiguration;
+import org.apache.zeppelin.interpreter.InterpreterContext;
+import org.apache.zeppelin.interpreter.InterpreterOption;
+import org.apache.zeppelin.interpreter.remote.RemoteInterpreterManagedProcess;
+import org.apache.zeppelin.interpreter.remote.RemoteInterpreterProcess;
+import org.junit.Test;
+
+import java.util.Properties;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class ShellScriptLauncherTest {
+
+ @Test
+ public void testLauncher() {
+ ZeppelinConfiguration zConf = new ZeppelinConfiguration();
+ ShellScriptLauncher launcher = new ShellScriptLauncher(zConf);
+ Properties properties = new Properties();
+ properties.setProperty("ENV_1", "VALUE_1");
+ properties.setProperty("property_1", "value_1");
+ InterpreterOption option = new InterpreterOption();
+ InterpreterLaunchContext context = new InterpreterLaunchContext(properties, option, null, "groupId", "groupName");
+ InterpreterClient client = launcher.launch(context);
+ assertTrue( client instanceof RemoteInterpreterManagedProcess);
+ RemoteInterpreterManagedProcess interpreterProcess = (RemoteInterpreterManagedProcess) client;
+ assertEquals("groupName", interpreterProcess.getInterpreterGroupName());
+ assertEquals(".//interpreter/groupName", interpreterProcess.getInterpreterDir());
+ assertEquals(".//local-repo/groupId", interpreterProcess.getLocalRepoDir());
+ assertEquals(zConf.getInterpreterRemoteRunnerPath(), interpreterProcess.getInterpreterRunner());
+ assertEquals(1, interpreterProcess.getEnv().size());
+ assertEquals("VALUE_1", interpreterProcess.getEnv().get("ENV_1"));
+ }
+
+}
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/launcher/SparkInterpreterLauncherTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/launcher/SparkInterpreterLauncherTest.java
new file mode 100644
index 0000000000..45e009f719
--- /dev/null
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/launcher/SparkInterpreterLauncherTest.java
@@ -0,0 +1,160 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.interpreter.launcher;
+
+import org.apache.zeppelin.conf.ZeppelinConfiguration;
+import org.apache.zeppelin.interpreter.InterpreterOption;
+import org.apache.zeppelin.interpreter.remote.RemoteInterpreterManagedProcess;
+import org.junit.Test;
+
+import java.util.Properties;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class SparkInterpreterLauncherTest {
+
+ @Test
+ public void testLocalMode() {
+ ZeppelinConfiguration zConf = new ZeppelinConfiguration();
+ SparkInterpreterLauncher launcher = new SparkInterpreterLauncher(zConf);
+ Properties properties = new Properties();
+ properties.setProperty("SPARK_HOME", "/user/spark");
+ properties.setProperty("property_1", "value_1");
+ properties.setProperty("master", "local[*]");
+ properties.setProperty("spark.files", "file_1");
+ properties.setProperty("spark.jars", "jar_1");
+
+ InterpreterOption option = new InterpreterOption();
+ InterpreterLaunchContext context = new InterpreterLaunchContext(properties, option, null, "groupId", "spark");
+ InterpreterClient client = launcher.launch(context);
+ assertTrue( client instanceof RemoteInterpreterManagedProcess);
+ RemoteInterpreterManagedProcess interpreterProcess = (RemoteInterpreterManagedProcess) client;
+ assertEquals("spark", interpreterProcess.getInterpreterGroupName());
+ assertEquals(".//interpreter/spark", interpreterProcess.getInterpreterDir());
+ assertEquals(".//local-repo/groupId", interpreterProcess.getLocalRepoDir());
+ assertEquals(zConf.getInterpreterRemoteRunnerPath(), interpreterProcess.getInterpreterRunner());
+ assertEquals(2, interpreterProcess.getEnv().size());
+ assertEquals("/user/spark", interpreterProcess.getEnv().get("SPARK_HOME"));
+ assertEquals(" --master local[*] --conf spark.files='file_1' --conf spark.jars='jar_1'", interpreterProcess.getEnv().get("ZEPPELIN_SPARK_CONF"));
+ }
+
+ @Test
+ public void testYarnClientMode_1() {
+ ZeppelinConfiguration zConf = new ZeppelinConfiguration();
+ SparkInterpreterLauncher launcher = new SparkInterpreterLauncher(zConf);
+ Properties properties = new Properties();
+ properties.setProperty("SPARK_HOME", "/user/spark");
+ properties.setProperty("property_1", "value_1");
+ properties.setProperty("master", "yarn-client");
+ properties.setProperty("spark.files", "file_1");
+ properties.setProperty("spark.jars", "jar_1");
+
+ InterpreterOption option = new InterpreterOption();
+ InterpreterLaunchContext context = new InterpreterLaunchContext(properties, option, null, "groupId", "spark");
+ InterpreterClient client = launcher.launch(context);
+ assertTrue( client instanceof RemoteInterpreterManagedProcess);
+ RemoteInterpreterManagedProcess interpreterProcess = (RemoteInterpreterManagedProcess) client;
+ assertEquals("spark", interpreterProcess.getInterpreterGroupName());
+ assertEquals(".//interpreter/spark", interpreterProcess.getInterpreterDir());
+ assertEquals(".//local-repo/groupId", interpreterProcess.getLocalRepoDir());
+ assertEquals(zConf.getInterpreterRemoteRunnerPath(), interpreterProcess.getInterpreterRunner());
+ assertEquals(2, interpreterProcess.getEnv().size());
+ assertEquals("/user/spark", interpreterProcess.getEnv().get("SPARK_HOME"));
+ assertEquals(" --master yarn-client --conf spark.files='file_1' --conf spark.jars='jar_1' --conf spark.yarn.isPython=true", interpreterProcess.getEnv().get("ZEPPELIN_SPARK_CONF"));
+ }
+
+ @Test
+ public void testYarnClientMode_2() {
+ ZeppelinConfiguration zConf = new ZeppelinConfiguration();
+ SparkInterpreterLauncher launcher = new SparkInterpreterLauncher(zConf);
+ Properties properties = new Properties();
+ properties.setProperty("SPARK_HOME", "/user/spark");
+ properties.setProperty("property_1", "value_1");
+ properties.setProperty("master", "yarn");
+ properties.setProperty("spark.submit.deployMode", "client");
+ properties.setProperty("spark.files", "file_1");
+ properties.setProperty("spark.jars", "jar_1");
+
+ InterpreterOption option = new InterpreterOption();
+ InterpreterLaunchContext context = new InterpreterLaunchContext(properties, option, null, "groupId", "spark");
+ InterpreterClient client = launcher.launch(context);
+ assertTrue( client instanceof RemoteInterpreterManagedProcess);
+ RemoteInterpreterManagedProcess interpreterProcess = (RemoteInterpreterManagedProcess) client;
+ assertEquals("spark", interpreterProcess.getInterpreterGroupName());
+ assertEquals(".//interpreter/spark", interpreterProcess.getInterpreterDir());
+ assertEquals(".//local-repo/groupId", interpreterProcess.getLocalRepoDir());
+ assertEquals(zConf.getInterpreterRemoteRunnerPath(), interpreterProcess.getInterpreterRunner());
+ assertEquals(2, interpreterProcess.getEnv().size());
+ assertEquals("/user/spark", interpreterProcess.getEnv().get("SPARK_HOME"));
+ assertEquals(" --master yarn --conf spark.files='file_1' --conf spark.jars='jar_1' --conf spark.submit.deployMode='client' --conf spark.yarn.isPython=true", interpreterProcess.getEnv().get("ZEPPELIN_SPARK_CONF"));
+ }
+
+ @Test
+ public void testYarnClusterMode_1() {
+ ZeppelinConfiguration zConf = new ZeppelinConfiguration();
+ SparkInterpreterLauncher launcher = new SparkInterpreterLauncher(zConf);
+ Properties properties = new Properties();
+ properties.setProperty("SPARK_HOME", "/user/spark");
+ properties.setProperty("property_1", "value_1");
+ properties.setProperty("master", "yarn-cluster");
+ properties.setProperty("spark.files", "file_1");
+ properties.setProperty("spark.jars", "jar_1");
+
+ InterpreterOption option = new InterpreterOption();
+ InterpreterLaunchContext context = new InterpreterLaunchContext(properties, option, null, "groupId", "spark");
+ InterpreterClient client = launcher.launch(context);
+ assertTrue( client instanceof RemoteInterpreterManagedProcess);
+ RemoteInterpreterManagedProcess interpreterProcess = (RemoteInterpreterManagedProcess) client;
+ assertEquals("spark", interpreterProcess.getInterpreterGroupName());
+ assertEquals(".//interpreter/spark", interpreterProcess.getInterpreterDir());
+ assertEquals(".//local-repo/groupId", interpreterProcess.getLocalRepoDir());
+ assertEquals(zConf.getInterpreterRemoteRunnerPath(), interpreterProcess.getInterpreterRunner());
+ assertEquals(3, interpreterProcess.getEnv().size());
+ assertEquals("/user/spark", interpreterProcess.getEnv().get("SPARK_HOME"));
+ assertEquals("true", interpreterProcess.getEnv().get("ZEPPELIN_SPARK_YARN_CLUSTER"));
+ assertEquals(" --master yarn-cluster --files .//conf/log4j_yarn_cluster.properties --conf spark.files='file_1' --conf spark.jars='jar_1' --conf spark.yarn.isPython=true", interpreterProcess.getEnv().get("ZEPPELIN_SPARK_CONF"));
+ }
+
+ @Test
+ public void testYarnClusterMode_2() {
+ ZeppelinConfiguration zConf = new ZeppelinConfiguration();
+ SparkInterpreterLauncher launcher = new SparkInterpreterLauncher(zConf);
+ Properties properties = new Properties();
+ properties.setProperty("SPARK_HOME", "/user/spark");
+ properties.setProperty("property_1", "value_1");
+ properties.setProperty("master", "yarn");
+ properties.setProperty("spark.submit.deployMode", "cluster");
+ properties.setProperty("spark.files", "file_1");
+ properties.setProperty("spark.jars", "jar_1");
+
+ InterpreterOption option = new InterpreterOption();
+ InterpreterLaunchContext context = new InterpreterLaunchContext(properties, option, null, "groupId", "spark");
+ InterpreterClient client = launcher.launch(context);
+ assertTrue( client instanceof RemoteInterpreterManagedProcess);
+ RemoteInterpreterManagedProcess interpreterProcess = (RemoteInterpreterManagedProcess) client;
+ assertEquals("spark", interpreterProcess.getInterpreterGroupName());
+ assertEquals(".//interpreter/spark", interpreterProcess.getInterpreterDir());
+ assertEquals(".//local-repo/groupId", interpreterProcess.getLocalRepoDir());
+ assertEquals(zConf.getInterpreterRemoteRunnerPath(), interpreterProcess.getInterpreterRunner());
+ assertEquals(3, interpreterProcess.getEnv().size());
+ assertEquals("/user/spark", interpreterProcess.getEnv().get("SPARK_HOME"));
+ assertEquals("true", interpreterProcess.getEnv().get("ZEPPELIN_SPARK_YARN_CLUSTER"));
+ assertEquals(" --master yarn --files .//conf/log4j_yarn_cluster.properties --conf spark.files='file_1' --conf spark.jars='jar_1' --conf spark.submit.deployMode='cluster' --conf spark.yarn.isPython=true", interpreterProcess.getEnv().get("ZEPPELIN_SPARK_CONF"));
+ }
+}
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteAngularObjectTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteAngularObjectTest.java
index 61e4ef06c0..54814c45ec 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteAngularObjectTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteAngularObjectTest.java
@@ -60,7 +60,6 @@ public class RemoteAngularObjectTest implements AngularObjectRegistryListener {
onRemove = new AtomicInteger(0);
InterpreterOption interpreterOption = new InterpreterOption();
- interpreterOption.setRemote(true);
InterpreterInfo interpreterInfo1 = new InterpreterInfo(MockInterpreterAngular.class.getName(), "mock", true, new HashMap());
List interpreterInfos = new ArrayList<>();
interpreterInfos.add(interpreterInfo1);
@@ -101,7 +100,7 @@ public class RemoteAngularObjectTest implements AngularObjectRegistryListener {
}
@Test
- public void testAngularObjectInterpreterSideCRUD() throws InterruptedException {
+ public void testAngularObjectInterpreterSideCRUD() throws InterruptedException, InterpreterException {
InterpreterResult ret = intp.interpret("get", context);
Thread.sleep(500); // waitFor eventpoller pool event
String[] result = ret.message().get(0).getData().split(" ");
@@ -134,7 +133,7 @@ public class RemoteAngularObjectTest implements AngularObjectRegistryListener {
}
@Test
- public void testAngularObjectRemovalOnZeppelinServerSide() throws InterruptedException {
+ public void testAngularObjectRemovalOnZeppelinServerSide() throws InterruptedException, InterpreterException {
// test if angularobject removal from server side propagate to interpreter process's registry.
// will happen when notebook is removed.
@@ -159,7 +158,7 @@ public class RemoteAngularObjectTest implements AngularObjectRegistryListener {
}
@Test
- public void testAngularObjectAddOnZeppelinServerSide() throws InterruptedException {
+ public void testAngularObjectAddOnZeppelinServerSide() throws InterruptedException, InterpreterException {
// test if angularobject add from server side propagate to interpreter process's registry.
// will happen when zeppelin server loads notebook and restore the object into registry
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterOutputTestStream.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterOutputTestStream.java
index 1687060d6d..f52803d2dc 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterOutputTestStream.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterOutputTestStream.java
@@ -46,7 +46,6 @@ public class RemoteInterpreterOutputTestStream implements RemoteInterpreterProce
public void setUp() throws Exception {
InterpreterOption interpreterOption = new InterpreterOption();
- interpreterOption.setRemote(true);
InterpreterInfo interpreterInfo1 = new InterpreterInfo(MockInterpreterOutputStream.class.getName(), "mock", true, new HashMap());
List interpreterInfos = new ArrayList<>();
interpreterInfos.add(interpreterInfo1);
@@ -83,7 +82,7 @@ public class RemoteInterpreterOutputTestStream implements RemoteInterpreterProce
}
@Test
- public void testInterpreterResultOnly() {
+ public void testInterpreterResultOnly() throws InterpreterException {
RemoteInterpreter intp = (RemoteInterpreter) interpreterSetting.getDefaultInterpreter("user1", "note1");
InterpreterResult ret = intp.interpret("SUCCESS::staticresult", createInterpreterContext());
assertEquals(InterpreterResult.Code.SUCCESS, ret.code());
@@ -99,7 +98,7 @@ public class RemoteInterpreterOutputTestStream implements RemoteInterpreterProce
}
@Test
- public void testInterpreterOutputStreamOnly() {
+ public void testInterpreterOutputStreamOnly() throws InterpreterException {
RemoteInterpreter intp = (RemoteInterpreter) interpreterSetting.getDefaultInterpreter("user1", "note1");
InterpreterResult ret = intp.interpret("SUCCESS:streamresult:", createInterpreterContext());
assertEquals(InterpreterResult.Code.SUCCESS, ret.code());
@@ -111,7 +110,7 @@ public class RemoteInterpreterOutputTestStream implements RemoteInterpreterProce
}
@Test
- public void testInterpreterResultOutputStreamMixed() {
+ public void testInterpreterResultOutputStreamMixed() throws InterpreterException {
RemoteInterpreter intp = (RemoteInterpreter) interpreterSetting.getDefaultInterpreter("user1", "note1");
InterpreterResult ret = intp.interpret("SUCCESS:stream:static", createInterpreterContext());
assertEquals(InterpreterResult.Code.SUCCESS, ret.code());
@@ -120,7 +119,7 @@ public class RemoteInterpreterOutputTestStream implements RemoteInterpreterProce
}
@Test
- public void testOutputType() {
+ public void testOutputType() throws InterpreterException {
RemoteInterpreter intp = (RemoteInterpreter) interpreterSetting.getDefaultInterpreter("user1", "note1");
InterpreterResult ret = intp.interpret("SUCCESS:%html hello:", createInterpreterContext());
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterTest.java
index 0a5e484979..74bde89dfa 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterTest.java
@@ -52,7 +52,6 @@ public class RemoteInterpreterTest {
public void setUp() throws Exception {
InterpreterOption interpreterOption = new InterpreterOption();
- interpreterOption.setRemote(true);
InterpreterInfo interpreterInfo1 = new InterpreterInfo(EchoInterpreter.class.getName(), "echo", true, new HashMap());
InterpreterInfo interpreterInfo2 = new InterpreterInfo(DoubleEchoInterpreter.class.getName(), "double_echo", false, new HashMap());
InterpreterInfo interpreterInfo3 = new InterpreterInfo(SleepInterpreter.class.getName(), "sleep", false, new HashMap());
@@ -82,7 +81,7 @@ public class RemoteInterpreterTest {
}
@Test
- public void testSharedMode() {
+ public void testSharedMode() throws InterpreterException, IOException {
interpreterSetting.getOption().setPerUser(InterpreterOption.SHARED);
Interpreter interpreter1 = interpreterSetting.getDefaultInterpreter("user1", "note1");
@@ -125,7 +124,7 @@ public class RemoteInterpreterTest {
}
@Test
- public void testScopedMode() {
+ public void testScopedMode() throws InterpreterException, IOException {
interpreterSetting.getOption().setPerUser(InterpreterOption.SCOPED);
Interpreter interpreter1 = interpreterSetting.getDefaultInterpreter("user1", "note1");
@@ -171,7 +170,7 @@ public class RemoteInterpreterTest {
}
@Test
- public void testIsolatedMode() {
+ public void testIsolatedMode() throws InterpreterException, IOException {
interpreterSetting.getOption().setPerUser(InterpreterOption.ISOLATED);
Interpreter interpreter1 = interpreterSetting.getDefaultInterpreter("user1", "note1");
@@ -218,7 +217,7 @@ public class RemoteInterpreterTest {
}
@Test
- public void testExecuteIncorrectPrecode() throws TTransportException, IOException {
+ public void testExecuteIncorrectPrecode() throws TTransportException, IOException, InterpreterException {
interpreterSetting.getOption().setPerUser(InterpreterOption.SHARED);
interpreterSetting.setProperty("zeppelin.SleepInterpreter.precode", "fail test");
Interpreter interpreter1 = interpreterSetting.getInterpreter("user1", "note1", "sleep");
@@ -229,7 +228,7 @@ public class RemoteInterpreterTest {
}
@Test
- public void testExecuteCorrectPrecode() throws TTransportException, IOException {
+ public void testExecuteCorrectPrecode() throws TTransportException, IOException, InterpreterException {
interpreterSetting.getOption().setPerUser(InterpreterOption.SHARED);
interpreterSetting.setProperty("zeppelin.SleepInterpreter.precode", "1");
Interpreter interpreter1 = interpreterSetting.getInterpreter("user1", "note1", "sleep");
@@ -240,7 +239,7 @@ public class RemoteInterpreterTest {
}
@Test
- public void testRemoteInterperterErrorStatus() throws TTransportException, IOException {
+ public void testRemoteInterperterErrorStatus() throws TTransportException, IOException, InterpreterException {
interpreterSetting.setProperty("zeppelin.interpreter.echo.fail", "true");
interpreterSetting.getOption().setPerUser(InterpreterOption.SHARED);
@@ -255,7 +254,7 @@ public class RemoteInterpreterTest {
}
@Test
- public void testFIFOScheduler() throws InterruptedException {
+ public void testFIFOScheduler() throws InterruptedException, InterpreterException {
interpreterSetting.getOption().setPerUser(InterpreterOption.SHARED);
// by default SleepInterpreter would use FIFOScheduler
@@ -269,13 +268,23 @@ public class RemoteInterpreterTest {
Thread thread1 = new Thread() {
@Override
public void run() {
- assertEquals(Code.SUCCESS, interpreter1.interpret("100", context1).code());
+ try {
+ assertEquals(Code.SUCCESS, interpreter1.interpret("100", context1).code());
+ } catch (InterpreterException e) {
+ e.printStackTrace();
+ fail();
+ }
}
};
Thread thread2 = new Thread() {
@Override
public void run() {
- assertEquals(Code.SUCCESS, interpreter1.interpret("100", context1).code());
+ try {
+ assertEquals(Code.SUCCESS, interpreter1.interpret("100", context1).code());
+ } catch (InterpreterException e) {
+ e.printStackTrace();
+ fail();
+ }
}
};
long start = System.currentTimeMillis();
@@ -288,7 +297,7 @@ public class RemoteInterpreterTest {
}
@Test
- public void testParallelScheduler() throws InterruptedException {
+ public void testParallelScheduler() throws InterruptedException, InterpreterException {
interpreterSetting.getOption().setPerUser(InterpreterOption.SHARED);
interpreterSetting.setProperty("zeppelin.SleepInterpreter.parallel", "true");
@@ -303,13 +312,23 @@ public class RemoteInterpreterTest {
Thread thread1 = new Thread() {
@Override
public void run() {
- assertEquals(Code.SUCCESS, interpreter1.interpret("100", context1).code());
+ try {
+ assertEquals(Code.SUCCESS, interpreter1.interpret("100", context1).code());
+ } catch (InterpreterException e) {
+ e.printStackTrace();
+ fail();
+ }
}
};
Thread thread2 = new Thread() {
@Override
public void run() {
- assertEquals(Code.SUCCESS, interpreter1.interpret("100", context1).code());
+ try {
+ assertEquals(Code.SUCCESS, interpreter1.interpret("100", context1).code());
+ } catch (InterpreterException e) {
+ e.printStackTrace();
+ fail();
+ }
}
};
long start = System.currentTimeMillis();
@@ -377,7 +396,7 @@ public class RemoteInterpreterTest {
}
@Test
- public void testEnvironmentAndProperty() {
+ public void testEnvironmentAndProperty() throws InterpreterException {
interpreterSetting.getOption().setPerUser(InterpreterOption.SHARED);
interpreterSetting.setProperty("ENV_1", "VALUE_1");
interpreterSetting.setProperty("property_1", "value_1");
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/mock/MockInterpreterA.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/mock/MockInterpreterA.java
index 5a3e57c06f..dbd2df77f5 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/mock/MockInterpreterA.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/mock/MockInterpreterA.java
@@ -51,8 +51,9 @@ public class MockInterpreterA extends Interpreter {
}
@Override
- public InterpreterResult interpret(String st, InterpreterContext context) {
- if (property.containsKey("progress")) {
+ public InterpreterResult interpret(String st, InterpreterContext context)
+ throws InterpreterException {
+ if (getProperties().containsKey("progress")) {
context.setProgress(Integer.parseInt(getProperty("progress")));
}
try {
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/mock/MockInterpreterOutputStream.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/mock/MockInterpreterOutputStream.java
index 1890cbc94e..7a5321ae3a 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/mock/MockInterpreterOutputStream.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/remote/mock/MockInterpreterOutputStream.java
@@ -52,7 +52,8 @@ public class MockInterpreterOutputStream extends Interpreter {
}
@Override
- public InterpreterResult interpret(String st, InterpreterContext context) {
+ public InterpreterResult interpret(String st, InterpreterContext context)
+ throws InterpreterException {
String[] ret = st.split(":");
try {
if (ret[1] != null) {
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NotebookTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NotebookTest.java
index f044fbda5d..a1621e86ee 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NotebookTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NotebookTest.java
@@ -23,8 +23,6 @@ import org.apache.zeppelin.conf.ZeppelinConfiguration;
import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars;
import org.apache.zeppelin.display.AngularObjectRegistry;
import org.apache.zeppelin.interpreter.AbstractInterpreterTest;
-import org.apache.zeppelin.interpreter.ClassloaderInterpreter;
-import org.apache.zeppelin.interpreter.Interpreter;
import org.apache.zeppelin.interpreter.InterpreterException;
import org.apache.zeppelin.interpreter.InterpreterFactory;
import org.apache.zeppelin.interpreter.InterpreterGroup;
@@ -32,9 +30,6 @@ import org.apache.zeppelin.interpreter.InterpreterOption;
import org.apache.zeppelin.interpreter.InterpreterResult;
import org.apache.zeppelin.interpreter.InterpreterResultMessage;
import org.apache.zeppelin.interpreter.InterpreterSetting;
-import org.apache.zeppelin.interpreter.LazyOpenInterpreter;
-import org.apache.zeppelin.interpreter.mock.MockInterpreter1;
-import org.apache.zeppelin.interpreter.mock.MockInterpreter2;
import org.apache.zeppelin.interpreter.remote.RemoteInterpreter;
import org.apache.zeppelin.notebook.repo.NotebookRepo;
import org.apache.zeppelin.notebook.repo.VFSNotebookRepo;
@@ -98,7 +93,7 @@ public class NotebookTest extends AbstractInterpreterTest implements JobListener
SearchService search = mock(SearchService.class);
notebookRepo = new VFSNotebookRepo(conf);
notebookAuthorization = NotebookAuthorization.init(conf);
- credentials = new Credentials(conf.credentialsPersist(), conf.getCredentialsPath());
+ credentials = new Credentials(conf.credentialsPersist(), conf.getCredentialsPath(), null);
notebook = new Notebook(conf, notebookRepo, schedulerFactory, interpreterFactory, interpreterSettingManager, this, search,
notebookAuthorization, credentials);
@@ -667,7 +662,7 @@ public class NotebookTest extends AbstractInterpreterTest implements JobListener
@Test
public void testAngularObjectRemovalOnInterpreterRestart() throws InterruptedException,
- IOException {
+ IOException, InterpreterException {
// create a note and a paragraph
Note note = notebook.createNote(anonymous);
interpreterSettingManager.setInterpreterBinding(anonymous.getUser(), note.getId(), interpreterSettingManager.getInterpreterSettingIds());
@@ -795,7 +790,7 @@ public class NotebookTest extends AbstractInterpreterTest implements JobListener
@Test
public void testAbortParagraphStatusOnInterpreterRestart() throws InterruptedException,
- IOException {
+ IOException, InterpreterException {
Note note = notebook.createNote(anonymous);
interpreterSettingManager.setInterpreterBinding(anonymous.getUser(), note.getId(), interpreterSettingManager.getInterpreterSettingIds());
@@ -829,7 +824,7 @@ public class NotebookTest extends AbstractInterpreterTest implements JobListener
}
@Test
- public void testPerSessionInterpreterCloseOnNoteRemoval() throws IOException {
+ public void testPerSessionInterpreterCloseOnNoteRemoval() throws IOException, InterpreterException {
// create a notes
Note note1 = notebook.createNote(anonymous);
Paragraph p1 = note1.addNewParagraph(AuthenticationInfo.ANONYMOUS);
@@ -861,7 +856,7 @@ public class NotebookTest extends AbstractInterpreterTest implements JobListener
}
@Test
- public void testPerSessionInterpreter() throws IOException {
+ public void testPerSessionInterpreter() throws IOException, InterpreterException {
// create two notes
Note note1 = notebook.createNote(anonymous);
Paragraph p1 = note1.addNewParagraph(AuthenticationInfo.ANONYMOUS);
@@ -905,7 +900,7 @@ public class NotebookTest extends AbstractInterpreterTest implements JobListener
@Test
- public void testPerNoteSessionInterpreter() throws IOException {
+ public void testPerNoteSessionInterpreter() throws IOException, InterpreterException {
// create two notes
Note note1 = notebook.createNote(anonymous);
Paragraph p1 = note1.addNewParagraph(AuthenticationInfo.ANONYMOUS);
@@ -964,7 +959,7 @@ public class NotebookTest extends AbstractInterpreterTest implements JobListener
}
@Test
- public void testPerSessionInterpreterCloseOnUnbindInterpreterSetting() throws IOException {
+ public void testPerSessionInterpreterCloseOnUnbindInterpreterSetting() throws IOException, InterpreterException {
// create a notes
Note note1 = notebook.createNote(anonymous);
Paragraph p1 = note1.addNewParagraph(AuthenticationInfo.ANONYMOUS);
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/NotebookRepoSyncTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/NotebookRepoSyncTest.java
index 8a0b5a13b7..22366545ee 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/NotebookRepoSyncTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/NotebookRepoSyncTest.java
@@ -103,7 +103,7 @@ public class NotebookRepoSyncTest implements JobListenerFactory {
search = mock(SearchService.class);
notebookRepoSync = new NotebookRepoSync(conf);
notebookAuthorization = NotebookAuthorization.init(conf);
- credentials = new Credentials(conf.credentialsPersist(), conf.getCredentialsPath());
+ credentials = new Credentials(conf.credentialsPersist(), conf.getCredentialsPath(), null);
notebookSync = new Notebook(conf, notebookRepoSync, schedulerFactory, factory, interpreterSettingManager, this, search,
notebookAuthorization, credentials);
anonymous = new AuthenticationInfo("anonymous");
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/resource/DistributedResourcePoolTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/resource/DistributedResourcePoolTest.java
index 469d5b593c..c7ccd467a3 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/resource/DistributedResourcePoolTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/resource/DistributedResourcePoolTest.java
@@ -79,7 +79,7 @@ public class DistributedResourcePoolTest extends AbstractInterpreterTest {
}
@Test
- public void testRemoteDistributedResourcePool() {
+ public void testRemoteDistributedResourcePool() throws InterpreterException {
Gson gson = new Gson();
InterpreterResult ret;
intp1.interpret("put key1 value1", context);
@@ -162,7 +162,7 @@ public class DistributedResourcePoolTest extends AbstractInterpreterTest {
}
@Test
- public void testResourcePoolUtils() {
+ public void testResourcePoolUtils() throws InterpreterException {
Gson gson = new Gson();
InterpreterResult ret;
@@ -201,7 +201,7 @@ public class DistributedResourcePoolTest extends AbstractInterpreterTest {
}
@Test
- public void testResourceInvokeMethod() {
+ public void testResourceInvokeMethod() throws InterpreterException {
Gson gson = new Gson();
InterpreterResult ret;
intp1.interpret("put key1 hey", context);
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/scheduler/RemoteSchedulerTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/scheduler/RemoteSchedulerTest.java
index a758591727..e43a39d52d 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/scheduler/RemoteSchedulerTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/scheduler/RemoteSchedulerTest.java
@@ -20,6 +20,7 @@ package org.apache.zeppelin.scheduler;
import org.apache.zeppelin.display.GUI;
import org.apache.zeppelin.interpreter.InterpreterContext;
import org.apache.zeppelin.interpreter.InterpreterContextRunner;
+import org.apache.zeppelin.interpreter.InterpreterException;
import org.apache.zeppelin.interpreter.InterpreterInfo;
import org.apache.zeppelin.interpreter.InterpreterOption;
import org.apache.zeppelin.interpreter.InterpreterResult;
@@ -63,7 +64,6 @@ public class RemoteSchedulerTest implements RemoteInterpreterProcessListener {
schedulerSvc = new SchedulerFactory();
InterpreterOption interpreterOption = new InterpreterOption();
- interpreterOption.setRemote(true);
InterpreterInfo interpreterInfo1 = new InterpreterInfo(MockInterpreterA.class.getName(), "mock", true, new HashMap());
List interpreterInfos = new ArrayList<>();
interpreterInfos.add(interpreterInfo1);
@@ -210,7 +210,11 @@ public class RemoteSchedulerTest implements RemoteInterpreterProcessListener {
@Override
protected boolean jobAbort() {
if (isRunning()) {
- intpA.cancel(context);
+ try {
+ intpA.cancel(context);
+ } catch (InterpreterException e) {
+ e.printStackTrace();
+ }
}
return true;
}
@@ -260,7 +264,11 @@ public class RemoteSchedulerTest implements RemoteInterpreterProcessListener {
@Override
protected boolean jobAbort() {
if (isRunning()) {
- intpA.cancel(context);
+ try {
+ intpA.cancel(context);
+ } catch (InterpreterException e) {
+ e.printStackTrace();
+ }
}
return true;
}