mirror of
https://github.com/apache/zeppelin
synced 2026-05-24 09:38:26 +00:00
Merge branch 'master' into notebook-search
Conflicts: zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java
This commit is contained in:
commit
2b2f8dcb9d
4 changed files with 266 additions and 8 deletions
|
|
@ -33,7 +33,7 @@ limitations under the License.
|
|||
<br />
|
||||
### Notebook REST API list
|
||||
|
||||
Notebooks REST API supports the following operations: List, Create, Delete & Clone as detailed in the following table
|
||||
Notebooks REST API supports the following operations: List, Create, Get, Delete, Clone, Run as detailed in the following table
|
||||
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
|
|
@ -119,6 +119,108 @@ limitations under the License.
|
|||
</tr>
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<th>Get notebook</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```GET``` method retrieves an existing notebook's information using the given id.
|
||||
The body field of the returned JSON contain information about paragraphs in the notebook.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>URL</td>
|
||||
<td>```http://[zeppelin-server]:[zeppelin-port]/api/notebook/[notebookId]```</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Success code</td>
|
||||
<td>200</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> Fail code</td>
|
||||
<td> 500 </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> sample JSON response </td>
|
||||
<td><pre>
|
||||
{
|
||||
"status": "OK",
|
||||
"message": "",
|
||||
"body": {
|
||||
"paragraphs": [
|
||||
{
|
||||
"text": "%sql \nselect age, count(1) value\nfrom bank \nwhere age < 30 \ngroup by age \norder by age",
|
||||
"config": {
|
||||
"colWidth": 4,
|
||||
"graph": {
|
||||
"mode": "multiBarChart",
|
||||
"height": 300,
|
||||
"optionOpen": false,
|
||||
"keys": [
|
||||
{
|
||||
"name": "age",
|
||||
"index": 0,
|
||||
"aggr": "sum"
|
||||
}
|
||||
],
|
||||
"values": [
|
||||
{
|
||||
"name": "value",
|
||||
"index": 1,
|
||||
"aggr": "sum"
|
||||
}
|
||||
],
|
||||
"groups": [],
|
||||
"scatter": {
|
||||
"xAxis": {
|
||||
"name": "age",
|
||||
"index": 0,
|
||||
"aggr": "sum"
|
||||
},
|
||||
"yAxis": {
|
||||
"name": "value",
|
||||
"index": 1,
|
||||
"aggr": "sum"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"params": {},
|
||||
"forms": {}
|
||||
},
|
||||
"jobName": "paragraph_1423500782552_-1439281894",
|
||||
"id": "20150210-015302_1492795503",
|
||||
"result": {
|
||||
"code": "SUCCESS",
|
||||
"type": "TABLE",
|
||||
"msg": "age\tvalue\n19\t4\n20\t3\n21\t7\n22\t9\n23\t20\n24\t24\n25\t44\n26\t77\n27\t94\n28\t103\n29\t97\n"
|
||||
},
|
||||
"dateCreated": "Feb 10, 2015 1:53:02 AM",
|
||||
"dateStarted": "Jul 3, 2015 1:43:17 PM",
|
||||
"dateFinished": "Jul 3, 2015 1:43:23 PM",
|
||||
"status": "FINISHED",
|
||||
"progressUpdateIntervalMs": 500
|
||||
}
|
||||
],
|
||||
"name": "Zeppelin Tutorial",
|
||||
"id": "2A94M5J1Z",
|
||||
"angularObjects": {},
|
||||
"config": {
|
||||
"looknfeel": "default"
|
||||
},
|
||||
"info": {}
|
||||
}
|
||||
}
|
||||
</pre></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
|
||||
<table class="table-configuration">
|
||||
|
|
@ -308,6 +410,18 @@ limitations under the License.
|
|||
<td> Fail code</td>
|
||||
<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>
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import javax.ws.rs.QueryParam;
|
|||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.zeppelin.interpreter.InterpreterSetting;
|
||||
import org.apache.zeppelin.notebook.Note;
|
||||
import org.apache.zeppelin.notebook.Notebook;
|
||||
|
|
@ -41,6 +42,7 @@ import org.apache.zeppelin.rest.message.CronRequest;
|
|||
import org.apache.zeppelin.rest.message.InterpreterSettingListForNoteBind;
|
||||
import org.apache.zeppelin.rest.message.NewNotebookRequest;
|
||||
import org.apache.zeppelin.rest.message.NewParagraphRequest;
|
||||
import org.apache.zeppelin.rest.message.RunParagraphWithParametersRequest;
|
||||
import org.apache.zeppelin.search.SearchService;
|
||||
import org.apache.zeppelin.server.JsonResponse;
|
||||
import org.apache.zeppelin.socket.NotebookServer;
|
||||
|
|
@ -133,6 +135,17 @@ public class NotebookRestApi {
|
|||
return new JsonResponse<>(Status.OK, "", notesInfo ).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{notebookId}")
|
||||
public Response getNotebook(@PathParam("notebookId") String notebookId) throws IOException {
|
||||
Note note = notebook.getNote(notebookId);
|
||||
if (note == null) {
|
||||
return new JsonResponse<>(Status.NOT_FOUND, "note not found.").build();
|
||||
}
|
||||
|
||||
return new JsonResponse<>(Status.OK, "", note).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new note REST API
|
||||
* @param message - JSON with new note name
|
||||
|
|
@ -271,26 +284,43 @@ 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 {
|
||||
LOG.info("run paragraph job {} {} ", notebookId, paragraphId);
|
||||
LOG.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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -34,6 +34,7 @@ import org.apache.zeppelin.notebook.Note;
|
|||
import org.apache.zeppelin.notebook.Paragraph;
|
||||
import org.apache.zeppelin.rest.message.NewParagraphRequest;
|
||||
import org.apache.zeppelin.scheduler.Job.Status;
|
||||
import org.apache.zeppelin.server.JsonResponse;
|
||||
import org.apache.zeppelin.server.ZeppelinServer;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
|
|
@ -193,6 +194,39 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
|
|||
ZeppelinServer.notebook.removeNote(note.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNotebookInfo() throws IOException {
|
||||
LOG.info("testGetNotebookInfo");
|
||||
// Create note to get info
|
||||
Note note = ZeppelinServer.notebook.createNote();
|
||||
assertNotNull("can't create new note", note);
|
||||
note.setName("note");
|
||||
Paragraph paragraph = note.addParagraph();
|
||||
Map config = paragraph.getConfig();
|
||||
config.put("enabled", true);
|
||||
paragraph.setConfig(config);
|
||||
String paragraphText = "%md This is my new paragraph in my new note";
|
||||
paragraph.setText(paragraphText);
|
||||
note.persist();
|
||||
|
||||
String sourceNoteID = note.getId();
|
||||
GetMethod get = httpGet("/notebook/" + sourceNoteID);
|
||||
LOG.info("testGetNotebookInfo \n" + get.getResponseBodyAsString());
|
||||
assertThat("test notebook get method:", get, isAllowed());
|
||||
|
||||
Map<String, Object> resp = gson.fromJson(get.getResponseBodyAsString(), new TypeToken<Map<String, Object>>() {
|
||||
}.getType());
|
||||
|
||||
assertNotNull(resp);
|
||||
assertEquals("OK", resp.get("status"));
|
||||
|
||||
Map<String, Object> body = (Map<String, Object>) resp.get("body");
|
||||
List<Map<String, Object>> paragraphs = (List<Map<String, Object>>) body.get("paragraphs");
|
||||
|
||||
assertTrue(paragraphs.size() > 0);
|
||||
assertEquals(paragraphText, paragraphs.get(0).get("text"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotebookCreateWithName() throws IOException {
|
||||
String noteName = "Test note name";
|
||||
|
|
@ -405,7 +439,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
|
||||
|
|
|
|||
Loading…
Reference in a new issue