Repository: incubator-zeppelin
Updated Branches:
  refs/heads/master 1ba6e2a59 -> 9fec2598c


ZEPPELIN-507 Expand "run paragraph" of REST API to update dynamic form's value

### What is this PR for?

To update dynamic form's value (via params) when running paragraph via REST API

### What type of PR is it?

Improvement

### Todos

### Is there a relevant Jira issue?

https://issues.apache.org/jira/browse/ZEPPELIN-507

### How should this be tested?

* Create a new notebook with one paragraph which contains

```
%spark

val form1 = z.input("form1").toString
```

* Get paragraph ID via websocket (I think we should add a new REST API to get 
it easily.)

* Request ```http://<zeppelin host>:<zeppelin port>/api/notebook/job/<notebook 
id>/<paragraph id>``` with POST method including JSON payload,

```
{
    "params": {
        "form1": "value1"
    }
}
```

* Confirm that paragraph has run and input text of form1 is filled with 
"value1" (from the UI)

### Screenshots (if appropriate)

### Questions:
* Does the licenses files need update? (No)
* Is there breaking changes for older versions? (No, additonal json payload is 
optional.)
* Does this needs documentation? (Yes, I've addressed it.)

Author: Jungtaek Lim <[email protected]>

Closes #541 from HeartSaVioR/ZEPPELIN-507 and squashes the following commits:

814664e [Jungtaek Lim] ZEPPELIN-507 Increase timeout for initializing spark 
interpreter
8dcf02c [Jungtaek Lim] ZEPPELIN-507 Expand "run paragraph" of REST API to 
specify params


Project: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/commit/9fec2598
Tree: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/tree/9fec2598
Diff: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/diff/9fec2598

Branch: refs/heads/master
Commit: 9fec2598ca36578517aed6d776fef8060df42755
Parents: 1ba6e2a
Author: Jungtaek Lim <[email protected]>
Authored: Mon Dec 21 10:15:12 2015 +0900
Committer: Lee moon soo <[email protected]>
Committed: Tue Dec 22 04:28:25 2015 +0900

----------------------------------------------------------------------
 docs/rest-api/rest-notebook.md                  | 12 +++++
 .../apache/zeppelin/rest/NotebookRestApi.java   | 29 +++++++++---
 .../RunParagraphWithParametersRequest.java      | 35 +++++++++++++++
 .../zeppelin/rest/ZeppelinRestApiTest.java      | 47 +++++++++++++++++++-
 4 files changed, 116 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/9fec2598/docs/rest-api/rest-notebook.md
----------------------------------------------------------------------
diff --git a/docs/rest-api/rest-notebook.md b/docs/rest-api/rest-notebook.md
index bbecc5c..0739bcb 100644
--- a/docs/rest-api/rest-notebook.md
+++ b/docs/rest-api/rest-notebook.md
@@ -309,6 +309,18 @@ limitations under the License.
       <td> 500 </td>
     </tr>
     <tr>
+      <td> sample JSON input (optional, only needed when if you want to update 
dynamic form's value) </td>
+      <td><pre>
+{
+  "name": "name of new notebook",
+  "params": {
+    "formLabel1": "value1",
+    "formLabel2": "value2"
+  }
+}
+      </pre></td>
+    </tr>
+    <tr>
       <td> sample JSON response </td>
       <td><pre>{"status":"OK"}</pre></td>
     </tr>

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/9fec2598/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java
----------------------------------------------------------------------
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 4f1dd01..29c5c29 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
@@ -26,6 +26,8 @@ import javax.ws.rs.*;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
 
+import org.apache.commons.lang3.StringUtils;
+import org.apache.zeppelin.display.Input;
 import org.apache.zeppelin.interpreter.InterpreterSetting;
 import org.apache.zeppelin.notebook.Note;
 import org.apache.zeppelin.notebook.Notebook;
@@ -260,26 +262,41 @@ public class NotebookRestApi {
   
   /**
    * Run paragraph job REST API
-   * @param
+   * @param message - JSON with params if user wants to update dynamic form's 
value
+   *                null, empty string, empty json if user doesn't want to 
update
    * @return JSON with status.OK
    * @throws IOException, IllegalArgumentException
    */
   @POST
   @Path("job/{notebookId}/{paragraphId}")
   public Response runParagraph(@PathParam("notebookId") String notebookId, 
-                               @PathParam("paragraphId") String paragraphId) 
throws
+                               @PathParam("paragraphId") String paragraphId,
+                               String message) throws
                                IOException, IllegalArgumentException {
-    logger.info("run paragraph job {} {} ", notebookId, paragraphId);
+    logger.info("run paragraph job {} {} {}", notebookId, paragraphId, 
message);
+
     Note note = notebook.getNote(notebookId);
     if (note == null) {
       return new JsonResponse(Status.NOT_FOUND, "note not found.").build();
     }
-    
-    if (note.getParagraph(paragraphId) == null) {
+
+    Paragraph paragraph = note.getParagraph(paragraphId);
+    if (paragraph == null) {
       return new JsonResponse(Status.NOT_FOUND, "paragraph not 
found.").build();
     }
 
-    note.run(paragraphId);
+    // handle params if presented
+    if (!StringUtils.isEmpty(message)) {
+      RunParagraphWithParametersRequest request = gson.fromJson(message,
+          RunParagraphWithParametersRequest.class);
+      Map<String, Object> paramsForUpdating = request.getParams();
+      if (paramsForUpdating != null) {
+        paragraph.settings.getParams().putAll(paramsForUpdating);
+        note.persist();
+      }
+    }
+
+    note.run(paragraph.getId());
     return new JsonResponse(Status.OK).build();
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/9fec2598/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/RunParagraphWithParametersRequest.java
----------------------------------------------------------------------
diff --git 
a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/RunParagraphWithParametersRequest.java
 
b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/RunParagraphWithParametersRequest.java
new file mode 100644
index 0000000..7d8095f
--- /dev/null
+++ 
b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/RunParagraphWithParametersRequest.java
@@ -0,0 +1,35 @@
+/*
+ * 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;
+
+import java.util.Map;
+
+/**
+ * RunParagraphWithParametersRequest rest api request message
+ */
+public class RunParagraphWithParametersRequest {
+  Map<String, Object> params;
+
+  public RunParagraphWithParametersRequest() {
+
+  }
+
+  public Map<String, Object> getParams() {
+    return params;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/9fec2598/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java
----------------------------------------------------------------------
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 3111807..cee36b4 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
@@ -405,7 +405,52 @@ public class ZeppelinRestApiTest extends 
AbstractTestRestApi {
     //cleanup
     ZeppelinServer.notebook.removeNote(note.getId());
   }
-  
+
+  @Test
+  public void testRunParagraphWithParams() throws IOException, 
InterruptedException {
+    LOG.info("testRunParagraphWithParams");
+    // Create note to run test.
+    Note note = ZeppelinServer.notebook.createNote();
+    assertNotNull("can't create new note", note);
+    note.setName("note for run test");
+    Paragraph paragraph = note.addParagraph();
+
+    Map config = paragraph.getConfig();
+    config.put("enabled", true);
+    paragraph.setConfig(config);
+
+    paragraph.setText("%spark\nval param = 
z.input(\"param\").toString\nprintln(param)");
+    note.persist();
+    String noteID = note.getId();
+
+    note.runAll();
+    // wait until job is finished or timeout.
+    int timeout = 1;
+    while (!paragraph.isTerminated()) {
+      Thread.sleep(1000);
+      if (timeout++ > 120) {
+        LOG.info("testRunParagraphWithParams timeout job.");
+        break;
+      }
+    }
+
+    // Call Run paragraph REST API
+    PostMethod postParagraph = httpPost("/notebook/job/" + noteID + "/" + 
paragraph.getId(),
+        "{\"params\": {\"param\": \"hello\", \"param2\": \"world\"}}");
+    assertThat("test paragraph run:", postParagraph, isAllowed());
+    postParagraph.releaseConnection();
+    Thread.sleep(1000);
+
+    Note retrNote = ZeppelinServer.notebook.getNote(noteID);
+    Paragraph retrParagraph = retrNote.getParagraph(paragraph.getId());
+    Map<String, Object> params = retrParagraph.settings.getParams();
+    assertEquals("hello", params.get("param"));
+    assertEquals("world", params.get("param2"));
+
+    //cleanup
+    ZeppelinServer.notebook.removeNote(note.getId());
+  }
+
   @Test
   public void testCronJobs() throws InterruptedException, IOException{
     // create a note and a paragraph

Reply via email to