diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/ParametersRequest.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/ParametersRequest.java index 04e19a3772b..828c36c4749 100644 --- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/ParametersRequest.java +++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/ParametersRequest.java @@ -16,6 +16,7 @@ */ package org.apache.zeppelin.rest.message; +import java.util.Collections; import java.util.Map; /** @@ -29,7 +30,12 @@ public ParametersRequest(Map params) { this.params = params; } + /** + * Gson bypasses the constructor, so this field is null when the body carries no "params" entry. + * + * @return the parameters, or an empty map when none were supplied + */ public Map getParams() { - return params; + return params == null ? Collections.emptyMap() : params; } } diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/NotebookRestApiTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/NotebookRestApiTest.java index c93cc610d58..0257f8a69ef 100644 --- a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/NotebookRestApiTest.java +++ b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/NotebookRestApiTest.java @@ -890,6 +890,33 @@ void testRunNoteWithParams() throws IOException, InterruptedException { } } + @Test + void testRunNoteWithoutParamsInBody() throws IOException { + LOGGER.info("Running testRunNoteWithoutParamsInBody"); + String note1Id = null; + try { + note1Id = notebook.createNote("note1", anonymous); + + // Running a note without form parameters is valid. Gson leaves ParametersRequest#params + // null both when the key is absent and when it is an explicit null, so neither body may fail. + for (String body : new String[] {"{}", "{\"params\":null}"}) { + CloseableHttpResponse post = + httpPost("/notebook/job/" + note1Id + "?blocking=true&isolated=true", body); + assertThat(post, isAllowed()); + Map resp = gson.fromJson( + EntityUtils.toString(post.getEntity(), StandardCharsets.UTF_8), + new TypeToken>() {}.getType()); + assertEquals("OK", resp.get("status"), "Failed for request body: " + body); + post.close(); + } + } finally { + // cleanup + if (null != note1Id) { + notebook.removeNote(note1Id, anonymous); + } + } + } + @Test void testRunAllParagraph_FirstFailed() throws IOException { LOGGER.info("Running testRunAllParagraph_FirstFailed");