Till Westmann has submitted this change and it was merged. Change subject: More consistency between the HTTP APIs ......................................................................
More consistency between the HTTP APIs Change-Id: Ie0e58cac20c1976610f38796d06f0518a3174c50 Reviewed-on: https://asterix-gerrit.ics.uci.edu/1550 Sonar-Qube: Jenkins <[email protected]> Tested-by: Jenkins <[email protected]> Reviewed-by: abdullah alamoudi <[email protected]> BAD: Jenkins <[email protected]> Integration-Tests: Jenkins <[email protected]> --- M asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/AbstractQueryApiServlet.java M asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java M asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryStatusApiServlet.java M asterixdb/asterix-app/src/test/resources/runtimets/results/async-deferred/async-failed/async-failed.2.json M asterixdb/asterix-app/src/test/resources/runtimets/results/async-deferred/async-running/async-running.2.json D asterixdb/asterix-app/src/test/resources/runtimets/results/async-deferred/async-running/async-running.3.json A asterixdb/asterix-app/src/test/resources/runtimets/results/async-deferred/async-running/async-running.3.regex D asterixdb/asterix-app/src/test/resources/runtimets/results/async-deferred/async/async.2.json A asterixdb/asterix-app/src/test/resources/runtimets/results/async-deferred/async/async.2.regex D asterixdb/asterix-app/src/test/resources/runtimets/results/flwor/at00/at00.5.json A asterixdb/asterix-app/src/test/resources/runtimets/results/flwor/at00/at00.5.regex 11 files changed, 143 insertions(+), 109 deletions(-) Approvals: abdullah alamoudi: Looks good to me, approved Jenkins: Verified; No violations found; No violations found; Verified diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/AbstractQueryApiServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/AbstractQueryApiServlet.java index 8d934ee..f156de5 100644 --- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/AbstractQueryApiServlet.java +++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/AbstractQueryApiServlet.java @@ -22,6 +22,8 @@ import static org.apache.asterix.api.http.servlet.ServletConstants.HYRACKS_DATASET_ATTR; import java.io.IOException; +import java.io.PrintWriter; +import java.util.UUID; import java.util.concurrent.ConcurrentMap; import java.util.logging.Level; import java.util.logging.Logger; @@ -32,6 +34,7 @@ import org.apache.hyracks.api.client.IHyracksClientConnection; import org.apache.hyracks.api.dataset.IHyracksDataset; import org.apache.hyracks.client.dataset.HyracksDataset; +import org.apache.hyracks.http.api.IServletRequest; import org.apache.hyracks.http.server.AbstractServlet; import com.fasterxml.jackson.core.JsonProcessingException; @@ -39,6 +42,46 @@ import com.fasterxml.jackson.databind.ObjectMapper; class AbstractQueryApiServlet extends AbstractServlet { + + public enum ResultFields { + REQUEST_ID("requestID"), + CLIENT_ID("clientContextID"), + SIGNATURE("signature"), + TYPE("type"), + STATUS("status"), + RESULTS("results"), + HANDLE("handle"), + ERRORS("errors"), + METRICS("metrics"); + + private final String str; + + ResultFields(String str) { + this.str = str; + } + + public String str() { + return str; + } + } + + public enum ResultStatus { + RUNNING("running"), + SUCCESS("success"), + TIMEOUT("timeout"), + FAILED("failed"), + FATAL("fatal"); + + private final String str; + + ResultStatus(String str) { + this.str = str; + } + + public String str() { + return str; + } + } AbstractQueryApiServlet(ConcurrentMap<String, Object> ctx, String[] paths) { super(ctx, paths); @@ -82,4 +125,42 @@ } return null; } + + protected static UUID printRequestId(PrintWriter pw) { + UUID requestId = UUID.randomUUID(); + printField(pw, ResultFields.REQUEST_ID.str(), requestId.toString()); + return requestId; + } + + protected static void printStatus(PrintWriter pw, ResultStatus rs) { + printField(pw, ResultFields.STATUS.str(), rs.str()); + } + + protected static void printHandle(PrintWriter pw, String handle) { + printField(pw, ResultFields.HANDLE.str(), handle); + } + + protected static void printField(PrintWriter pw, String name, String value) { + printField(pw, name, value, true); + } + + protected static void printField(PrintWriter pw, String name, String value, boolean comma) { + printFieldInternal(pw, name, "\"" + value + "\"", comma); + } + + protected static void printField(PrintWriter pw, String name, long value, boolean comma) { + printFieldInternal(pw, name, String.valueOf(value), comma); + } + + protected static void printFieldInternal(PrintWriter pw, String name, String value, boolean comma) { + pw.print("\t\""); + pw.print(name); + pw.print("\": "); + pw.print(value); + if (comma) { + pw.print(','); + } + pw.print('\n'); + } + } diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java index c0a38e8..9d22452 100644 --- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java +++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java @@ -18,8 +18,6 @@ */ package org.apache.asterix.api.http.server; -import static org.apache.asterix.api.http.servlet.ServletConstants.HYRACKS_CONNECTION_ATTR; -import static org.apache.asterix.api.http.servlet.ServletConstants.HYRACKS_DATASET_ATTR; import static org.apache.asterix.translator.IStatementExecutor.ResultDelivery; import java.io.IOException; @@ -27,12 +25,10 @@ import java.io.StringWriter; import java.nio.charset.StandardCharsets; import java.util.List; -import java.util.UUID; import java.util.concurrent.ConcurrentMap; import java.util.logging.Level; import java.util.logging.Logger; -import org.apache.asterix.app.result.ResultReader; import org.apache.asterix.app.result.ResultUtil; import org.apache.asterix.common.api.IClusterManagementWork; import org.apache.asterix.common.config.GlobalConfig; @@ -51,12 +47,8 @@ import org.apache.asterix.translator.SessionConfig; import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException; import org.apache.hyracks.algebricks.core.algebra.prettyprint.AlgebricksAppendable; -import org.apache.hyracks.api.client.IHyracksClientConnection; -import org.apache.hyracks.api.dataset.IHyracksDataset; -import org.apache.hyracks.client.dataset.HyracksDataset; import org.apache.hyracks.http.api.IServletRequest; import org.apache.hyracks.http.api.IServletResponse; -import org.apache.hyracks.http.server.AbstractServlet; import org.apache.hyracks.http.server.utils.HttpUtil; import com.fasterxml.jackson.core.JsonParseException; @@ -66,10 +58,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; import io.netty.handler.codec.http.HttpHeaderNames; -import io.netty.handler.codec.http.HttpMethod; import io.netty.handler.codec.http.HttpResponseStatus; -public class QueryServiceServlet extends AbstractServlet { +public class QueryServiceServlet extends AbstractQueryApiServlet { private static final Logger LOGGER = Logger.getLogger(QueryServiceServlet.class.getName()); private final ILangCompilationProvider compilationProvider; private final IStatementExecutorFactory statementExecutorFactory; @@ -120,46 +111,6 @@ private final String str; Attribute(String str) { - this.str = str; - } - - public String str() { - return str; - } - } - - public enum ResultFields { - REQUEST_ID("requestID"), - CLIENT_ID("clientContextID"), - SIGNATURE("signature"), - TYPE("type"), - STATUS("status"), - RESULTS("results"), - HANDLE("handle"), - ERRORS("errors"), - METRICS("metrics"); - - private final String str; - - ResultFields(String str) { - this.str = str; - } - - public String str() { - return str; - } - } - - public enum ResultStatus { - STARTED("started"), - SUCCESS("success"), - TIMEOUT("timeout"), - ERRORS("errors"), - FATAL("fatal"); - - private final String str; - - ResultStatus(String str) { this.str = str; } @@ -327,35 +278,6 @@ return sessionConfig; } - private static void printField(PrintWriter pw, String name, String value) { - printField(pw, name, value, true); - } - - private static void printField(PrintWriter pw, String name, String value, boolean comma) { - printFieldInternal(pw, name, "\"" + value + "\"", comma); - } - - private static void printField(PrintWriter pw, String name, long value, boolean comma) { - printFieldInternal(pw, name, String.valueOf(value), comma); - } - - private static void printFieldInternal(PrintWriter pw, String name, String value, boolean comma) { - pw.print("\t\""); - pw.print(name); - pw.print("\": "); - pw.print(value); - if (comma) { - pw.print(','); - } - pw.print('\n'); - } - - private static UUID printRequestId(PrintWriter pw) { - UUID requestId = UUID.randomUUID(); - printField(pw, ResultFields.REQUEST_ID.str(), requestId.toString()); - return requestId; - } - private static void printClientContextID(PrintWriter pw, RequestParameters params) { if (params.clientContextID != null && !params.clientContextID.isEmpty()) { printField(pw, ResultFields.CLIENT_ID.str(), params.clientContextID); @@ -379,10 +301,6 @@ default: break; } - } - - private static void printStatus(PrintWriter pw, ResultStatus rs) { - printField(pw, ResultFields.STATUS.str(), rs.str()); } private static void printError(PrintWriter pw, Throwable e) throws JsonProcessingException { @@ -501,26 +419,15 @@ if (param.statement == null || param.statement.isEmpty()) { throw new AsterixException("Empty request, no statement provided"); } - IHyracksClientConnection hcc = (IHyracksClientConnection) ctx.get(HYRACKS_CONNECTION_ATTR); - IHyracksDataset hds = (IHyracksDataset) ctx.get(HYRACKS_DATASET_ATTR); - if (hds == null) { - synchronized (ctx) { - hds = (IHyracksDataset) ctx.get(HYRACKS_DATASET_ATTR); - if (hds == null) { - hds = new HyracksDataset(hcc, ResultReader.FRAME_SIZE, ResultReader.NUM_READERS); - ctx.put(HYRACKS_DATASET_ATTR, hds); - } - } - } IParser parser = compilationProvider.getParserFactory().createParser(param.statement); List<Statement> statements = parser.parse(); MetadataManager.INSTANCE.init(); IStatementExecutor translator = statementExecutorFactory.create(statements, sessionConfig, compilationProvider, componentProvider); execStart = System.nanoTime(); - translator.compileAndExecute(hcc, hds, delivery, stats); + translator.compileAndExecute(getHyracksClientConnection(), getHyracksDataset(), delivery, stats); execEnd = System.nanoTime(); - printStatus(resultWriter, ResultDelivery.ASYNC == delivery ? ResultStatus.STARTED : ResultStatus.SUCCESS); + printStatus(resultWriter, ResultDelivery.ASYNC == delivery ? ResultStatus.RUNNING : ResultStatus.SUCCESS); } catch (AsterixException | TokenMgrError | org.apache.asterix.aqlplus.parser.TokenMgrError pe) { GlobalConfig.ASTERIX_LOGGER.log(Level.SEVERE, pe.getMessage(), pe); printError(resultWriter, pe); diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryStatusApiServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryStatusApiServlet.java index 33c5c8f..9aa74c5 100644 --- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryStatusApiServlet.java +++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryStatusApiServlet.java @@ -18,6 +18,8 @@ */ package org.apache.asterix.api.http.server; +import java.io.PrintWriter; +import java.io.StringWriter; import java.util.concurrent.ConcurrentMap; import java.util.logging.Level; import java.util.logging.Logger; @@ -33,7 +35,6 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; import io.netty.handler.codec.http.HttpResponseStatus; @@ -59,16 +60,54 @@ IHyracksDataset hds = getHyracksDataset(); ResultReader resultReader = new ResultReader(hds, jobId, rsId); - ObjectNode jsonResponse = om.createObjectNode(); - final DatasetJobRecord.Status status = resultReader.getStatus(); - if (status == null) { + ResultStatus resultStatus = resultStatus(resultReader.getStatus()); + + if (resultStatus == null) { LOGGER.log(Level.INFO, "No results for: \"" + strHandle + "\""); response.setStatus(HttpResponseStatus.NOT_FOUND); return; } - jsonResponse.put("status", status.name()); - HttpUtil.setContentType(response, HttpUtil.ContentType.TEXT_PLAIN, HttpUtil.Encoding.UTF8); - response.setStatus(HttpResponseStatus.OK); - response.writer().write(jsonResponse.toString()); + + final StringWriter stringWriter = new StringWriter(); + final PrintWriter resultWriter = new PrintWriter(stringWriter); + + HttpUtil.setContentType(response, HttpUtil.ContentType.APPLICATION_JSON, HttpUtil.Encoding.UTF8); + HttpResponseStatus httpStatus = HttpResponseStatus.OK; + + resultWriter.print("{\n"); + printStatus(resultWriter, resultStatus); + + if (ResultStatus.SUCCESS == resultStatus) { + String servletPath = servletPath(request).replace("status", "result"); + String resHandle = "http://" + host(request) + servletPath + localPath(request); + printHandle(resultWriter, resHandle); + } + + resultWriter.print("}\n"); + resultWriter.flush(); + String result = stringWriter.toString(); + + response.setStatus(httpStatus); + response.writer().print(result); + if (response.writer().checkError()) { + LOGGER.warning("Error flushing output writer"); + } + } + + ResultStatus resultStatus(DatasetJobRecord.Status status) { + if (status == null) { + return null; + } + switch (status) { + case IDLE: + case RUNNING: + return ResultStatus.RUNNING; + case SUCCESS: + return ResultStatus.SUCCESS; + case FAILED: + return ResultStatus.FAILED; + default: + return ResultStatus.FATAL; + } } } diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/async-deferred/async-failed/async-failed.2.json b/asterixdb/asterix-app/src/test/resources/runtimets/results/async-deferred/async-failed/async-failed.2.json index dd665eb..246785b 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/results/async-deferred/async-failed/async-failed.2.json +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/async-deferred/async-failed/async-failed.2.json @@ -1 +1,3 @@ -{"status":"FAILED"} +{ + "status": "failed", +} diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/async-deferred/async-running/async-running.2.json b/asterixdb/asterix-app/src/test/resources/runtimets/results/async-deferred/async-running/async-running.2.json index 6cffe65..2dc2832 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/results/async-deferred/async-running/async-running.2.json +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/async-deferred/async-running/async-running.2.json @@ -1 +1,3 @@ -{"status":"RUNNING"} +{ + "status": "running", +} diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/async-deferred/async-running/async-running.3.json b/asterixdb/asterix-app/src/test/resources/runtimets/results/async-deferred/async-running/async-running.3.json deleted file mode 100644 index 6213a6b..0000000 --- a/asterixdb/asterix-app/src/test/resources/runtimets/results/async-deferred/async-running/async-running.3.json +++ /dev/null @@ -1 +0,0 @@ -{"status":"SUCCESS"} diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/async-deferred/async-running/async-running.3.regex b/asterixdb/asterix-app/src/test/resources/runtimets/results/async-deferred/async-running/async-running.3.regex new file mode 100644 index 0000000..4308ba2 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/async-deferred/async-running/async-running.3.regex @@ -0,0 +1,2 @@ +/"status": "success"/ +/"handle": ".*"/ diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/async-deferred/async/async.2.json b/asterixdb/asterix-app/src/test/resources/runtimets/results/async-deferred/async/async.2.json deleted file mode 100644 index 6213a6b..0000000 --- a/asterixdb/asterix-app/src/test/resources/runtimets/results/async-deferred/async/async.2.json +++ /dev/null @@ -1 +0,0 @@ -{"status":"SUCCESS"} diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/async-deferred/async/async.2.regex b/asterixdb/asterix-app/src/test/resources/runtimets/results/async-deferred/async/async.2.regex new file mode 100644 index 0000000..4308ba2 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/async-deferred/async/async.2.regex @@ -0,0 +1,2 @@ +/"status": "success"/ +/"handle": ".*"/ diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/flwor/at00/at00.5.json b/asterixdb/asterix-app/src/test/resources/runtimets/results/flwor/at00/at00.5.json deleted file mode 100644 index 6213a6b..0000000 --- a/asterixdb/asterix-app/src/test/resources/runtimets/results/flwor/at00/at00.5.json +++ /dev/null @@ -1 +0,0 @@ -{"status":"SUCCESS"} diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/flwor/at00/at00.5.regex b/asterixdb/asterix-app/src/test/resources/runtimets/results/flwor/at00/at00.5.regex new file mode 100644 index 0000000..4308ba2 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/flwor/at00/at00.5.regex @@ -0,0 +1,2 @@ +/"status": "success"/ +/"handle": ".*"/ -- To view, visit https://asterix-gerrit.ics.uci.edu/1550 To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ie0e58cac20c1976610f38796d06f0518a3174c50 Gerrit-PatchSet: 5 Gerrit-Project: asterixdb Gerrit-Branch: master Gerrit-Owner: Till Westmann <[email protected]> Gerrit-Reviewer: Jenkins <[email protected]> Gerrit-Reviewer: Till Westmann <[email protected]> Gerrit-Reviewer: abdullah alamoudi <[email protected]>
