This is an automated email from the ASF dual-hosted git repository.
liuxun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/zeppelin.git
The following commit(s) were added to refs/heads/master by this push:
new f58f8d8 [ZEPPELIN-4171] Configuration paragraph is empty to execute
f58f8d8 is described below
commit f58f8d88866f7d2c7d041e1a410b82f2bf25e24f
Author: Xun Liu <[email protected]>
AuthorDate: Mon May 27 11:34:07 2019 +0800
[ZEPPELIN-4171] Configuration paragraph is empty to execute
### What is this PR for?
In some cases,
For example: `%sh.terminal` interpreter
The paragraph is empty and can be executed
Add the config configuration section in the `interpreter-setting.json` file
of the interpreter.
```
"config": {
"checkEmpty": true
}
```
### What type of PR is it?
[Improvement]
### Todos
* [ ] - Task
### What is the Jira issue?
* https://issues.apache.org/jira/browse/ZEPPELIN-4171
### How should this be tested?
* [CI Pass](https://travis-ci.org/liuxunorg/zeppelin/builds/537325588)
### Screenshots (if appropriate)

### Questions:
* Does the licenses files need update?
* Is there breaking changes for older versions?
* Does this needs documentation?
Author: Xun Liu <[email protected]>
Closes #3371 from liuxunorg/ZEPPELIN-4171 and squashes the following
commits:
753a8a3c7 [Xun Liu] Modify according to review comments.
ef1889574 [Xun Liu] Improve document description.
5abd7fc86 [Xun Liu] [ZEPPELIN-4171] Check paragraph is empty before
execution
---
docs/development/writing_zeppelin_interpreter.md | 14 +++++++-
.../apache/zeppelin/service/NotebookService.java | 2 +-
.../org/apache/zeppelin/notebook/Paragraph.java | 38 ++++++++++++++++++----
.../org/apache/zeppelin/notebook/NotebookTest.java | 23 ++++++++-----
.../src/test/resources/conf/interpreter.json | 3 +-
.../config_test/interpreter-setting.json | 3 +-
6 files changed, 63 insertions(+), 20 deletions(-)
diff --git a/docs/development/writing_zeppelin_interpreter.md
b/docs/development/writing_zeppelin_interpreter.md
index c613204..27843ac 100644
--- a/docs/development/writing_zeppelin_interpreter.md
+++ b/docs/development/writing_zeppelin_interpreter.md
@@ -121,7 +121,8 @@ Here is an example of `interpreter-setting.json` on your
own interpreter.
},
"config": {
"runOnSelectionChange": true/false,
- "title": true/false
+ "title": true/false,
+ "checkEmpty": true/false
}
},
{
@@ -207,6 +208,17 @@ You can make the dynamic form in the notebook not trigger
execution after select
}
```
+
+### Check if the paragraph is empty before running (Optional)
+The notebook's paragraph default will not run if it is empty.
+You can set `config.checkEmpty=false`, to run even when the paragraph of the
notebook is empty.
+
+```json
+"config": {
+ "checkEmpty": false # default: true
+}
+```
+
## Install your interpreter binary
Once you have built your interpreter, you can place it under the interpreter
directory with all its dependencies.
diff --git
a/zeppelin-server/src/main/java/org/apache/zeppelin/service/NotebookService.java
b/zeppelin-server/src/main/java/org/apache/zeppelin/service/NotebookService.java
index bb42ce2..ccd6639 100644
---
a/zeppelin-server/src/main/java/org/apache/zeppelin/service/NotebookService.java
+++
b/zeppelin-server/src/main/java/org/apache/zeppelin/service/NotebookService.java
@@ -453,7 +453,7 @@ public class NotebookService {
throw new NoteNotFoundException(noteId);
}
Paragraph newPara = note.insertNewParagraph(index, context.getAutheInfo());
- newPara.setConfig(config);
+ newPara.mergeConfig(config);
notebook.saveNote(note, context.getAutheInfo());
callback.onSuccess(newPara, context);
return newPara;
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 81b5250..1cc0ba7 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
@@ -105,10 +105,12 @@ public class Paragraph extends
JobWithProgressPoller<InterpreterResult> implemen
private transient Map<String, String> localProperties = new HashMap<>();
private transient Map<String, ParagraphRuntimeInfo> runtimeInfos = new
HashMap<>();
- private static String PARAGRAPH_CONFIG_RUNONSELECTIONCHANGE =
"runOnSelectionChange";
+ public static String PARAGRAPH_CONFIG_RUNONSELECTIONCHANGE =
"runOnSelectionChange";
private static boolean PARAGRAPH_CONFIG_RUNONSELECTIONCHANGE_DEFAULT = true;
- private static String PARAGRAPH_CONFIG_TITLE = "title";
+ public static String PARAGRAPH_CONFIG_TITLE = "title";
private static boolean PARAGRAPH_CONFIG_TITLE_DEFAULT = false;
+ public static String PARAGRAPH_CONFIG_CHECK_EMTPY = "checkEmpty";
+ private static boolean PARAGRAPH_CONFIG_CHECK_EMTPY_DEFAULT = true;
@VisibleForTesting
Paragraph() {
@@ -343,12 +345,30 @@ public class Paragraph extends
JobWithProgressPoller<InterpreterResult> implemen
return null;
}
- public boolean isBlankParagraph() {
+ public boolean shouldSkipRunParagraph() {
+ // check interpreter-setting.json `config.checkEmpty` is equal false
+ Object configCheckEmpty = this.config.get(PARAGRAPH_CONFIG_CHECK_EMTPY);
+ if (null != configCheckEmpty) {
+ boolean checkEmtpy = PARAGRAPH_CONFIG_CHECK_EMTPY_DEFAULT;
+ try {
+ checkEmtpy = (boolean) configCheckEmpty;
+ } catch (ClassCastException e) {
+ LOGGER.error(e.getMessage(), e);
+ } catch (Exception e) {
+ LOGGER.error(e.getMessage(), e);
+ }
+ if (!checkEmtpy) {
+ LOGGER.info("This interpreter config `interpreter-setting.json` set
config.{} = false",
+ PARAGRAPH_CONFIG_CHECK_EMTPY);
+ return false;
+ }
+ }
+
return Strings.isNullOrEmpty(scriptText);
}
public boolean execute(boolean blocking) {
- if (isBlankParagraph()) {
+ if (shouldSkipRunParagraph()) {
LOGGER.info("Skip to run blank paragraph. {}", getId());
setStatus(Job.Status.FINISHED);
return true;
@@ -478,7 +498,7 @@ public class Paragraph extends
JobWithProgressPoller<InterpreterResult> implemen
String name = ((ManagedInterpreterGroup)
intpGroup).getInterpreterSetting().getName();
Map<String, Object> config
= intpSettingManager.getConfigSetting(name);
- applyConfigSetting(config);
+ mergeConfig(config);
}
}
}
@@ -601,10 +621,13 @@ public class Paragraph extends
JobWithProgressPoller<InterpreterResult> implemen
return config;
}
+ // NOTE: function setConfig(...) will overwrite all configuration
+ // Merge configuration, you need to use function mergeConfig(...)
public void setConfig(Map<String, Object> config) {
this.config = config;
}
+ // [ZEPPELIN-3919] Paragraph config default value can be customized
// apply the `interpreter-setting.json` config
// When creating a paragraph, it will update some of the configuration
// parameters of the paragraph from the web side.
@@ -615,13 +638,13 @@ public class Paragraph extends
JobWithProgressPoller<InterpreterResult> implemen
// 2. The user manually modified the interpreter types of this paragraph.
// Need to delete the existing configuration of this paragraph,
// update with the specified interpreter configuration
- public void applyConfigSetting(Map<String, Object> newConfig) {
+ public void mergeConfig(Map<String, Object> newConfig) {
if (null == newConfig || 0 == newConfig.size()) {
newConfig = getDefaultConfigSetting();
}
List<String> keysToRemove =
Arrays.asList(PARAGRAPH_CONFIG_RUNONSELECTIONCHANGE,
- PARAGRAPH_CONFIG_TITLE);
+ PARAGRAPH_CONFIG_TITLE, PARAGRAPH_CONFIG_CHECK_EMTPY);
for (String removeKey : keysToRemove) {
if ((false == newConfig.containsKey(removeKey))
&& (true == config.containsKey(removeKey))) {
@@ -637,6 +660,7 @@ public class Paragraph extends
JobWithProgressPoller<InterpreterResult> implemen
Map<String, Object> config = new HashMap<>();
config.put(PARAGRAPH_CONFIG_RUNONSELECTIONCHANGE,
PARAGRAPH_CONFIG_RUNONSELECTIONCHANGE_DEFAULT);
config.put(PARAGRAPH_CONFIG_TITLE, PARAGRAPH_CONFIG_TITLE_DEFAULT);
+ config.put(PARAGRAPH_CONFIG_CHECK_EMTPY,
PARAGRAPH_CONFIG_CHECK_EMTPY_DEFAULT);
return config;
}
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 1629ab2..49023e7 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
@@ -1094,16 +1094,19 @@ public class NotebookTest extends
AbstractInterpreterTest implements ParagraphJo
// create paragraphs
Paragraph p1 = note.addNewParagraph(anonymous);
Map<String, Object> config = p1.getConfig();
- assertTrue(config.containsKey("runOnSelectionChange"));
- assertTrue(config.containsKey("title"));
- assertEquals(config.get("runOnSelectionChange"), false);
- assertEquals(config.get("title"), true);
+
assertTrue(config.containsKey(Paragraph.PARAGRAPH_CONFIG_RUNONSELECTIONCHANGE));
+ assertTrue(config.containsKey(Paragraph.PARAGRAPH_CONFIG_TITLE));
+ assertTrue(config.containsKey(Paragraph.PARAGRAPH_CONFIG_CHECK_EMTPY));
+ assertEquals(config.get(Paragraph.PARAGRAPH_CONFIG_RUNONSELECTIONCHANGE),
false);
+ assertEquals(config.get(Paragraph.PARAGRAPH_CONFIG_TITLE), true);
+ assertEquals(config.get(Paragraph.PARAGRAPH_CONFIG_CHECK_EMTPY), false);
// The config_test interpreter sets the default parameters
// in interpreter/config_test/interpreter-setting.json
// "config": {
// "runOnSelectionChange": false,
- // "title": true
+ // "title": true,
+ // "checkEmpty": true
// },
p1.setText("%config_test sleep 1000");
note.runAll(AuthenticationInfo.ANONYMOUS, false);
@@ -1113,8 +1116,9 @@ public class NotebookTest extends AbstractInterpreterTest
implements ParagraphJo
// Check if the config_test interpreter default parameter takes effect
LOGGER.info("p1.getConfig() = " + p1.getConfig());
- assertEquals(config.get("runOnSelectionChange"), false);
- assertEquals(config.get("title"), true);
+ assertEquals(config.get(Paragraph.PARAGRAPH_CONFIG_RUNONSELECTIONCHANGE),
false);
+ assertEquals(config.get(Paragraph.PARAGRAPH_CONFIG_TITLE), true);
+ assertEquals(config.get(Paragraph.PARAGRAPH_CONFIG_CHECK_EMTPY), false);
// The mock1 interpreter does not set default parameters
p1.setText("%mock1 sleep 1000");
@@ -1125,8 +1129,9 @@ public class NotebookTest extends AbstractInterpreterTest
implements ParagraphJo
// Check if the mock1 interpreter parameter is updated
LOGGER.info("changed intp p1.getConfig() = " + p1.getConfig());
- assertEquals(config.get("runOnSelectionChange"), true);
- assertEquals(config.get("title"), false);
+ assertEquals(config.get(Paragraph.PARAGRAPH_CONFIG_RUNONSELECTIONCHANGE),
true);
+ assertEquals(config.get(Paragraph.PARAGRAPH_CONFIG_TITLE), false);
+ assertEquals(config.get(Paragraph.PARAGRAPH_CONFIG_CHECK_EMTPY), true);
}
@Test
diff --git a/zeppelin-zengine/src/test/resources/conf/interpreter.json
b/zeppelin-zengine/src/test/resources/conf/interpreter.json
index dc3e8ce..62ae850 100644
--- a/zeppelin-zengine/src/test/resources/conf/interpreter.json
+++ b/zeppelin-zengine/src/test/resources/conf/interpreter.json
@@ -132,7 +132,8 @@
"fontSize": 9,
"colWidth": 12,
"runOnSelectionChange": false,
- "title": true
+ "title": true,
+ "checkEmpty": false
},
"option": {
"remote": true,
diff --git
a/zeppelin-zengine/src/test/resources/interpreter/config_test/interpreter-setting.json
b/zeppelin-zengine/src/test/resources/interpreter/config_test/interpreter-setting.json
index 6fd39fc..08d4ac7 100644
---
a/zeppelin-zengine/src/test/resources/interpreter/config_test/interpreter-setting.json
+++
b/zeppelin-zengine/src/test/resources/interpreter/config_test/interpreter-setting.json
@@ -8,7 +8,8 @@
},
"config": {
"runOnSelectionChange": false,
- "title": true
+ "title": true,
+ "checkEmpty": false
},
"option": {
"remote": true,