ZEPPELIN-511 REST API: Insert / Retrieve / Move / Delete operation for paragraph

* implements 4 REST APIs about the paragraph
* Added unit test to test this features

Conflicts:
	zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java
This commit is contained in:
Jungtaek Lim 2015-12-18 07:42:27 +09:00
parent d64920d20b
commit 3658b009b1
3 changed files with 223 additions and 3 deletions

View file

@ -218,7 +218,125 @@ public class NotebookRestApi {
notebookServer.broadcastNoteList();
return new JsonResponse<>(Status.CREATED, "", newNote.getId()).build();
}
/**
* Insert paragraph REST API
* @param message - JSON containing paragraph's information
* @return JSON with status.OK
* @throws IOException
*/
@POST
@Path("{notebookId}/paragraph")
public Response insertParagraph(@PathParam("notebookId") String notebookId, String message)
throws IOException {
LOG.info("insert paragraph {} {}", notebookId, message);
Note note = notebook.getNote(notebookId);
if (note == null) {
return new JsonResponse(Status.NOT_FOUND, "note not found.").build();
}
NewParagraphRequest request = gson.fromJson(message, NewParagraphRequest.class);
Paragraph p;
Double indexDouble = request.getIndex();
if (indexDouble == null) {
p = note.addParagraph();
} else {
p = note.insertParagraph(indexDouble.intValue());
}
p.setTitle(request.getTitle());
p.setText(request.getText());
note.persist();
notebookServer.broadcastNote(note);
return new JsonResponse(Status.OK, "").build();
}
/**
* Get paragraph REST API
* @param
* @return JSON with information of the paragraph
* @throws IOException
*/
@GET
@Path("{notebookId}/paragraph/{paragraphId}")
public Response getParagraph(@PathParam("notebookId") String notebookId,
@PathParam("paragraphId") String paragraphId) throws IOException {
LOG.info("get paragraph {} {}", notebookId, paragraphId);
Note note = notebook.getNote(notebookId);
if (note == null) {
return new JsonResponse(Status.NOT_FOUND, "note not found.").build();
}
Paragraph p = note.getParagraph(paragraphId);
if (p == null) {
return new JsonResponse(Status.NOT_FOUND, "paragraph not found.").build();
}
return new JsonResponse(Status.OK, "", p).build();
}
/**
* Move paragraph REST API
* @param newIndex - new index to move
* @return JSON with status.OK
* @throws IOException
*/
@POST
@Path("{notebookId}/paragraph/{paragraphId}/move/{newIndex}")
public Response moveParagraph(@PathParam("notebookId") String notebookId,
@PathParam("paragraphId") String paragraphId,
@PathParam("newIndex") String newIndex) throws IOException {
LOG.info("move paragraph {} {} {}", notebookId, paragraphId, newIndex);
Note note = notebook.getNote(notebookId);
if (note == null) {
return new JsonResponse(Status.NOT_FOUND, "note not found.").build();
}
Paragraph p = note.getParagraph(paragraphId);
if (p == null) {
return new JsonResponse(Status.NOT_FOUND, "paragraph not found.").build();
}
note.moveParagraph(paragraphId, Integer.parseInt(newIndex));
note.persist();
notebookServer.broadcastNote(note);
return new JsonResponse(Status.OK, "").build();
}
/**
* Delete paragraph REST API
* @param
* @return JSON with status.OK
* @throws IOException
*/
@DELETE
@Path("{notebookId}/paragraph/{paragraphId}")
public Response deleteParagraph(@PathParam("notebookId") String notebookId,
@PathParam("paragraphId") String paragraphId) throws IOException {
LOG.info("delete paragraph {} {}", notebookId, paragraphId);
Note note = notebook.getNote(notebookId);
if (note == null) {
return new JsonResponse(Status.NOT_FOUND, "note not found.").build();
}
Paragraph p = note.getParagraph(paragraphId);
if (p == null) {
return new JsonResponse(Status.NOT_FOUND, "paragraph not found.").build();
}
note.removeParagraph(paragraphId);
note.persist();
notebookServer.broadcastNote(note);
return new JsonResponse(Status.OK, "").build();
}
/**
* Run notebook jobs REST API
* @param

View file

@ -20,12 +20,12 @@ package org.apache.zeppelin.rest.message;
/**
* NewParagraphRequest rest api request message
*
* It is used for NewNotebookRequest with initial paragraphs
*
* index field will be ignored when it's used to provide initial paragraphs
*/
public class NewParagraphRequest {
String title;
String text;
Double index;
public NewParagraphRequest() {
@ -38,4 +38,8 @@ public class NewParagraphRequest {
public String getText() {
return text;
}
public Double getIndex() {
return index;
}
}

View file

@ -602,5 +602,103 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
ZeppelinServer.notebook.removeNote(note.getId());
}
@Test
public void testInsertParagraph() throws IOException {
Note note = ZeppelinServer.notebook.createNote();
String jsonRequest = "{\"title\": \"title1\", \"text\": \"text1\"}";
PostMethod post = httpPost("/notebook/" + note.getId() + "/paragraph", jsonRequest);
LOG.info("testInsertParagraph response\n" + post.getResponseBodyAsString());
assertThat("Test insert method:", post, isAllowed());
post.releaseConnection();
Paragraph lastParagraph = note.getLastParagraph();
assertEquals("title1", lastParagraph.getTitle());
assertEquals("text1", lastParagraph.getText());
// insert to index 0
String jsonRequest2 = "{\"index\": 0, \"title\": \"title2\", \"text\": \"text2\"}";
PostMethod post2 = httpPost("/notebook/" + note.getId() + "/paragraph", jsonRequest2);
LOG.info("testInsertParagraph response2\n" + post.getResponseBodyAsString());
assertThat("Test insert method:", post, isAllowed());
post.releaseConnection();
Paragraph paragraphAtIdx0 = note.getParagraphs().get(0);
assertEquals("title2", paragraphAtIdx0.getTitle());
assertEquals("text2", paragraphAtIdx0.getText());
}
@Test
public void testGetParagraph() throws IOException {
Note note = ZeppelinServer.notebook.createNote();
Paragraph p = note.addParagraph();
p.setTitle("hello");
p.setText("world");
note.persist();
GetMethod get = httpGet("/notebook/" + note.getId() + "/paragraph/" + p.getId());
LOG.info("testGetParagraph response\n" + get.getResponseBodyAsString());
assertThat("Test get method: ", get, isAllowed());
get.releaseConnection();
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");
assertEquals(p.getId(), body.get("id"));
assertEquals("hello", body.get("title"));
assertEquals("world", body.get("text"));
}
@Test
public void testMoveParagraph() throws IOException {
Note note = ZeppelinServer.notebook.createNote();
Paragraph p = note.addParagraph();
p.setTitle("title1");
p.setText("text1");
Paragraph p2 = note.addParagraph();
p.setTitle("title2");
p.setText("text2");
note.persist();
PostMethod post = httpPost("/notebook/" + note.getId() + "/paragraph/" + p2.getId() + "/move/" + 0, "");
assertThat("Test post method: ", post, isAllowed());
post.releaseConnection();
Note retrNote = ZeppelinServer.notebook.getNote(note.getId());
Paragraph paragraphAtIdx0 = retrNote.getParagraphs().get(0);
assertEquals(p2.getId(), paragraphAtIdx0.getId());
assertEquals(p2.getTitle(), paragraphAtIdx0.getTitle());
assertEquals(p2.getText(), paragraphAtIdx0.getText());
}
@Test
public void testDeleteParagraph() throws IOException {
Note note = ZeppelinServer.notebook.createNote();
Paragraph p = note.addParagraph();
p.setTitle("title1");
p.setText("text1");
note.persist();
DeleteMethod delete = httpDelete("/notebook/" + note.getId() + "/paragraph/" + p.getId());
assertThat("Test delete method: ", delete, isAllowed());
delete.releaseConnection();
Note retrNote = ZeppelinServer.notebook.getNote(note.getId());
Paragraph retrParagrah = retrNote.getParagraph(p.getId());
assertNull("paragraph should be deleted", retrParagrah);
}
}