mirror of
https://github.com/apache/zeppelin
synced 2026-05-24 09:38:26 +00:00
Add rest api for paragraph config update
This commit is contained in:
parent
cb175032a2
commit
c8357ca58e
4 changed files with 230 additions and 4 deletions
|
|
@ -808,6 +808,127 @@ If you work with Apache Zeppelin and find a need for an additional REST API, ple
|
|||
</tr>
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
### Update paragraph configuration
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```PUT``` method update paragraph configuration using given id so that user can change paragraph setting such as graph type, show or hide editor/result and paragraph size, etc. You can update certain fields you want, for example you can update <code>colWidth</code> field only by sending request with payload <code>{"colWidth": 12.0}</code>.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>URL</td>
|
||||
<td>```http://[zeppelin-server]:[zeppelin-port]/api/notebook/[noteId]/paragraph/[paragraphId]/config```</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Success code</td>
|
||||
<td>200</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Bad Request code</td>
|
||||
<td>400</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Forbidden code</td>
|
||||
<td>403</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Not Found code</td>
|
||||
<td>404</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Fail code</td>
|
||||
<td>500</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>sample JSON input</td>
|
||||
<td><pre>
|
||||
{
|
||||
"colWidth": 6.0,
|
||||
"graph": {
|
||||
"mode": "lineChart",
|
||||
"height": 200.0,
|
||||
"optionOpen": false,
|
||||
"keys": [
|
||||
{
|
||||
"name": "age",
|
||||
"index": 0.0,
|
||||
"aggr": "sum"
|
||||
}
|
||||
],
|
||||
"values": [
|
||||
{
|
||||
"name": "value",
|
||||
"index": 1.0,
|
||||
"aggr": "sum"
|
||||
}
|
||||
],
|
||||
"groups": [],
|
||||
"scatter": {}
|
||||
},
|
||||
"editorHide": true,
|
||||
"editorMode": "ace/mode/markdown",
|
||||
"tableHide": false
|
||||
}</pre></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>sample JSON response</td>
|
||||
<td><pre>
|
||||
{
|
||||
"status":"OK",
|
||||
"message":"",
|
||||
"body":{
|
||||
"text":"%sql \nselect age, count(1) value\nfrom bank \nwhere age \u003c 30 \ngroup by age \norder by age",
|
||||
"config":{
|
||||
"colWidth":6.0,
|
||||
"graph":{
|
||||
"mode":"lineChart",
|
||||
"height":200.0,
|
||||
"optionOpen":false,
|
||||
"keys":[
|
||||
{
|
||||
"name":"age",
|
||||
"index":0.0,
|
||||
"aggr":"sum"
|
||||
}
|
||||
],
|
||||
"values":[
|
||||
{
|
||||
"name":"value",
|
||||
"index":1.0,
|
||||
"aggr":"sum"
|
||||
}
|
||||
],
|
||||
"groups":[],
|
||||
"scatter":{}
|
||||
},
|
||||
"tableHide":false,
|
||||
"editorMode":"ace/mode/markdown",
|
||||
"editorHide":true
|
||||
},
|
||||
"settings":{
|
||||
"params":{},
|
||||
"forms":{}
|
||||
},
|
||||
"apps":[],
|
||||
"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
|
||||
}
|
||||
}</pre></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
### Move a paragraph to the specific index
|
||||
<table class="table-configuration">
|
||||
|
|
@ -835,7 +956,6 @@ If you work with Apache Zeppelin and find a need for an additional REST API, ple
|
|||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
<br/>
|
||||
### Delete a paragraph
|
||||
<table class="table-configuration">
|
||||
|
|
@ -934,7 +1054,8 @@ If you work with Apache Zeppelin and find a need for an additional REST API, ple
|
|||
<td> Fail code</td>
|
||||
<td> 500 </td>
|
||||
</tr>
|
||||
<td>sample JSON input</td>
|
||||
<tr>
|
||||
<td>sample JSON input</td>
|
||||
<td><pre>
|
||||
{
|
||||
"paragraphs": [
|
||||
|
|
@ -961,6 +1082,7 @@ If you work with Apache Zeppelin and find a need for an additional REST API, ple
|
|||
"config": {},
|
||||
"info": {}
|
||||
}</pre></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>sample JSON response</td>
|
||||
<td><pre>
|
||||
|
|
@ -970,7 +1092,6 @@ If you work with Apache Zeppelin and find a need for an additional REST API, ple
|
|||
"body": "2AZPHY918"
|
||||
}</pre></td>
|
||||
</tr>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br />
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ import org.apache.zeppelin.notebook.Note;
|
|||
import org.apache.zeppelin.notebook.Notebook;
|
||||
import org.apache.zeppelin.notebook.NotebookAuthorization;
|
||||
import org.apache.zeppelin.notebook.Paragraph;
|
||||
import org.apache.zeppelin.rest.exception.BadRequestException;
|
||||
import org.apache.zeppelin.rest.exception.NotFoundException;
|
||||
import org.apache.zeppelin.rest.exception.ForbiddenException;
|
||||
import org.apache.zeppelin.rest.message.CronRequest;
|
||||
|
|
@ -451,6 +452,38 @@ public class NotebookRestApi {
|
|||
return new JsonResponse<>(Status.OK, "", p).build();
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("{noteId}/paragraph/{paragraphId}/config")
|
||||
@ZeppelinApi
|
||||
public Response updateParagraphConfig(@PathParam("noteId") String noteId,
|
||||
@PathParam("paragraphId") String paragraphId, String message) throws IOException {
|
||||
String user = SecurityUtils.getPrincipal();
|
||||
LOG.info("{} will update paragraph config {} {}", user, noteId, paragraphId);
|
||||
|
||||
Note note = notebook.getNote(noteId);
|
||||
checkIfNoteIsNotNull(note);
|
||||
checkIfUserCanWrite(noteId, "Insufficient privileges you cannot update this paragraph config");
|
||||
Paragraph p = note.getParagraph(paragraphId);
|
||||
checkIfParagraphIsNotNull(p);
|
||||
|
||||
Map<String, Object> newConfig = gson.fromJson(message, HashMap.class);
|
||||
if (newConfig == null || newConfig.isEmpty()) {
|
||||
LOG.warn("{} is trying to update paragraph {} of note {} with empty config",
|
||||
user, paragraphId, noteId);
|
||||
throw new BadRequestException("paragraph config cannot be empty");
|
||||
}
|
||||
Map<String, Object> origConfig = p.getConfig();
|
||||
for (String key : newConfig.keySet()) {
|
||||
origConfig.put(key, newConfig.get(key));
|
||||
}
|
||||
|
||||
p.setConfig(origConfig);
|
||||
AuthenticationInfo subject = new AuthenticationInfo(user);
|
||||
note.persist(subject);
|
||||
|
||||
return new JsonResponse<>(Status.OK, "", p).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Move paragraph REST API
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* 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.exception;
|
||||
|
||||
import org.apache.zeppelin.utils.ExceptionUtils;
|
||||
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
|
||||
|
||||
/**
|
||||
* BadRequestException handler for WebApplicationException.
|
||||
*/
|
||||
public class BadRequestException extends WebApplicationException {
|
||||
|
||||
public BadRequestException() {
|
||||
super(ExceptionUtils.jsonResponse(BAD_REQUEST));
|
||||
}
|
||||
|
||||
private static Response badRequestJson(String message) {
|
||||
return ExceptionUtils.jsonResponseContent(BAD_REQUEST, message);
|
||||
}
|
||||
|
||||
public BadRequestException(Throwable cause, String message) {
|
||||
super(cause, badRequestJson(message));
|
||||
}
|
||||
|
||||
public BadRequestException(String message) {
|
||||
super(badRequestJson(message));
|
||||
}
|
||||
}
|
||||
|
|
@ -94,7 +94,7 @@ public class NotebookRestApiTest extends AbstractTestRestApi {
|
|||
Note note2 = ZeppelinServer.notebook.createNote(anonymous);
|
||||
// Set only writers
|
||||
jsonRequest = "{\"readers\":[],\"owners\":[]," +
|
||||
"\"writers\":[\"admin-team\"]}";
|
||||
"\"writers\":[\"admin-team\"]}";
|
||||
put = httpPut("/notebook/" + note2.getId() + "/permissions/", jsonRequest);
|
||||
assertThat("test update method:", put, isAllowed());
|
||||
put.releaseConnection();
|
||||
|
|
@ -175,7 +175,32 @@ public class NotebookRestApiTest extends AbstractTestRestApi {
|
|||
//cleanup
|
||||
ZeppelinServer.notebook.removeNote(note1.getId(), anonymous);
|
||||
ZeppelinServer.notebook.removeNote(clonedNoteId, anonymous);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateParagraphConfig() throws IOException {
|
||||
Note note = ZeppelinServer.notebook.createNote(anonymous);
|
||||
String noteId = note.getId();
|
||||
Paragraph p = note.addParagraph();
|
||||
assertNull(p.getConfig().get("colWidth"));
|
||||
String paragraphId = p.getId();
|
||||
String jsonRequest = "{\"colWidth\": 6.0}";
|
||||
|
||||
PutMethod put = httpPut("/notebook/" + noteId + "/paragraph/" + paragraphId +"/config", jsonRequest);
|
||||
assertThat("test testUpdateParagraphConfig:", put, isAllowed());
|
||||
|
||||
Map<String, Object> resp = gson.fromJson(put.getResponseBodyAsString(), new TypeToken<Map<String, Object>>() {
|
||||
}.getType());
|
||||
Map<String, Object> respBody = (Map<String, Object>) resp.get("body");
|
||||
Map<String, Object> config = (Map<String, Object>) respBody.get("config");
|
||||
put.releaseConnection();
|
||||
|
||||
assertEquals(config.get("colWidth"), 6.0);
|
||||
note = ZeppelinServer.notebook.getNote(noteId);
|
||||
assertEquals(note.getParagraph(paragraphId).getConfig().get("colWidth"), 6.0);
|
||||
|
||||
//cleanup
|
||||
ZeppelinServer.notebook.removeNote(noteId, anonymous);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
Loading…
Reference in a new issue