| /* |
| * 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.client; |
| |
| import kong.unirest.GetRequest; |
| import kong.unirest.HttpResponse; |
| import kong.unirest.JsonNode; |
| import kong.unirest.Unirest; |
| import kong.unirest.apache.ApacheClient; |
| import kong.unirest.json.JSONArray; |
| import kong.unirest.json.JSONObject; |
| import org.apache.commons.text.StringEscapeUtils; |
| import org.apache.http.conn.ssl.NoopHostnameVerifier; |
| import org.apache.http.conn.ssl.TrustSelfSignedStrategy; |
| import org.apache.http.ssl.SSLContextBuilder; |
| import org.apache.zeppelin.common.SessionInfo; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| import unirest.shaded.org.apache.http.client.HttpClient; |
| import unirest.shaded.org.apache.http.impl.client.HttpClients; |
| |
| import javax.net.ssl.SSLContext; |
| import java.security.cert.X509Certificate; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| /** |
| * Low level api for interacting with Zeppelin. Underneath, it use the zeppelin rest api. |
| * You can use this class to operate Zeppelin note/paragraph, |
| * e.g. get/add/delete/update/execute/cancel |
| */ |
| public class ZeppelinClient { |
| private static final Logger LOGGER = LoggerFactory.getLogger(ZeppelinClient.class); |
| |
| private ClientConfig clientConfig; |
| |
| public ZeppelinClient(ClientConfig clientConfig) throws Exception { |
| this.clientConfig = clientConfig; |
| Unirest.config().defaultBaseUrl(clientConfig.getZeppelinRestUrl() + "/api"); |
| |
| if (clientConfig.isUseKnox()) { |
| try { |
| SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustSelfSignedStrategy() { |
| public boolean isTrusted(X509Certificate[] chain, String authType) { |
| return true; |
| } |
| }).build(); |
| HttpClient customHttpClient = HttpClients.custom().setSSLContext(sslContext) |
| .setSSLHostnameVerifier(new NoopHostnameVerifier()).build(); |
| Unirest.config().httpClient(ApacheClient.builder(customHttpClient)); |
| } catch (Exception e) { |
| throw new Exception("Fail to setup httpclient of Unirest", e); |
| } |
| } |
| } |
| |
| public ClientConfig getClientConfig() { |
| return clientConfig; |
| } |
| |
| /** |
| * Throw exception if the status code is not 200. |
| * |
| * @param response |
| * @throws Exception |
| */ |
| private void checkResponse(HttpResponse<JsonNode> response) throws Exception { |
| if (response.getStatus() == 302) { |
| throw new Exception("Please login first"); |
| } |
| if (response.getStatus() != 200) { |
| String message = response.getStatusText(); |
| if (response.getBody() != null && |
| response.getBody().getObject() != null && |
| response.getBody().getObject().has("message")) { |
| message = response.getBody().getObject().getString("message"); |
| } |
| throw new Exception(String.format("Unable to call rest api, status: %s, statusText: %s, message: %s", |
| response.getStatus(), |
| response.getStatusText(), |
| message)); |
| } |
| } |
| |
| /** |
| * Throw exception if the status in the json object is not `OK`. |
| * |
| * @param jsonNode |
| * @throws Exception |
| */ |
| private void checkJsonNodeStatus(JsonNode jsonNode) throws Exception { |
| if (! "OK".equalsIgnoreCase(jsonNode.getObject().getString("status"))) { |
| throw new Exception(StringEscapeUtils.unescapeJava(jsonNode.getObject().getString("message"))); |
| } |
| } |
| |
| /** |
| * Get Zeppelin version. |
| * |
| * @return |
| * @throws Exception |
| */ |
| public String getVersion() throws Exception { |
| HttpResponse<JsonNode> response = Unirest |
| .get("/version") |
| .asJson(); |
| checkResponse(response); |
| JsonNode jsonNode = response.getBody(); |
| checkJsonNodeStatus(jsonNode); |
| return jsonNode.getObject().getJSONObject("body").getString("version"); |
| } |
| |
| /** |
| * Request a new session id. It doesn't create session (interpreter process) in zeppelin server side, but just |
| * create an unique session id. |
| * |
| * @param interpreter |
| * @return |
| * @throws Exception |
| */ |
| public SessionInfo newSession(String interpreter) throws Exception { |
| HttpResponse<JsonNode> response = Unirest |
| .post("/session") |
| .queryString("interpreter", interpreter) |
| .asJson(); |
| checkResponse(response); |
| JsonNode jsonNode = response.getBody(); |
| checkJsonNodeStatus(jsonNode); |
| return createSessionInfoFromJson(jsonNode.getObject().getJSONObject("body")); |
| } |
| |
| /** |
| * Stop the session(interpreter process) in Zeppelin server. |
| * |
| * @param sessionId |
| * @throws Exception |
| */ |
| public void stopSession(String sessionId) throws Exception { |
| HttpResponse<JsonNode> response = Unirest |
| .delete("/session/{sessionId}") |
| .routeParam("sessionId", sessionId) |
| .asJson(); |
| checkResponse(response); |
| JsonNode jsonNode = response.getBody(); |
| checkJsonNodeStatus(jsonNode); |
| } |
| |
| /** |
| * Get session info for the provided sessionId. |
| * Return null if provided sessionId doesn't exist. |
| * |
| * @param sessionId |
| * @throws Exception |
| */ |
| public SessionInfo getSession(String sessionId) throws Exception { |
| HttpResponse<JsonNode> response = Unirest |
| .get("/session/{sessionId}") |
| .routeParam("sessionId", sessionId) |
| .asJson(); |
| if (response.getStatus() == 404) { |
| String statusText = response.getStatusText(); |
| if (response.getBody().getObject().has("message")) { |
| statusText = response.getBody().getObject().getString("message"); |
| } |
| if (statusText.contains("No such session")) { |
| return null; |
| } |
| } |
| checkResponse(response); |
| JsonNode jsonNode = response.getBody(); |
| checkJsonNodeStatus(jsonNode); |
| |
| JSONObject bodyObject = jsonNode.getObject().getJSONObject("body"); |
| return createSessionInfoFromJson(bodyObject); |
| } |
| |
| /** |
| * List all the sessions. |
| * |
| * @return |
| * @throws Exception |
| */ |
| public List<SessionInfo> listSessions() throws Exception { |
| return listSessions(null); |
| } |
| |
| /** |
| * List all the sessions for the provided interpreter. |
| * |
| * @param interpreter |
| * @return |
| * @throws Exception |
| */ |
| public List<SessionInfo> listSessions(String interpreter) throws Exception { |
| GetRequest getRequest = Unirest.get("/session"); |
| if (interpreter != null) { |
| getRequest.queryString("interpreter", interpreter); |
| } |
| HttpResponse<JsonNode> response = getRequest.asJson(); |
| checkResponse(response); |
| JsonNode jsonNode = response.getBody(); |
| checkJsonNodeStatus(jsonNode); |
| JSONArray sessionJsonArray = jsonNode.getObject().getJSONArray("body"); |
| List<SessionInfo> sessionInfos = new ArrayList<>(); |
| for (int i = 0; i< sessionJsonArray.length();++i) { |
| sessionInfos.add(createSessionInfoFromJson(sessionJsonArray.getJSONObject(i))); |
| } |
| return sessionInfos; |
| } |
| |
| private SessionInfo createSessionInfoFromJson(JSONObject sessionJson) { |
| SessionInfo sessionInfo = new SessionInfo(); |
| if (sessionJson.has("sessionId")) { |
| sessionInfo.setSessionId(sessionJson.getString("sessionId")); |
| } |
| if (sessionJson.has("noteId")) { |
| sessionInfo.setNoteId(sessionJson.getString("noteId")); |
| } |
| if (sessionJson.has("interpreter")) { |
| sessionInfo.setInterpreter(sessionJson.getString("interpreter")); |
| } |
| if (sessionJson.has("state")) { |
| sessionInfo.setState(sessionJson.getString("state")); |
| } |
| if (sessionJson.has("weburl")) { |
| sessionInfo.setWeburl(sessionJson.getString("weburl")); |
| } |
| if (sessionJson.has("startTime")) { |
| sessionInfo.setStartTime(sessionJson.getString("startTime")); |
| } |
| |
| return sessionInfo; |
| } |
| |
| /** |
| * Login zeppelin with userName and password, throw exception if login fails. |
| * |
| * @param userName |
| * @param password |
| * @throws Exception |
| */ |
| public void login(String userName, String password) throws Exception { |
| if (clientConfig.isUseKnox()) { |
| HttpResponse<String> response = Unirest.get(clientConfig.getKnoxSSOUrl() + |
| "?originalUrl=" + clientConfig.getZeppelinRestUrl()) |
| .basicAuth(userName, password) |
| .asString(); |
| if (response.getStatus() != 200) { |
| throw new Exception(String.format("Knox SSO login failed, status: %s, statusText: %s", |
| response.getStatus(), |
| response.getStatusText())); |
| } |
| response = Unirest.get("/security/ticket") |
| .asString(); |
| if (response.getStatus() != 200) { |
| throw new Exception(String.format("Fail to get ticket after Knox SSO, status: %s, statusText: %s", |
| response.getStatus(), |
| response.getStatusText())); |
| } |
| } else { |
| HttpResponse<JsonNode> response = Unirest |
| .post("/login") |
| .field("userName", userName) |
| .field("password", password) |
| .asJson(); |
| if (response.getStatus() != 200) { |
| throw new Exception(String.format("Login failed, status: %s, statusText: %s", |
| response.getStatus(), |
| response.getStatusText())); |
| } |
| } |
| } |
| |
| public String createNote(String notePath) throws Exception { |
| return createNote(notePath, ""); |
| } |
| |
| /** |
| * Create a new empty note with provided notePath and defaultInterpreterGroup |
| * |
| * @param notePath |
| * @param defaultInterpreterGroup |
| * @return |
| * @throws Exception |
| */ |
| public String createNote(String notePath, String defaultInterpreterGroup) throws Exception { |
| JSONObject bodyObject = new JSONObject(); |
| bodyObject.put("name", notePath); |
| bodyObject.put("defaultInterpreterGroup", defaultInterpreterGroup); |
| HttpResponse<JsonNode> response = Unirest |
| .post("/notebook") |
| .body(bodyObject.toString()) |
| .asJson(); |
| checkResponse(response); |
| JsonNode jsonNode = response.getBody(); |
| checkJsonNodeStatus(jsonNode); |
| |
| return jsonNode.getObject().getString("body"); |
| } |
| |
| /** |
| * Delete note with provided noteId. |
| * |
| * @param noteId |
| * @throws Exception |
| */ |
| public void deleteNote(String noteId) throws Exception { |
| HttpResponse<JsonNode> response = Unirest |
| .delete("/notebook/{noteId}") |
| .routeParam("noteId", noteId) |
| .asJson(); |
| checkResponse(response); |
| JsonNode jsonNode = response.getBody(); |
| checkJsonNodeStatus(jsonNode); |
| } |
| |
| /** |
| * Clone a note to a specified notePath. |
| * |
| * @param noteId |
| * @param destPath |
| * @return |
| * @throws Exception |
| */ |
| public String cloneNote(String noteId, String destPath) throws Exception { |
| JSONObject bodyObject = new JSONObject(); |
| bodyObject.put("name", destPath); |
| HttpResponse<JsonNode> response = Unirest |
| .post("/notebook/{noteId}") |
| .routeParam("noteId", noteId) |
| .body(bodyObject.toString()) |
| .asJson(); |
| checkResponse(response); |
| JsonNode jsonNode = response.getBody(); |
| checkJsonNodeStatus(jsonNode); |
| |
| return jsonNode.getObject().getString("body"); |
| } |
| |
| public void renameNote(String noteId, String newNotePath) throws Exception { |
| JSONObject bodyObject = new JSONObject(); |
| bodyObject.put("name", newNotePath); |
| |
| HttpResponse<JsonNode> response = Unirest |
| .put("/notebook/{noteId}/rename") |
| .routeParam("noteId", noteId) |
| .body(bodyObject.toString()) |
| .asJson(); |
| |
| checkResponse(response); |
| JsonNode jsonNode = response.getBody(); |
| checkJsonNodeStatus(jsonNode); |
| } |
| |
| /** |
| * Query {@link NoteResult} with provided noteId. |
| * |
| * @param noteId |
| * @return |
| * @throws Exception |
| */ |
| public NoteResult queryNoteResult(String noteId) throws Exception { |
| HttpResponse<JsonNode> response = Unirest |
| .get("/notebook/{noteId}") |
| .routeParam("noteId", noteId) |
| .asJson(); |
| return extractNoteResultFromResponse(response); |
| } |
| |
| /** |
| * Query {@link NoteResult} with provided notePath. |
| * |
| * @param notePath |
| * @return |
| * @throws Exception |
| */ |
| public NoteResult queryNoteResultByPath(String notePath) throws Exception { |
| JSONObject bodyObject = new JSONObject(); |
| bodyObject.put("notePath", notePath); |
| HttpResponse<JsonNode> response = Unirest |
| .post("/notebook/getByPath") |
| .body(bodyObject) |
| .asJson(); |
| return extractNoteResultFromResponse(response); |
| } |
| |
| private NoteResult extractNoteResultFromResponse(HttpResponse<JsonNode> response) throws Exception { |
| checkResponse(response); |
| JsonNode jsonNode = response.getBody(); |
| checkJsonNodeStatus(jsonNode); |
| |
| JSONObject noteJsonObject = jsonNode.getObject().getJSONObject("body"); |
| boolean isRunning = false; |
| if (noteJsonObject.has("info")) { |
| JSONObject infoJsonObject = noteJsonObject.getJSONObject("info"); |
| if (infoJsonObject.has("isRunning")) { |
| isRunning = Boolean.parseBoolean(infoJsonObject.getString("isRunning")); |
| } |
| } |
| String noteId = null; |
| if (noteJsonObject.has("id")) { |
| noteId = noteJsonObject.getString("id"); |
| } |
| |
| String notePath = null; |
| if (noteJsonObject.has("path")) { |
| notePath = noteJsonObject.getString("path"); |
| } |
| |
| List<ParagraphResult> paragraphResultList = new ArrayList<>(); |
| if (noteJsonObject.has("paragraphs")) { |
| JSONArray paragraphJsonArray = noteJsonObject.getJSONArray("paragraphs"); |
| for (int i = 0; i< paragraphJsonArray.length(); ++i) { |
| paragraphResultList.add(new ParagraphResult(paragraphJsonArray.getJSONObject(i))); |
| } |
| } |
| |
| return new NoteResult(noteId, notePath, isRunning, paragraphResultList); |
| } |
| |
| /** |
| * Execute note with provided noteId, return until note execution is completed. |
| * Interpreter process will be stopped after note execution. |
| * |
| * @param noteId |
| * @return |
| * @throws Exception |
| */ |
| public NoteResult executeNote(String noteId) throws Exception { |
| return executeNote(noteId, new HashMap<>()); |
| } |
| |
| /** |
| * Execute note with provided noteId and parameters, return until note execution is completed. |
| * Interpreter process will be stopped after note execution. |
| * |
| * @param noteId |
| * @param parameters |
| * @return |
| * @throws Exception |
| */ |
| public NoteResult executeNote(String noteId, Map<String, String> parameters) throws Exception { |
| submitNote(noteId, parameters); |
| return waitUntilNoteFinished(noteId); |
| } |
| |
| /** |
| * Submit note to execute with provided noteId, return at once the submission is completed. |
| * You need to query {@link NoteResult} by yourself afterwards until note execution is completed. |
| * Interpreter process will be stopped after note execution. |
| * |
| * @param noteId |
| * @return |
| * @throws Exception |
| */ |
| public NoteResult submitNote(String noteId) throws Exception { |
| return submitNote(noteId, new HashMap<>()); |
| } |
| |
| /** |
| * Submit note to execute with provided noteId and parameters, return at once the submission is completed. |
| * You need to query {@link NoteResult} by yourself afterwards until note execution is completed. |
| * Interpreter process will be stopped after note execution. |
| * |
| * @param noteId |
| * @param parameters |
| * @return |
| * @throws Exception |
| */ |
| public NoteResult submitNote(String noteId, Map<String, String> parameters) throws Exception { |
| JSONObject bodyObject = new JSONObject(); |
| bodyObject.put("params", parameters); |
| // run note in non-blocking and isolated way. |
| HttpResponse<JsonNode> response = Unirest |
| .post("/notebook/job/{noteId}") |
| .routeParam("noteId", noteId) |
| .queryString("blocking", "false") |
| .queryString("isolated", "true") |
| .body(bodyObject) |
| .asJson(); |
| checkResponse(response); |
| JsonNode jsonNode = response.getBody(); |
| checkJsonNodeStatus(jsonNode); |
| return queryNoteResult(noteId); |
| } |
| |
| /** |
| * Cancel a running note. |
| * |
| * @param noteId |
| * @throws Exception |
| */ |
| public void cancelNote(String noteId) throws Exception { |
| HttpResponse<JsonNode> response = Unirest |
| .delete("/notebook/job/{noteId}") |
| .routeParam("noteId", noteId) |
| .asJson(); |
| checkResponse(response); |
| JsonNode jsonNode = response.getBody(); |
| checkJsonNodeStatus(jsonNode); |
| } |
| |
| /** |
| * Import note with given note json content to the specified notePath. |
| * |
| * @param notePath |
| * @param noteContent |
| * @return |
| * @throws Exception |
| */ |
| public String importNote(String notePath, String noteContent) throws Exception { |
| JSONObject bodyObject = new JSONObject(noteContent); |
| HttpResponse<JsonNode> response = Unirest |
| .post("/notebook/import") |
| .queryString("notePath", notePath) |
| .body(bodyObject) |
| .asJson(); |
| checkResponse(response); |
| JsonNode jsonNode = response.getBody(); |
| checkJsonNodeStatus(jsonNode); |
| return jsonNode.getObject().getString("body"); |
| } |
| |
| /** |
| * Block there until note execution is completed. |
| * |
| * @param noteId |
| * @return |
| * @throws Exception |
| */ |
| public NoteResult waitUntilNoteFinished(String noteId) throws Exception { |
| while (true) { |
| NoteResult noteResult = queryNoteResult(noteId); |
| if (!noteResult.isRunning()) { |
| return noteResult; |
| } |
| Thread.sleep(clientConfig.getQueryInterval()); |
| } |
| } |
| |
| /** |
| * Block there until note execution is completed, and throw exception if note execution is not completed |
| * in <code>timeoutInMills</code>. |
| * |
| * @param noteId |
| * @param timeoutInMills |
| * @return |
| * @throws Exception |
| */ |
| public NoteResult waitUntilNoteFinished(String noteId, long timeoutInMills) throws Exception { |
| long start = System.currentTimeMillis(); |
| while (true && (System.currentTimeMillis() - start) < timeoutInMills) { |
| NoteResult noteResult = queryNoteResult(noteId); |
| if (!noteResult.isRunning()) { |
| return noteResult; |
| } |
| Thread.sleep(clientConfig.getQueryInterval()); |
| } |
| throw new Exception("Note is not finished in " + timeoutInMills / 1000 + " seconds"); |
| } |
| |
| /** |
| * Add paragraph to note with provided title and text. |
| * |
| * @param noteId |
| * @param title |
| * @param text |
| * @return |
| * @throws Exception |
| */ |
| public String addParagraph(String noteId, String title, String text) throws Exception { |
| JSONObject bodyObject = new JSONObject(); |
| bodyObject.put("title", title); |
| bodyObject.put("text", text); |
| HttpResponse<JsonNode> response = Unirest.post("/notebook/{noteId}/paragraph") |
| .routeParam("noteId", noteId) |
| .body(bodyObject.toString()) |
| .asJson(); |
| checkResponse(response); |
| JsonNode jsonNode = response.getBody(); |
| checkJsonNodeStatus(jsonNode); |
| |
| return jsonNode.getObject().getString("body"); |
| } |
| |
| /** |
| * Update paragraph with specified title and text. |
| * |
| * @param noteId |
| * @param paragraphId |
| * @param title |
| * @param text |
| * @throws Exception |
| */ |
| public void updateParagraph(String noteId, String paragraphId, String title, String text) throws Exception { |
| JSONObject bodyObject = new JSONObject(); |
| bodyObject.put("title", title); |
| bodyObject.put("text", text); |
| HttpResponse<JsonNode> response = Unirest.put("/notebook/{noteId}/paragraph/{paragraphId}") |
| .routeParam("noteId", noteId) |
| .routeParam("paragraphId", paragraphId) |
| .body(bodyObject.toString()) |
| .asJson(); |
| checkResponse(response); |
| JsonNode jsonNode = response.getBody(); |
| checkJsonNodeStatus(jsonNode); |
| } |
| |
| /** |
| * Execute paragraph with parameters in specified session. If sessionId is null or empty string, then it depends on |
| * the interpreter binding mode of Note(e.g. isolated per note), otherwise it will run in the specified session. |
| * |
| * @param noteId |
| * @param paragraphId |
| * @param sessionId |
| * @param parameters |
| * @return |
| * @throws Exception |
| */ |
| public ParagraphResult executeParagraph(String noteId, |
| String paragraphId, |
| String sessionId, |
| Map<String, String> parameters) throws Exception { |
| submitParagraph(noteId, paragraphId, sessionId, parameters); |
| return waitUtilParagraphFinish(noteId, paragraphId); |
| } |
| |
| /** |
| * Execute paragraph with parameters. |
| * |
| * @param noteId |
| * @param paragraphId |
| * @param parameters |
| * @return |
| * @throws Exception |
| */ |
| public ParagraphResult executeParagraph(String noteId, |
| String paragraphId, |
| Map<String, String> parameters) throws Exception { |
| return executeParagraph(noteId, paragraphId, "", parameters); |
| } |
| |
| /** |
| * Execute paragraph in specified session. If sessionId is null or empty string, then it depends on |
| * the interpreter binding mode of Note (e.g. isolated per note), otherwise it will run in the specified session. |
| * |
| * @param noteId |
| * @param paragraphId |
| * @param sessionId |
| * @return |
| * @throws Exception |
| */ |
| public ParagraphResult executeParagraph(String noteId, |
| String paragraphId, |
| String sessionId) throws Exception { |
| return executeParagraph(noteId, paragraphId, sessionId, new HashMap<>()); |
| } |
| |
| /** |
| * Execute paragraph. |
| * |
| * @param noteId |
| * @param paragraphId |
| * @return |
| * @throws Exception |
| */ |
| public ParagraphResult executeParagraph(String noteId, String paragraphId) throws Exception { |
| return executeParagraph(noteId, paragraphId, "", new HashMap<>()); |
| } |
| |
| /** |
| * Submit paragraph to execute with provided parameters and sessionId. Return at once the submission is completed. |
| * You need to query {@link ParagraphResult} by yourself afterwards until paragraph execution is completed. |
| * |
| * @param noteId |
| * @param paragraphId |
| * @param sessionId |
| * @param parameters |
| * @return |
| * @throws Exception |
| */ |
| public ParagraphResult submitParagraph(String noteId, |
| String paragraphId, |
| String sessionId, |
| Map<String, String> parameters) throws Exception { |
| JSONObject bodyObject = new JSONObject(); |
| bodyObject.put("params", parameters); |
| HttpResponse<JsonNode> response = Unirest |
| .post("/notebook/job/{noteId}/{paragraphId}") |
| .routeParam("noteId", noteId) |
| .routeParam("paragraphId", paragraphId) |
| .queryString("sessionId", sessionId) |
| .body(bodyObject.toString()) |
| .asJson(); |
| checkResponse(response); |
| JsonNode jsonNode = response.getBody(); |
| checkJsonNodeStatus(jsonNode); |
| return queryParagraphResult(noteId, paragraphId); |
| } |
| |
| /** |
| * Submit paragraph to execute with provided sessionId. Return at once the submission is completed. |
| * You need to query {@link ParagraphResult} by yourself afterwards until paragraph execution is completed. |
| * |
| * @param noteId |
| * @param paragraphId |
| * @param sessionId |
| * @return |
| * @throws Exception |
| */ |
| public ParagraphResult submitParagraph(String noteId, |
| String paragraphId, |
| String sessionId) throws Exception { |
| return submitParagraph(noteId, paragraphId, sessionId, new HashMap<>()); |
| } |
| |
| /** |
| * Submit paragraph to execute with provided parameters. Return at once the submission is completed. |
| * You need to query {@link ParagraphResult} by yourself afterwards until paragraph execution is completed. |
| * |
| * @param noteId |
| * @param paragraphId |
| * @param parameters |
| * @return |
| * @throws Exception |
| */ |
| public ParagraphResult submitParagraph(String noteId, |
| String paragraphId, |
| Map<String, String> parameters) throws Exception { |
| return submitParagraph(noteId, paragraphId, "", parameters); |
| } |
| |
| /** |
| * Submit paragraph to execute. Return at once the submission is completed. |
| * You need to query {@link ParagraphResult} by yourself afterwards until paragraph execution is completed. |
| * |
| * @param noteId |
| * @param paragraphId |
| * @return |
| * @throws Exception |
| */ |
| public ParagraphResult submitParagraph(String noteId, String paragraphId) throws Exception { |
| return submitParagraph(noteId, paragraphId, "", new HashMap<>()); |
| } |
| |
| /** |
| * This used by {@link ZSession} for creating or reusing a paragraph for executing another piece of code. |
| * |
| * @param noteId |
| * @param maxParagraph |
| * @return |
| * @throws Exception |
| */ |
| public String nextSessionParagraph(String noteId, int maxParagraph) throws Exception { |
| HttpResponse<JsonNode> response = Unirest |
| .post("/notebook/{noteId}/paragraph/next") |
| .routeParam("noteId", noteId) |
| .queryString("maxParagraph", maxParagraph) |
| .asJson(); |
| checkResponse(response); |
| JsonNode jsonNode = response.getBody(); |
| checkJsonNodeStatus(jsonNode); |
| |
| return jsonNode.getObject().getString("message"); |
| } |
| |
| /** |
| * Cancel a running paragraph. |
| * |
| * @param noteId |
| * @param paragraphId |
| * @throws Exception |
| */ |
| public void cancelParagraph(String noteId, String paragraphId) throws Exception { |
| HttpResponse<JsonNode> response = Unirest |
| .delete("/notebook/job/{noteId}/{paragraphId}") |
| .routeParam("noteId", noteId) |
| .routeParam("paragraphId", paragraphId) |
| .asJson(); |
| checkResponse(response); |
| JsonNode jsonNode = response.getBody(); |
| checkJsonNodeStatus(jsonNode); |
| } |
| |
| /** |
| * Query {@link ParagraphResult} |
| * |
| * @param noteId |
| * @param paragraphId |
| * @return |
| * @throws Exception |
| */ |
| public ParagraphResult queryParagraphResult(String noteId, String paragraphId) throws Exception { |
| HttpResponse<JsonNode> response = Unirest |
| .get("/notebook/{noteId}/paragraph/{paragraphId}") |
| .routeParam("noteId", noteId) |
| .routeParam("paragraphId", paragraphId) |
| .asJson(); |
| checkResponse(response); |
| JsonNode jsonNode = response.getBody(); |
| checkJsonNodeStatus(jsonNode); |
| |
| JSONObject paragraphJson = jsonNode.getObject().getJSONObject("body"); |
| return new ParagraphResult(paragraphJson); |
| } |
| |
| /** |
| * Query {@link ParagraphResult} until it is finished. |
| * |
| * @param noteId |
| * @param paragraphId |
| * @return |
| * @throws Exception |
| */ |
| public ParagraphResult waitUtilParagraphFinish(String noteId, String paragraphId) throws Exception { |
| while (true) { |
| ParagraphResult paragraphResult = queryParagraphResult(noteId, paragraphId); |
| LOGGER.debug(paragraphResult.toString()); |
| if (paragraphResult.getStatus().isCompleted()) { |
| return paragraphResult; |
| } |
| Thread.sleep(clientConfig.getQueryInterval()); |
| } |
| } |
| |
| /** |
| * Query {@link ParagraphResult} until it is finished or timeout. |
| * |
| * @param noteId |
| * @param paragraphId |
| * @param timeoutInMills |
| * @return |
| * @throws Exception |
| */ |
| public ParagraphResult waitUtilParagraphFinish(String noteId, String paragraphId, long timeoutInMills) throws Exception { |
| long start = System.currentTimeMillis(); |
| while (true && (System.currentTimeMillis() - start) < timeoutInMills) { |
| ParagraphResult paragraphResult = queryParagraphResult(noteId, paragraphId); |
| if (paragraphResult.getStatus().isCompleted()) { |
| return paragraphResult; |
| } |
| Thread.sleep(clientConfig.getQueryInterval()); |
| } |
| throw new Exception("Paragraph is not finished in " + timeoutInMills / 1000 + " seconds"); |
| } |
| |
| /** |
| * Query {@link ParagraphResult} until it is running. |
| * |
| * @param noteId |
| * @param paragraphId |
| * @return |
| * @throws Exception |
| */ |
| public ParagraphResult waitUtilParagraphRunning(String noteId, String paragraphId) throws Exception { |
| while (true) { |
| ParagraphResult paragraphResult = queryParagraphResult(noteId, paragraphId); |
| if (paragraphResult.getStatus().isRunning()) { |
| return paragraphResult; |
| } |
| Thread.sleep(clientConfig.getQueryInterval()); |
| } |
| } |
| |
| /** |
| * This is equal to the restart operation in note page. |
| * |
| * @param noteId |
| * @param interpreter |
| */ |
| public void stopInterpreter(String noteId, String interpreter) throws Exception { |
| JSONObject bodyObject = new JSONObject(); |
| bodyObject.put("noteId", noteId); |
| HttpResponse<JsonNode> response = Unirest |
| .put("/interpreter/setting/restart/{interpreter}") |
| .routeParam("interpreter", interpreter) |
| .body(bodyObject.toString()) |
| .asJson(); |
| checkResponse(response); |
| JsonNode jsonNode = response.getBody(); |
| checkJsonNodeStatus(jsonNode); |
| } |
| } |