You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zeppelin.apache.org by fe...@apache.org on 2017/03/25 21:54:17 UTC
zeppelin git commit: [ZEPPELIN-1999] get interpreter property with
replaced context parameters
Repository: zeppelin
Updated Branches:
refs/heads/master a3c7f985f -> 998c8f35e
[ZEPPELIN-1999] get interpreter property with replaced context parameters
### What is this PR for?
Adds posibility to use context parameters (types: String.class, Double.class, Float.class, Short.class,
Byte.class, Character.class, Boolean.class, Integer.class, Long.class, ) into property value of interpreter.
### What type of PR is it?
Feature
### What is the Jira issue?
https://issues.apache.org/jira/browse/ZEPPELIN-1999
### How should this be tested?
1. Add text with markers #{contextFieldNAme} (ex. #{noteId} or #{replName}) to interpreter property value (or add new property of interpreter).
2. Get this property (getProperty(key)), markers should be replaced by context values
### Questions:
* Does the licenses files need update? no
* Is there breaking changes for older versions? no
* Does this needs documentation? yes
Author: Tinkoff DWH <ti...@gmail.com>
Closes #2085 from tinkoff-dwh/ZEPPELIN-1999 and squashes the following commits:
fa1500a [Tinkoff DWH] [ZEPPELIN-1999] fix logic of replace
93c759d [Tinkoff DWH] Merge remote-tracking branch 'origin/master' into ZEPPELIN-1999
be4fada [Tinkoff DWH] [ZEPPELIN-1999] revert gitignore
c0110e9 [Tinkoff DWH] [ZEPPELIN-1999] documentation
61ac564 [Tinkoff DWH] [ZEPPELIN-1999] docs
a10dc0e [Tinkoff DWH] [ZEPPELIN-1999] skip fields of paragraph
ea9c6a3 [Tinkoff DWH] [ZEPPELIN-1999] docs
7c4489c [Tinkoff DWH] Merge remote-tracking branch 'origin/master' into ZEPPELIN-1999
527419a [Tinkoff DWH] Merge remote-tracking branch 'origin/master' into ZEPPELIN-1999
b5424b9 [Tinkoff DWH] [ZEPPELIN-1999] get interpreter property with replaced context parameters
Project: http://git-wip-us.apache.org/repos/asf/zeppelin/repo
Commit: http://git-wip-us.apache.org/repos/asf/zeppelin/commit/998c8f35
Tree: http://git-wip-us.apache.org/repos/asf/zeppelin/tree/998c8f35
Diff: http://git-wip-us.apache.org/repos/asf/zeppelin/diff/998c8f35
Branch: refs/heads/master
Commit: 998c8f35e894335ae757867982401e4ba4118d00
Parents: a3c7f98
Author: Tinkoff DWH <ti...@gmail.com>
Authored: Wed Mar 22 14:20:38 2017 +0500
Committer: Felix Cheung <fe...@apache.org>
Committed: Sat Mar 25 14:54:12 2017 -0700
----------------------------------------------------------------------
...erpreter_setting_with_context_parameters.png | Bin 0 -> 17290 bytes
docs/manual/interpreters.md | 35 ++++++++++++++-
.../zeppelin/interpreter/Interpreter.java | 43 ++++++++++++++++++-
.../zeppelin/interpreter/InterpreterTest.java | 39 ++++++++++++++++-
4 files changed, 112 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/998c8f35/docs/assets/themes/zeppelin/img/screenshots/interpreter_setting_with_context_parameters.png
----------------------------------------------------------------------
diff --git a/docs/assets/themes/zeppelin/img/screenshots/interpreter_setting_with_context_parameters.png b/docs/assets/themes/zeppelin/img/screenshots/interpreter_setting_with_context_parameters.png
new file mode 100644
index 0000000..17c83b6
Binary files /dev/null and b/docs/assets/themes/zeppelin/img/screenshots/interpreter_setting_with_context_parameters.png differ
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/998c8f35/docs/manual/interpreters.md
----------------------------------------------------------------------
diff --git a/docs/manual/interpreters.md b/docs/manual/interpreters.md
index 70b94d4..916d591 100644
--- a/docs/manual/interpreters.md
+++ b/docs/manual/interpreters.md
@@ -41,8 +41,39 @@ Zeppelin interpreter setting is the configuration of a given interpreter on Zepp
<img src="../assets/themes/zeppelin/img/screenshots/interpreter_setting.png" width="500px">
-Properties are exported as environment variable when property name is consisted of upper characters, numbers and underscore ([A-Z_0-9]). Otherwise set properties as JVM property.
-
+Properties are exported as environment variables when property name is consisted of upper characters, numbers and underscore ([A-Z_0-9]). Otherwise set properties as JVM property.
+
+You may use parameters from the context of interpreter by add #{contextParameterName} in value, parameter can be of the following types: string, number, boolean.
+
+###### Context parameters
+<table class="table-configuration">
+ <tr>
+ <th>Name</th>
+ <th>Type</th>
+ </tr>
+ <tr>
+ <td>user</td>
+ <td>string</td>
+ </tr>
+ <tr>
+ <td>noteId</td>
+ <td>string</td>
+ </tr>
+ <tr>
+ <td>replName</td>
+ <td>string</td>
+ </tr>
+ <tr>
+ <td>className</td>
+ <td>string</td>
+ </tr>
+</table>
+
+If context parameter is null then replaced by empty string.
+
+<img src="../assets/themes/zeppelin/img/screenshots/interpreter_setting_with_context_parameters.png" width="800px">
+
+<br>
Each notebook can be bound to multiple Interpreter Settings using setting icon on upper right corner of the notebook.
<img src="../assets/themes/zeppelin/img/screenshots/interpreter_binding.png" width="800px">
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/998c8f35/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/Interpreter.java
----------------------------------------------------------------------
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 7114f31..b64530a 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
@@ -18,15 +18,19 @@
package org.apache.zeppelin.interpreter;
+import java.lang.reflect.Field;
import java.net.URL;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
-import org.apache.zeppelin.annotation.ZeppelinApi;
+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.thrift.InterpreterCompletion;
import org.apache.zeppelin.scheduler.Scheduler;
import org.apache.zeppelin.scheduler.SchedulerFactory;
@@ -157,6 +161,8 @@ public abstract class Interpreter {
}
}
+ replaceContextParameters(p);
+
return p;
}
@@ -296,6 +302,41 @@ public abstract class Interpreter {
return null;
}
+ /**
+ * Replace markers #{contextFieldName} by values from {@link InterpreterContext} fields
+ * with same name and marker #{user}. If value == null then replace by empty string.
+ */
+ private void replaceContextParameters(Properties properties) {
+ InterpreterContext interpreterContext = InterpreterContext.get();
+ if (interpreterContext != null) {
+ String markerTemplate = "#\\{%s\\}";
+ List<String> skipFields = Arrays.asList("paragraphTitle", "paragraphId", "paragraphText");
+ List typesToProcess = Arrays.asList(String.class, Double.class, Float.class, Short.class,
+ Byte.class, Character.class, Boolean.class, Integer.class, Long.class);
+ for (String key : properties.stringPropertyNames()) {
+ String p = properties.getProperty(key);
+ if (StringUtils.isNotEmpty(p)) {
+ for (Field field : InterpreterContext.class.getDeclaredFields()) {
+ Class clazz = field.getType();
+ if (!skipFields.contains(field.getName()) && (typesToProcess.contains(clazz)
+ || clazz.isPrimitive())) {
+ Object value = null;
+ try {
+ value = FieldUtils.readField(field, interpreterContext, true);
+ } catch (Exception e) {
+ logger.error("Cannot read value of field {0}", field.getName());
+ }
+ p = p.replaceAll(String.format(markerTemplate, field.getName()),
+ value != null ? value.toString() : StringUtils.EMPTY);
+ }
+ }
+ p = p.replaceAll(String.format(markerTemplate, "user"),
+ StringUtils.defaultString(userName, StringUtils.EMPTY));
+ properties.setProperty(key, p);
+ }
+ }
+ }
+ }
/**
* Type of interpreter.
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/998c8f35/zeppelin-interpreter/src/test/java/org/apache/zeppelin/interpreter/InterpreterTest.java
----------------------------------------------------------------------
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 9eb7932..a9ac1fc 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
@@ -17,13 +17,14 @@
package org.apache.zeppelin.interpreter;
-import static org.junit.Assert.assertEquals;
-
import java.util.Properties;
import org.apache.zeppelin.interpreter.remote.mock.MockInterpreterA;
+import org.apache.zeppelin.user.AuthenticationInfo;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
public class InterpreterTest {
@Test
@@ -51,4 +52,38 @@ public class InterpreterTest {
assertEquals("v2", intp.getProperty("p1"));
}
+ @Test
+ public void testPropertyWithReplacedContextFields() {
+ String noteId = "testNoteId";
+ String paragraphTitle = "testParagraphTitle";
+ String paragraphText = "testParagraphText";
+ String paragraphId = "testParagraphId";
+ String user = "username";
+ InterpreterContext.set(new InterpreterContext(noteId,
+ paragraphId,
+ null,
+ paragraphTitle,
+ paragraphText,
+ new AuthenticationInfo("testUser", "testTicket"),
+ null,
+ null,
+ null,
+ null,
+ null,
+ null));
+ Properties p = new Properties();
+ p.put("p1", "replName #{noteId}, #{paragraphTitle}, #{paragraphId}, #{paragraphText}, #{replName}, #{noteId}, #{user}," +
+ " #{authenticationInfo}");
+ MockInterpreterA intp = new MockInterpreterA(p);
+ intp.setUserName(user);
+ String actual = intp.getProperty("p1");
+ InterpreterContext.remove();
+
+ assertEquals(
+ String.format("replName %s, #{paragraphTitle}, #{paragraphId}, #{paragraphText}, , %s, %s, #{authenticationInfo}", noteId,
+ noteId, user),
+ actual
+ );
+ }
+
}