Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 0B11D200C08 for ; Thu, 26 Jan 2017 16:29:32 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id 09D46160B33; Thu, 26 Jan 2017 15:29:32 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id D90F6160B58 for ; Thu, 26 Jan 2017 16:29:29 +0100 (CET) Received: (qmail 37278 invoked by uid 500); 26 Jan 2017 15:29:29 -0000 Mailing-List: contact commits-help@asterixdb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@asterixdb.apache.org Delivered-To: mailing list commits@asterixdb.apache.org Received: (qmail 37144 invoked by uid 99); 26 Jan 2017 15:29:28 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 26 Jan 2017 15:29:28 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 8FA7BDFCC0; Thu, 26 Jan 2017 15:29:28 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: tillw@apache.org To: commits@asterixdb.apache.org Date: Thu, 26 Jan 2017 15:29:30 -0000 Message-Id: In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [3/5] asterixdb git commit: Replace Servlets with Netty Based HTTP Servers archived-at: Thu, 26 Jan 2017 15:29:32 -0000 http://git-wip-us.apache.org/repos/asf/asterixdb/blob/60e7f12b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ClusterNodeDetailsAPIServlet.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ClusterNodeDetailsAPIServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ClusterNodeDetailsAPIServlet.java deleted file mode 100644 index d737ad8..0000000 --- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ClusterNodeDetailsAPIServlet.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * 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.asterix.api.http.servlet; - -import static org.apache.asterix.api.http.servlet.ServletConstants.HYRACKS_CONNECTION_ATTR; - -import java.io.IOException; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; - -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; -import org.apache.asterix.runtime.util.ClusterStateManager; -import org.apache.hyracks.api.client.IHyracksClientConnection; -import com.fasterxml.jackson.databind.node.ArrayNode; - -import com.fasterxml.jackson.databind.node.ObjectNode; - -public class ClusterNodeDetailsAPIServlet extends ClusterAPIServlet { - private static final long serialVersionUID = 1L; - private static final Logger LOGGER = Logger.getLogger(ClusterNodeDetailsAPIServlet.class.getName()); - private final ObjectMapper om = new ObjectMapper(); - - @Override - public void init() throws ServletException{ - om.enable(SerializationFeature.INDENT_OUTPUT); - } - - @Override - protected void getUnsafe(HttpServletRequest request, HttpServletResponse response) throws IOException { - PrintWriter responseWriter = response.getWriter(); - ServletContext context = getServletContext(); - IHyracksClientConnection hcc = (IHyracksClientConnection) context.getAttribute(HYRACKS_CONNECTION_ATTR); - try { - ObjectNode json; - if (request.getPathInfo() == null) { - json = om.createObjectNode(); - json.set("ncs", getClusterStateJSON(request, "../").get("ncs")); - } else { - json = processNode(request, hcc); - } - response.setStatus(HttpServletResponse.SC_OK); - response.setContentType("application/json"); - response.setCharacterEncoding("utf-8"); - responseWriter.write(om.writerWithDefaultPrettyPrinter().writeValueAsString(json)); - } catch (IllegalStateException e) { // NOSONAR - exception not logged or rethrown - response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE); - } catch (IllegalArgumentException e) { // NOSONAR - exception not logged or rethrown - response.sendError(HttpServletResponse.SC_NOT_FOUND); - } catch (Exception e) { - LOGGER.log(Level.INFO, "exception thrown for " + request, e); - response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.toString()); - } - responseWriter.flush(); - } - - private ObjectNode processNode(HttpServletRequest request, IHyracksClientConnection hcc) - throws Exception { - String pathInfo = request.getPathInfo(); - if (pathInfo.endsWith("/")) { - throw new IllegalArgumentException(); - } - String[] parts = pathInfo.substring(1).split("/"); - final String node = parts[0]; - - if (parts.length == 1) { - ArrayNode ncs = (ArrayNode) getClusterStateJSON(request, "../../").get("ncs"); - for (int i = 0; i < ncs.size(); i++) { - if (node.equals(ncs.get(i).get("node_id").asText())) { - return (ObjectNode) ncs.get(i); - } - } - if ("cc".equals(node)) { - return om.createObjectNode(); - } - throw new IllegalArgumentException(); - } else if (parts.length == 2) { - ObjectNode json; - - switch (parts[1]) { - case "config": - json = processNodeConfig(hcc, node); - break; - - case "stats": - json = processNodeStats(hcc, node); - break; - - case "threaddump": - return processNodeThreadDump(hcc, node); - - default: - throw new IllegalArgumentException(); - } - fixupKeys(json); - - return json; - } else { - throw new IllegalArgumentException(); - } - } - - protected ObjectNode fixupKeys(ObjectNode json) { - // TODO (mblow): generate the keys with _ to begin with - List keys = new ArrayList<>(); - for (Iterator iter = json.fieldNames(); iter.hasNext(); ) { - keys.add((String) iter.next()); - } - for (String key : keys) { - String newKey = key.replace('-', '_'); - if (!newKey.equals(key)) { - json.set(newKey, json.remove(key)); - } - } - return json; - } - - protected ObjectNode processNodeStats(IHyracksClientConnection hcc, String node) throws Exception { - final String details = hcc.getNodeDetailsJSON(node, true, false); - if (details == null) { - throw new IllegalArgumentException(); - } - ObjectNode json = (ObjectNode) om.readTree(details); - int index = json.get("rrd-ptr").asInt() - 1; - json.remove("rrd-ptr"); - - List keys = new ArrayList<>(); - for (Iterator iter = json.fieldNames(); iter.hasNext(); ) { - keys.add((String) iter.next()); - } - - final ArrayNode gcNames = (ArrayNode) json.get("gc-names"); - final ArrayNode gcCollectionTimes = (ArrayNode) json.get("gc-collection-times"); - final ArrayNode gcCollectionCounts = (ArrayNode) json.get("gc-collection-counts"); - - for (String key : keys) { - if (key.startsWith("gc-")) { - json.remove(key); - } else { - final JsonNode keyNode = json.get(key); - if (keyNode instanceof ArrayNode) { - final ArrayNode valueArray = (ArrayNode) keyNode; - // fixup an index of -1 to the final element in the array (i.e. RRD_SIZE) - if (index == -1) { - index = valueArray.size() - 1; - } - final JsonNode value = valueArray.get(index); - json.remove(key); - json.set(key.replaceAll("s$",""), value); - } - } - } - ArrayNode gcs = om.createArrayNode(); - - for (int i = 0; i < gcNames.size(); i++) { - ObjectNode gc = om.createObjectNode(); - gc.set("name", gcNames.get(i)); - gc.set("collection-time", ((ArrayNode)gcCollectionTimes.get(i)).get(index)); - gc.set("collection-count", ((ArrayNode)gcCollectionCounts.get(i)).get(index)); - gcs.add(gc); - } - json.set("gcs", gcs); - - return json; - } - - private ObjectNode processNodeConfig(IHyracksClientConnection hcc, String node) throws Exception { - String config = hcc.getNodeDetailsJSON(node, false, true); - if (config == null) { - throw new IllegalArgumentException(); - } - return (ObjectNode) om.readTree(config); - } - - private ObjectNode processNodeThreadDump(IHyracksClientConnection hcc, String node) throws Exception { - if ("cc".equals(node)) { - return om.createObjectNode(); - } - String dump = hcc.getThreadDump(node); - if (dump == null) { - // check to see if this is a node that is simply down - throw ClusterStateManager.INSTANCE.getNodePartitions(node) != null - ? new IllegalStateException() - : new IllegalArgumentException(); - } - return (ObjectNode) om.readTree(dump); - } - -} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/60e7f12b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ConnectorAPIServlet.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ConnectorAPIServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ConnectorAPIServlet.java deleted file mode 100644 index 78801b8..0000000 --- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ConnectorAPIServlet.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * 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.asterix.api.http.servlet; - -import static org.apache.asterix.api.http.servlet.ServletConstants.HYRACKS_CONNECTION_ATTR; - -import java.io.IOException; -import java.io.PrintWriter; -import java.util.List; -import java.util.Map; - -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.asterix.metadata.MetadataManager; -import org.apache.asterix.metadata.MetadataTransactionContext; -import org.apache.asterix.metadata.declared.MetadataProvider; -import org.apache.asterix.metadata.entities.Dataset; -import org.apache.asterix.metadata.utils.DatasetUtils; -import org.apache.asterix.om.types.ARecordType; -import org.apache.asterix.util.FlushDatasetUtils; -import org.apache.hyracks.api.client.IHyracksClientConnection; -import org.apache.hyracks.api.client.NodeControllerInfo; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; -import org.apache.hyracks.api.io.FileSplit; - -/*** - * The REST API that takes a dataverse name and a dataset name as the input - * and returns an array of file splits (IP, file-path) of the dataset in LOSSLESS_JSON. - * It is mostly used by external runtime, e.g., Pregelix or IMRU to pull data - * in parallel from existing AsterixDB datasets. - * - * @author yingyi - */ -public class ConnectorAPIServlet extends HttpServlet { - private static final long serialVersionUID = 1L; - - @Override - public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { - response.setContentType("text/html"); - response.setCharacterEncoding("utf-8"); - PrintWriter out = response.getWriter(); - try { - ObjectMapper om = new ObjectMapper(); - ObjectNode jsonResponse = om.createObjectNode(); - String dataverseName = request.getParameter("dataverseName"); - String datasetName = request.getParameter("datasetName"); - if (dataverseName == null || datasetName == null) { - jsonResponse.put("error", "Parameter dataverseName or datasetName is null,"); - out.write(jsonResponse.toString()); - out.flush(); - return; - } - ServletContext context = getServletContext(); - - IHyracksClientConnection hcc = null; - synchronized (context) { - hcc = (IHyracksClientConnection) context.getAttribute(HYRACKS_CONNECTION_ATTR); - } - - // Metadata transaction begins. - MetadataManager.INSTANCE.init(); - MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction(); - - // Retrieves file splits of the dataset. - MetadataProvider metadataProvider = new MetadataProvider(null); - metadataProvider.setMetadataTxnContext(mdTxnCtx); - Dataset dataset = metadataProvider.findDataset(dataverseName, datasetName); - if (dataset == null) { - jsonResponse.put("error", - "Dataset " + datasetName + " does not exist in " + "dataverse " + dataverseName); - out.write(jsonResponse.toString()); - out.flush(); - return; - } - boolean temp = dataset.getDatasetDetails().isTemp(); - FileSplit[] fileSplits = metadataProvider.splitsForDataset(mdTxnCtx, dataverseName, datasetName, - datasetName, temp); - ARecordType recordType = (ARecordType) metadataProvider.findType(dataset.getItemTypeDataverseName(), - dataset.getItemTypeName()); - List> primaryKeys = DatasetUtils.getPartitioningKeys(dataset); - StringBuilder pkStrBuf = new StringBuilder(); - for (List keys : primaryKeys) { - for (String key : keys) { - pkStrBuf.append(key).append(","); - } - } - pkStrBuf.delete(pkStrBuf.length() - 1, pkStrBuf.length()); - - // Constructs the returned json object. - formResponseObject(jsonResponse, fileSplits, recordType, pkStrBuf.toString(), temp, - hcc.getNodeControllerInfos()); - - // Flush the cached contents of the dataset to file system. - FlushDatasetUtils.flushDataset(hcc, metadataProvider, mdTxnCtx, dataverseName, datasetName, datasetName); - - // Metadata transaction commits. - MetadataManager.INSTANCE.commitTransaction(mdTxnCtx); - // Writes file splits. - out.write(jsonResponse.toString()); - out.flush(); - } catch (Exception e) { - e.printStackTrace(); - out.println(e.getMessage()); - out.flush(); - e.printStackTrace(out); - } - } - - private void formResponseObject(ObjectNode jsonResponse, FileSplit[] fileSplits, ARecordType recordType, - String primaryKeys, boolean temp, Map nodeMap) throws Exception { - ObjectMapper om = new ObjectMapper(); - ArrayNode partititons = om.createArrayNode(); - // Whether the dataset is temp or not - jsonResponse.put("temp", temp); - // Adds a primary key. - jsonResponse.put("keys", primaryKeys); - // Adds record type. - jsonResponse.set("type", recordType.toJSON()); - // Generates file partitions. - for (FileSplit split : fileSplits) { - String ipAddress = nodeMap.get(split.getNodeName()).getNetworkAddress().getAddress().toString(); - String path = split.getPath(); - FilePartition partition = new FilePartition(ipAddress, path); - partititons.add(partition.toObjectNode()); - } - // Generates the response object which contains the splits. - jsonResponse.set("splits", partititons); - } -} - -class FilePartition { - private final String ipAddress; - private final String path; - - public FilePartition(String ipAddress, String path) { - this.ipAddress = ipAddress; - this.path = path; - } - - public String getIPAddress() { - return ipAddress; - } - - public String getPath() { - return path; - } - - @Override - public String toString() { - return ipAddress + ":" + path; - } - - public ObjectNode toObjectNode() { - ObjectMapper om = new ObjectMapper(); - ObjectNode partition = om.createObjectNode(); - partition.put("ip", ipAddress); - partition.put("path", path); - return partition; - } -} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/60e7f12b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/DDLAPIServlet.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/DDLAPIServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/DDLAPIServlet.java deleted file mode 100644 index 19a7609..0000000 --- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/DDLAPIServlet.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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.asterix.api.http.servlet; - -import javax.servlet.http.HttpServletRequest; - -import org.apache.asterix.compiler.provider.ILangCompilationProvider; -import org.apache.asterix.lang.common.base.Statement; -import org.apache.asterix.translator.IStatementExecutorFactory; - -public class DDLAPIServlet extends RESTAPIServlet { - private static final long serialVersionUID = 1L; - private static final byte ALLOWED_CATEGORIES = Statement.Category.QUERY | Statement.Category.UPDATE - | Statement.Category.DDL; - - public DDLAPIServlet(ILangCompilationProvider compilationProvider, - IStatementExecutorFactory statementExecutorFactory) { - super(compilationProvider, statementExecutorFactory); - } - - @Override - protected String getQueryParameter(HttpServletRequest request) { - return request.getParameter("ddl"); - } - - @Override - protected byte getAllowedCategories() { - return ALLOWED_CATEGORIES; - } - - @Override - protected String getErrorMessage() { - return "Invalid statement: Non-DDL statement %s to the DDL API."; - } -} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/60e7f12b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/DiagnosticsAPIServlet.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/DiagnosticsAPIServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/DiagnosticsAPIServlet.java deleted file mode 100644 index 4416d5c..0000000 --- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/DiagnosticsAPIServlet.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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.asterix.api.http.servlet; - -import static org.apache.asterix.api.http.servlet.ServletConstants.HYRACKS_CONNECTION_ATTR; - -import java.io.IOException; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; -import org.apache.asterix.runtime.util.AppContextInfo; -import org.apache.hyracks.api.client.IHyracksClientConnection; -import com.fasterxml.jackson.databind.node.ObjectNode; - -public class DiagnosticsAPIServlet extends ClusterNodeDetailsAPIServlet { - private static final long serialVersionUID = 1L; - private static final Logger LOGGER = Logger.getLogger(DiagnosticsAPIServlet.class.getName()); - - @Override - protected void getUnsafe(HttpServletRequest request, HttpServletResponse response) throws IOException { - response.setContentType("application/json"); - response.setCharacterEncoding("utf-8"); - PrintWriter responseWriter = response.getWriter(); - ObjectNode json; - ObjectMapper om = new ObjectMapper(); - om.enable(SerializationFeature.INDENT_OUTPUT); - try { - if (request.getPathInfo() != null) { - throw new IllegalArgumentException(); - } - json = getClusterDiagnosticsJSON(); - response.setStatus(HttpServletResponse.SC_OK); - responseWriter.write(om.writerWithDefaultPrettyPrinter().writeValueAsString(json)); - } catch (IllegalStateException e) { // NOSONAR - exception not logged or rethrown - response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE); - } catch (IllegalArgumentException e) { // NOSONAR - exception not logged or rethrown - response.sendError(HttpServletResponse.SC_NOT_FOUND); - } catch (Exception e) { - LOGGER.log(Level.INFO, "exception thrown for " + request, e); - response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.toString()); - } - responseWriter.flush(); - } - - private ObjectNode getClusterDiagnosticsJSON() throws Exception { - ObjectMapper om = new ObjectMapper(); - final ServletContext context = getServletContext(); - IHyracksClientConnection hcc = (IHyracksClientConnection) context.getAttribute(HYRACKS_CONNECTION_ATTR); - ExecutorService executor = (ExecutorService) context.getAttribute(ServletConstants.EXECUTOR_SERVICE); - - Map> ccFutureData = new HashMap<>(); - ccFutureData.put("threaddump", - executor.submit(() -> fixupKeys((ObjectNode) om.readTree(hcc.getThreadDump(null))))); - ccFutureData.put("config", - executor.submit(() -> fixupKeys((ObjectNode) om.readTree(hcc.getNodeDetailsJSON(null, false, true))))); - ccFutureData.put("stats", - executor.submit(() -> fixupKeys((ObjectNode) om.readTree(hcc.getNodeDetailsJSON(null, true, false))))); - - Map>> ncDataMap = new HashMap<>(); - for (String nc : AppContextInfo.INSTANCE.getMetadataProperties().getNodeNames()) { - Map> ncData = new HashMap<>(); - ncData.put("threaddump", executor.submit(() -> fixupKeys((ObjectNode) om.readTree(hcc.getThreadDump(nc))))); - ncData.put("config", executor - .submit(() -> fixupKeys((ObjectNode) om.readTree(hcc.getNodeDetailsJSON(nc, false, true))))); - ncData.put("stats", executor.submit(() -> fixupKeys(processNodeStats(hcc, nc)))); - ncDataMap.put(nc, ncData); - } - ObjectNode result = om.createObjectNode(); - result.putPOJO("cc", resolveFutures(ccFutureData)); - List> ncList = new ArrayList<>(); - for (Map.Entry>> entry : ncDataMap.entrySet()) { - final Map ncMap = resolveFutures(entry.getValue()); - ncMap.put("node_id", entry.getKey()); - ncList.add(ncMap); - } - result.putPOJO("ncs", ncList); - result.putPOJO("date", new Date()); - return result; - } - - private Map resolveFutures(Map> futureMap) - throws ExecutionException, InterruptedException { - Map result = new HashMap<>(); - for (Map.Entry> entry : futureMap.entrySet()) { - result.put(entry.getKey(), entry.getValue().get()); - } - return result; - } -} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/60e7f12b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/FeedServlet.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/FeedServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/FeedServlet.java deleted file mode 100644 index 6c8019d..0000000 --- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/FeedServlet.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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.asterix.api.http.servlet; - -import java.awt.image.BufferedImage; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.PrintWriter; - -import javax.imageio.ImageIO; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -public class FeedServlet extends HttpServlet { - private static final long serialVersionUID = 1L; - - @Override - public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { - String resourcePath = null; - String requestURI = request.getRequestURI(); - - if (requestURI.equals("/")) { - response.setContentType("text/html"); - resourcePath = "/feed/home.html"; - } else { - resourcePath = requestURI; - } - - InputStream is = FeedServlet.class.getResourceAsStream(resourcePath); - if (is == null) { - response.sendError(HttpServletResponse.SC_NOT_FOUND); - return; - } - - // Special handler for font files and .png resources - if (resourcePath.endsWith(".png")) { - - BufferedImage img = ImageIO.read(is); - OutputStream outputStream = response.getOutputStream(); - String formatName = "png"; - response.setContentType("image/png"); - ImageIO.write(img, formatName, outputStream); - outputStream.close(); - return; - - } - - response.setCharacterEncoding("utf-8"); - InputStreamReader isr = new InputStreamReader(is); - StringBuilder sb = new StringBuilder(); - BufferedReader br = new BufferedReader(isr); - String line = br.readLine(); - - while (line != null) { - sb.append(line + "\n"); - line = br.readLine(); - } - - String outStr = null; - outStr = sb.toString(); - - PrintWriter out = response.getWriter(); - out.println(outStr); - } -} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/60e7f12b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/FullAPIServlet.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/FullAPIServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/FullAPIServlet.java deleted file mode 100644 index 0f86ec6..0000000 --- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/FullAPIServlet.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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.asterix.api.http.servlet; - -import javax.servlet.http.HttpServletRequest; - -import org.apache.asterix.compiler.provider.ILangCompilationProvider; -import org.apache.asterix.lang.common.base.Statement; -import org.apache.asterix.translator.IStatementExecutorFactory; - -public class FullAPIServlet extends RESTAPIServlet { - - private static final long serialVersionUID = 1L; - private static final String AQL_STMT_PARAM_NAME = "aql"; - private static final byte ALLOWED_CATEGORIES = Statement.Category.QUERY | Statement.Category.UPDATE - | Statement.Category.DDL | Statement.Category.PROCEDURE; - - public FullAPIServlet(ILangCompilationProvider compilationProvider, - IStatementExecutorFactory statementExecutorFactory) { - super(compilationProvider, statementExecutorFactory); - } - - @Override - protected String getQueryParameter(HttpServletRequest request) { - return request.getParameter(AQL_STMT_PARAM_NAME); - } - - @Override - protected byte getAllowedCategories() { - return ALLOWED_CATEGORIES; - } - - @Override - protected String getErrorMessage() { - throw new IllegalStateException(); - } -} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/60e7f12b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryAPIServlet.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryAPIServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryAPIServlet.java deleted file mode 100644 index cc70324..0000000 --- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryAPIServlet.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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.asterix.api.http.servlet; - -import javax.servlet.http.HttpServletRequest; - -import org.apache.asterix.compiler.provider.ILangCompilationProvider; -import org.apache.asterix.lang.common.base.Statement; -import org.apache.asterix.translator.IStatementExecutorFactory; - -public class QueryAPIServlet extends RESTAPIServlet { - private static final long serialVersionUID = 1L; - private static final byte ALLOWED_CATEGORIES = Statement.Category.QUERY; - - public QueryAPIServlet(ILangCompilationProvider compilationProvider, - IStatementExecutorFactory queryTranslatorFactory) { - super(compilationProvider, queryTranslatorFactory); - } - - @Override - protected String getQueryParameter(HttpServletRequest request) { - return request.getParameter("query"); - } - - @Override - protected byte getAllowedCategories() { - return ALLOWED_CATEGORIES; - } - - @Override - protected String getErrorMessage() { - return "Invalid statement: Non-query statement %s to the query API."; - } -} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/60e7f12b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryResultAPIServlet.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryResultAPIServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryResultAPIServlet.java deleted file mode 100644 index b250690..0000000 --- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryResultAPIServlet.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * 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.asterix.api.http.servlet; - -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 java.io.IOException; -import java.io.PrintWriter; -import java.util.logging.Level; -import java.util.logging.Logger; - -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.asterix.app.result.ResultReader; -import org.apache.asterix.app.result.ResultUtil; -import org.apache.asterix.common.exceptions.AsterixException; -import org.apache.asterix.translator.IStatementExecutor.Stats; -import org.apache.asterix.translator.SessionConfig; -import org.apache.hyracks.api.client.HyracksConnection; -import org.apache.hyracks.api.client.IHyracksClientConnection; -import org.apache.hyracks.api.dataset.IHyracksDataset; -import org.apache.hyracks.api.dataset.ResultSetId; -import org.apache.hyracks.api.job.JobId; -import org.apache.hyracks.client.dataset.HyracksDataset; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; - -public class QueryResultAPIServlet extends HttpServlet { - private static final long serialVersionUID = 1L; - private static final Logger LOGGER = Logger.getLogger(QueryResultAPIServlet.class.getName()); - - @Override - public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { - int respCode = HttpServletResponse.SC_OK; - response.setContentType("text/html"); // TODO this seems wrong ... - response.setCharacterEncoding("utf-8"); - String strHandle = request.getParameter("handle"); - PrintWriter out = response.getWriter(); - ServletContext context = getServletContext(); - IHyracksClientConnection hcc; - IHyracksDataset hds; - - try { - if (strHandle == null || strHandle.isEmpty()) { - throw new AsterixException("Empty request, no handle provided"); - } - - HyracksProperties hp = new HyracksProperties(); - String strIP = hp.getHyracksIPAddress(); - int port = hp.getHyracksPort(); - - synchronized (context) { - hcc = (IHyracksClientConnection) context.getAttribute(HYRACKS_CONNECTION_ATTR); - if (hcc == null) { - hcc = new HyracksConnection(strIP, port); - context.setAttribute(HYRACKS_CONNECTION_ATTR, hcc); - } - - hds = (IHyracksDataset) context.getAttribute(HYRACKS_DATASET_ATTR); - if (hds == null) { - hds = new HyracksDataset(hcc, ResultReader.FRAME_SIZE, ResultReader.NUM_READERS); - context.setAttribute(HYRACKS_DATASET_ATTR, hds); - } - } - ObjectMapper om = new ObjectMapper(); - ObjectNode handleObj = (ObjectNode) om.readTree(strHandle); - ArrayNode handle = (ArrayNode) handleObj.get("handle"); - JobId jobId = new JobId(handle.get(0).asLong()); - ResultSetId rsId = new ResultSetId(handle.get(1).asLong()); - - ResultReader resultReader = new ResultReader(hds); - resultReader.open(jobId, rsId); - - // QQQ The output format is determined by the initial - // query and cannot be modified here, so calling back to - // initResponse() is really an error. We need to find a - // way to send the same OutputFormat value here as was - // originally determined there. Need to save this value on - // some object that we can obtain here. - SessionConfig sessionConfig = RESTAPIServlet.initResponse(request, response); - ResultUtil.printResults(resultReader, sessionConfig, new Stats(), null); - - } catch (Exception e) { - respCode = HttpServletResponse.SC_BAD_REQUEST; - out.println(e.getMessage()); - LOGGER.log(Level.WARNING, "Error retrieving result", e); - } - response.setStatus(respCode); - if (out.checkError()) { - LOGGER.warning("Error flushing output writer"); - } - } -} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/60e7f12b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryServiceServlet.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryServiceServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryServiceServlet.java deleted file mode 100644 index a0454fd..0000000 --- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryServiceServlet.java +++ /dev/null @@ -1,571 +0,0 @@ -/* - * 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.asterix.api.http.servlet; - -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 java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.nio.charset.StandardCharsets; -import java.util.List; -import java.util.UUID; -import java.util.logging.Level; -import java.util.logging.Logger; - -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.asterix.app.result.ResultReader; -import org.apache.asterix.app.result.ResultUtil; -import org.apache.asterix.app.translator.QueryTranslator; -import org.apache.asterix.common.api.IClusterManagementWork; -import org.apache.asterix.common.config.GlobalConfig; -import org.apache.asterix.common.exceptions.AsterixException; -import org.apache.asterix.common.utils.JSONUtil; -import org.apache.asterix.compiler.provider.ILangCompilationProvider; -import org.apache.asterix.lang.aql.parser.TokenMgrError; -import org.apache.asterix.lang.common.base.IParser; -import org.apache.asterix.lang.common.base.Statement; -import org.apache.asterix.metadata.MetadataManager; -import org.apache.asterix.runtime.util.ClusterStateManager; -import org.apache.asterix.translator.IStatementExecutor; -import org.apache.asterix.translator.IStatementExecutor.Stats; -import org.apache.asterix.translator.IStatementExecutorFactory; -import org.apache.asterix.translator.SessionConfig; -import org.apache.commons.io.IOUtils; -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; - -public class QueryServiceServlet extends HttpServlet { - private static final long serialVersionUID = 1L; - - private static final Logger LOGGER = Logger.getLogger(QueryServiceServlet.class.getName()); - private final transient ILangCompilationProvider compilationProvider; - private final transient IStatementExecutorFactory statementExecutorFactory; - - public QueryServiceServlet(ILangCompilationProvider compilationProvider, - IStatementExecutorFactory statementExecutorFactory) { - this.compilationProvider = compilationProvider; - this.statementExecutorFactory = statementExecutorFactory; - } - - public enum Parameter { - STATEMENT("statement"), - FORMAT("format"), - CLIENT_ID("client_context_id"), - PRETTY("pretty"), - MODE("mode"); - - private final String str; - - Parameter(String str) { - this.str = str; - } - - public String str() { - return str; - } - } - - private enum MediaType { - CSV("text/csv"), - JSON("application/json"), - ADM("application/x-adm"); - - private final String str; - - MediaType(String str) { - this.str = str; - } - - public String str() { - return str; - } - } - - private enum Attribute { - HEADER("header"), - LOSSLESS("lossless"); - - 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 { - SUCCESS("success"), - TIMEOUT("timeout"), - ERRORS("errors"), - FATAL("fatal"); - - private final String str; - - ResultStatus(String str) { - this.str = str; - } - - public String str() { - return str; - } - } - - private enum ErrorField { - CODE("code"), - MSG("msg"), - STACK("stack"); - - private final String str; - - ErrorField(String str) { - this.str = str; - } - - public String str() { - return str; - } - } - - private enum Metrics { - ELAPSED_TIME("elapsedTime"), - EXECUTION_TIME("executionTime"), - RESULT_COUNT("resultCount"), - RESULT_SIZE("resultSize"); - - private final String str; - - Metrics(String str) { - this.str = str; - } - - public String str() { - return str; - } - } - - enum TimeUnit { - SEC("s", 9), - MILLI("ms", 6), - MICRO("µs", 3), - NANO("ns", 0); - - String unit; - int nanoDigits; - - TimeUnit(String unit, int nanoDigits) { - this.unit = unit; - this.nanoDigits = nanoDigits; - } - - static String formatNanos(long nanoTime) { - final String strTime = String.valueOf(nanoTime); - final int len = strTime.length(); - for (TimeUnit tu : TimeUnit.values()) { - if (len > tu.nanoDigits) { - final String integer = strTime.substring(0, len - tu.nanoDigits); - final String fractional = strTime.substring(len - tu.nanoDigits); - return integer + (fractional.length() > 0 ? "." + fractional : "") + tu.unit; - } - } - return "illegal string value: " + strTime; - } - } - - static class RequestParameters { - String statement; - String format; - boolean pretty; - String clientContextID; - String mode; - - @Override - public String toString() { - return append(new StringBuilder()).toString(); - } - - public StringBuilder append(final StringBuilder sb) { - sb.append("{ "); - sb.append("\"statement\": \""); - JSONUtil.escape(sb, statement); - sb.append("\", "); - sb.append("\"format\": \"").append(format).append("\", "); - sb.append("\"pretty\": ").append(pretty).append(", "); - sb.append("\"mode\": ").append(mode).append(", "); - sb.append("\"clientContextID\": \"").append(clientContextID).append("\" "); - sb.append('}'); - return sb; - } - } - - private static String getParameterValue(String content, String attribute) { - if (content == null || attribute == null) { - return null; - } - int sc = content.indexOf(';'); - if (sc < 0) { - return null; - } - int eq = content.indexOf('=', sc + 1); - if (eq < 0) { - return null; - } - if (content.substring(sc + 1, eq).trim().equalsIgnoreCase(attribute)) { - return content.substring(eq + 1).trim().toLowerCase(); - } - return null; - } - - private static String toLower(String s) { - return s != null ? s.toLowerCase() : s; - } - - private static SessionConfig.OutputFormat getFormat(String format) { - if (format != null) { - if (format.startsWith(MediaType.CSV.str())) { - return SessionConfig.OutputFormat.CSV; - } - if (format.equals(MediaType.ADM.str())) { - return SessionConfig.OutputFormat.ADM; - } - if (format.startsWith(MediaType.JSON.str())) { - return Boolean.parseBoolean(getParameterValue(format, Attribute.LOSSLESS.str())) - ? SessionConfig.OutputFormat.LOSSLESS_JSON : SessionConfig.OutputFormat.CLEAN_JSON; - } - } - return SessionConfig.OutputFormat.CLEAN_JSON; - } - - private static SessionConfig createSessionConfig(RequestParameters param, PrintWriter resultWriter) { - SessionConfig.ResultDecorator resultPrefix = new SessionConfig.ResultDecorator() { - int resultNo = -1; - - @Override - public AlgebricksAppendable append(AlgebricksAppendable app) throws AlgebricksException { - app.append("\t\""); - app.append(ResultFields.RESULTS.str()); - if (resultNo >= 0) { - app.append('-').append(String.valueOf(resultNo)); - } - ++resultNo; - app.append("\": "); - return app; - } - }; - - - SessionConfig.ResultDecorator resultPostfix = (AlgebricksAppendable app) -> app.append("\t,\n"); - - SessionConfig.ResultDecorator handlePrefix = new SessionConfig.ResultDecorator() { - @Override - public AlgebricksAppendable append(AlgebricksAppendable app) throws AlgebricksException { - app.append("\t\""); - app.append(ResultFields.HANDLE.str()); - app.append("\": "); - return app; - } - }; - - SessionConfig.ResultDecorator handlePostfix = (AlgebricksAppendable app) -> app.append(",\n"); - - SessionConfig.OutputFormat format = getFormat(param.format); - SessionConfig sessionConfig = new SessionConfig(resultWriter, format, resultPrefix, resultPostfix, handlePrefix, - handlePostfix); - sessionConfig.set(SessionConfig.FORMAT_WRAPPER_ARRAY, true); - sessionConfig.set(SessionConfig.FORMAT_INDENT_JSON, param.pretty); - sessionConfig.set(SessionConfig.FORMAT_QUOTE_RECORD, - format != SessionConfig.OutputFormat.CLEAN_JSON && format != SessionConfig.OutputFormat.LOSSLESS_JSON); - sessionConfig.set(SessionConfig.FORMAT_CSV_HEADER, format == SessionConfig.OutputFormat.CSV - && "present".equals(getParameterValue(param.format, Attribute.HEADER.str()))); - 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) { - pw.print("\t\""); - pw.print(name); - pw.print("\": \""); - pw.print(value); - pw.print('"'); - 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); - } - } - - private static void printSignature(PrintWriter pw) { - printField(pw, ResultFields.SIGNATURE.str(), "*"); - } - - private static void printType(PrintWriter pw, SessionConfig sessionConfig) { - switch (sessionConfig.fmt()) { - case ADM: - printField(pw, ResultFields.TYPE.str(), MediaType.ADM.str()); - break; - case CSV: - String contentType = MediaType.CSV.str() + "; header=" - + (sessionConfig.is(SessionConfig.FORMAT_CSV_HEADER) ? "present" : "absent"); - printField(pw, ResultFields.TYPE.str(), contentType); - break; - 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 { - Throwable rootCause = ResultUtil.getRootCause(e); - if (rootCause == null) { - rootCause = e; - } - final boolean addStack = false; - pw.print("\t\""); - pw.print(ResultFields.ERRORS.str()); - pw.print("\": [{ \n"); - printField(pw, ErrorField.CODE.str(), "1"); - - final String msg = rootCause.getMessage(); - printField(pw, ErrorField.MSG.str(), JSONUtil.escape(msg != null ? msg : rootCause.getClass().getSimpleName()), - addStack); - pw.print("\t}],\n"); - } - - private static void printMetrics(PrintWriter pw, long elapsedTime, long executionTime, long resultCount, - long resultSize) { - pw.print("\t\""); - pw.print(ResultFields.METRICS.str()); - pw.print("\": {\n"); - pw.print("\t"); - printField(pw, Metrics.ELAPSED_TIME.str(), TimeUnit.formatNanos(elapsedTime)); - pw.print("\t"); - printField(pw, Metrics.EXECUTION_TIME.str(), TimeUnit.formatNanos(executionTime)); - pw.print("\t"); - printField(pw, Metrics.RESULT_COUNT.str(), String.valueOf(resultCount)); - pw.print("\t"); - printField(pw, Metrics.RESULT_SIZE.str(), String.valueOf(resultSize), false); - pw.print("\t}\n"); - } - - @Override - protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException { - try { - handleRequest(getRequestParameters(request), response); - } catch (IOException e) { - // Servlet methods should not throw exceptions - // http://cwe.mitre.org/data/definitions/600.html - GlobalConfig.ASTERIX_LOGGER.log(Level.SEVERE, e.getMessage(), e); - } - } - - private String getOptText(JsonNode node, String fieldName) { - final JsonNode value = node.get(fieldName); - return value != null ? value.asText() : null; - } - - private boolean getOptBoolean(JsonNode node, String fieldName, boolean defaultValue) { - final JsonNode value = node.get(fieldName); - return value != null ? value.asBoolean() : defaultValue; - } - - private RequestParameters getRequestParameters(HttpServletRequest request) throws IOException { - final String contentTypeParam = request.getContentType(); - int sep = contentTypeParam.indexOf(';'); - final String contentType = sep < 0 ? contentTypeParam.trim() : contentTypeParam.substring(0, sep).trim(); - RequestParameters param = new RequestParameters(); - if (MediaType.JSON.str().equals(contentType)) { - try { - JsonNode jsonRequest = new ObjectMapper().readTree(getRequestBody(request)); - param.statement = jsonRequest.get(Parameter.STATEMENT.str()).asText(); - param.format = toLower(getOptText(jsonRequest, Parameter.FORMAT.str())); - param.pretty = getOptBoolean(jsonRequest, Parameter.PRETTY.str(), false); - param.mode = toLower(getOptText(jsonRequest, Parameter.MODE.str())); - param.clientContextID = getOptText(jsonRequest, Parameter.CLIENT_ID.str()); - } catch (JsonParseException | JsonMappingException e) { - // if the JSON parsing fails, the statement is empty and we get an empty statement error - GlobalConfig.ASTERIX_LOGGER.log(Level.SEVERE, e.getMessage(), e); - } - } else { - param.statement = request.getParameter(Parameter.STATEMENT.str()); - if (param.statement == null) { - param.statement = getRequestBody(request); - } - param.format = toLower(request.getParameter(Parameter.FORMAT.str())); - param.pretty = Boolean.parseBoolean(request.getParameter(Parameter.PRETTY.str())); - param.mode = toLower(request.getParameter(Parameter.MODE.str())); - param.clientContextID = request.getParameter(Parameter.CLIENT_ID.str()); - } - return param; - } - - private static String getRequestBody(HttpServletRequest request) throws IOException { - StringWriter sw = new StringWriter(); - IOUtils.copy(request.getInputStream(), sw, StandardCharsets.UTF_8.name()); - return sw.toString(); - } - - private static QueryTranslator.ResultDelivery parseResultDelivery(String mode) { - if ("async".equals(mode)) { - return QueryTranslator.ResultDelivery.ASYNC; - } else if ("deferred".equals(mode)) { - return QueryTranslator.ResultDelivery.DEFERRED; - } else { - return QueryTranslator.ResultDelivery.IMMEDIATE; - } - } - - private void handleRequest(RequestParameters param, HttpServletResponse response) throws IOException { - LOGGER.info(param.toString()); - long elapsedStart = System.nanoTime(); - final StringWriter stringWriter = new StringWriter(); - final PrintWriter resultWriter = new PrintWriter(stringWriter); - - QueryTranslator.ResultDelivery delivery = parseResultDelivery(param.mode); - - SessionConfig sessionConfig = createSessionConfig(param, resultWriter); - response.setCharacterEncoding("utf-8"); - response.setContentType(MediaType.JSON.str()); - - int respCode = HttpServletResponse.SC_OK; - Stats stats = new Stats(); - long execStart = -1; - long execEnd = -1; - - resultWriter.print("{\n"); - printRequestId(resultWriter); - printClientContextID(resultWriter, param); - printSignature(resultWriter); - printType(resultWriter, sessionConfig); - try { - final IClusterManagementWork.ClusterState clusterState = ClusterStateManager.INSTANCE.getState(); - if (clusterState != IClusterManagementWork.ClusterState.ACTIVE) { - // using a plain IllegalStateException here to get into the right catch clause for a 500 - throw new IllegalStateException("Cannot execute request, cluster is " + clusterState); - } - if (param.statement == null || param.statement.isEmpty()) { - throw new AsterixException("Empty request, no statement provided"); - } - IHyracksClientConnection hcc; - IHyracksDataset hds; - ServletContext context = getServletContext(); - synchronized (context) { - hcc = (IHyracksClientConnection) context.getAttribute(HYRACKS_CONNECTION_ATTR); - hds = (IHyracksDataset) context.getAttribute(HYRACKS_DATASET_ATTR); - if (hds == null) { - hds = new HyracksDataset(hcc, ResultReader.FRAME_SIZE, ResultReader.NUM_READERS); - context.setAttribute(HYRACKS_DATASET_ATTR, hds); - } - } - IParser parser = compilationProvider.getParserFactory().createParser(param.statement); - List statements = parser.parse(); - MetadataManager.INSTANCE.init(); - IStatementExecutor translator = statementExecutorFactory.create(statements, sessionConfig, - compilationProvider); - execStart = System.nanoTime(); - translator.compileAndExecute(hcc, hds, delivery, stats); - execEnd = System.nanoTime(); - printStatus(resultWriter, ResultStatus.SUCCESS); - } catch (AsterixException | TokenMgrError | org.apache.asterix.aqlplus.parser.TokenMgrError pe) { - GlobalConfig.ASTERIX_LOGGER.log(Level.SEVERE, pe.getMessage(), pe); - printError(resultWriter, pe); - printStatus(resultWriter, ResultStatus.FATAL); - respCode = HttpServletResponse.SC_BAD_REQUEST; - } catch (Exception e) { - GlobalConfig.ASTERIX_LOGGER.log(Level.SEVERE, e.getMessage(), e); - printError(resultWriter, e); - printStatus(resultWriter, ResultStatus.FATAL); - respCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR; - } finally { - if (execStart == -1) { - execEnd = -1; - } else if (execEnd == -1) { - execEnd = System.nanoTime(); - } - } - printMetrics(resultWriter, System.nanoTime() - elapsedStart, execEnd - execStart, stats.getCount(), - stats.getSize()); - resultWriter.print("}\n"); - resultWriter.flush(); - String result = stringWriter.toString(); - - GlobalConfig.ASTERIX_LOGGER.log(Level.FINE, result); - - response.setStatus(respCode); - response.getWriter().print(result); - if (response.getWriter().checkError()) { - LOGGER.warning("Error flushing output writer"); - } - } -} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/60e7f12b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryStatusAPIServlet.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryStatusAPIServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryStatusAPIServlet.java deleted file mode 100644 index 6d1b1b2..0000000 --- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryStatusAPIServlet.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 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.asterix.api.http.servlet; - -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 java.io.IOException; -import java.io.PrintWriter; - -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.asterix.app.result.ResultReader; -import org.apache.hyracks.api.client.IHyracksClientConnection; -import org.apache.hyracks.api.dataset.IHyracksDataset; -import org.apache.hyracks.api.dataset.ResultSetId; -import org.apache.hyracks.api.job.JobId; -import org.apache.hyracks.client.dataset.HyracksDataset; -import com.fasterxml.jackson.databind.node.ObjectNode; - -public class QueryStatusAPIServlet extends HttpServlet { - private static final long serialVersionUID = 1L; - - @Override - public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { - response.setContentType("text/html"); - response.setCharacterEncoding("utf-8"); - String strHandle = request.getParameter("handle"); - PrintWriter out = response.getWriter(); - ServletContext context = getServletContext(); - IHyracksClientConnection hcc; - IHyracksDataset hds; - - try { - synchronized (context) { - hcc = (IHyracksClientConnection) context.getAttribute(HYRACKS_CONNECTION_ATTR); - - hds = (IHyracksDataset) context.getAttribute(HYRACKS_DATASET_ATTR); - if (hds == null) { - hds = new HyracksDataset(hcc, ResultReader.FRAME_SIZE, ResultReader.NUM_READERS); - context.setAttribute(HYRACKS_DATASET_ATTR, hds); - } - } - ObjectMapper om = new ObjectMapper(); - JsonNode handleObj = om.readTree(strHandle); - JsonNode handle = handleObj.get("handle"); - JobId jobId = new JobId(handle.get(0).asLong()); - ResultSetId rsId = new ResultSetId(handle.get(1).asLong()); - - /* TODO(madhusudancs): We need to find a way to LOSSLESS_JSON serialize default format obtained from - * metadataProvider in the AQLTranslator and store it as part of the result handle. - */ - ResultReader resultReader = new ResultReader(hds); - resultReader.open(jobId, rsId); - - ObjectNode jsonResponse = om.createObjectNode(); - String status; - switch (resultReader.getStatus()) { - case RUNNING: - status = "RUNNING"; - break; - case FAILED: - status = "ERROR"; - break; - case SUCCESS: - status = "SUCCESS"; - break; - default: - status = "ERROR"; - break; - } - jsonResponse.put("status", status); - out.write(jsonResponse.toString()); - - } catch (Exception e) { - out.println(e.getMessage()); - e.printStackTrace(out); - } - } -} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/60e7f12b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryWebInterfaceServlet.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryWebInterfaceServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryWebInterfaceServlet.java deleted file mode 100644 index d3e5556..0000000 --- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryWebInterfaceServlet.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * 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.asterix.api.http.servlet; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.PrintWriter; -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; -import org.apache.asterix.common.config.ExternalProperties; -import org.apache.asterix.runtime.util.AppContextInfo; -import org.apache.commons.io.IOUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -public class QueryWebInterfaceServlet extends HttpServlet { - private static final long serialVersionUID = 1L; - private static final HashMap fileMimePair = new HashMap<>(); - private static final Log LOG = LogFactory.getLog(QueryWebInterfaceServlet.class); - - public QueryWebInterfaceServlet() { - fileMimePair.put("png", "image/png"); - fileMimePair.put("eot", "application/vnd.ms-fontobject"); - fileMimePair.put("svg", "image/svg+xml\t"); - fileMimePair.put("ttf", "application/x-font-ttf"); - fileMimePair.put("woff", "application/x-font-woff"); - fileMimePair.put("woff2", "application/x-font-woff"); - fileMimePair.put("html", "text/html"); - fileMimePair.put("css", "text/css"); - fileMimePair.put("js", "application/javascript"); - } - - @Override - public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { - String resourcePath = null; - String requestURI = request.getRequestURI(); - - if ("/".equals(requestURI)) { - response.setContentType("text/html"); - resourcePath = "/queryui/queryui.html"; - } else { - resourcePath = requestURI; - } - - try (InputStream is = APIServlet.class.getResourceAsStream(resourcePath)) { - if (is == null) { - try { - response.sendError(HttpServletResponse.SC_NOT_FOUND); - } catch (IllegalStateException | IOException e) { - LOG.error(e); - } - return; - } - // Multiple MIME type support - for (Map.Entry entry : fileMimePair.entrySet()) { - OutputStream out = null; - if (resourcePath.endsWith(entry.getKey())) { - response.setContentType(entry.getValue()); - try { - out = response.getOutputStream(); - IOUtils.copy(is, out); - - } catch (IOException e) { - LOG.info(e); - } finally { - - if (out != null) { - IOUtils.closeQuietly(out); - } - IOUtils.closeQuietly(is); - - } - return; - } - } - try { - response.sendError(HttpServletResponse.SC_BAD_REQUEST); - } catch (IllegalStateException | IOException e) { - LOG.error(e); - } - } - } - - @Override - public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { - response.setCharacterEncoding("utf-8"); - response.setContentType("application/json"); - ExternalProperties externalProperties = AppContextInfo.INSTANCE.getExternalProperties(); - ObjectMapper om = new ObjectMapper(); - ObjectNode obj = om.createObjectNode(); - try { - PrintWriter out = response.getWriter(); - obj.put("api_port", String.valueOf(externalProperties.getAPIServerPort())); - out.println(obj.toString()); - return; - } catch (Exception e) { - LOG.error(e); - } - - try { - response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - } catch (IllegalStateException | IOException e) { - LOG.error(e); - } - } - -} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/60e7f12b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/RESTAPIServlet.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/RESTAPIServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/RESTAPIServlet.java deleted file mode 100644 index dd030b0..0000000 --- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/RESTAPIServlet.java +++ /dev/null @@ -1,252 +0,0 @@ -/* - * 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.asterix.api.http.servlet; - -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 java.io.IOException; -import java.io.StringWriter; -import java.nio.charset.StandardCharsets; -import java.util.List; -import java.util.logging.Level; - -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.asterix.app.result.ResultReader; -import org.apache.asterix.app.result.ResultUtil; -import org.apache.asterix.app.translator.QueryTranslator; -import org.apache.asterix.common.config.GlobalConfig; -import org.apache.asterix.common.exceptions.AsterixException; -import org.apache.asterix.compiler.provider.ILangCompilationProvider; -import org.apache.asterix.lang.aql.parser.TokenMgrError; -import org.apache.asterix.lang.common.base.IParser; -import org.apache.asterix.lang.common.base.IParserFactory; -import org.apache.asterix.lang.common.base.Statement; -import org.apache.asterix.metadata.MetadataManager; -import org.apache.asterix.translator.IStatementExecutor; -import org.apache.asterix.translator.IStatementExecutorFactory; -import org.apache.asterix.translator.SessionConfig; -import org.apache.asterix.translator.SessionConfig.OutputFormat; -import org.apache.commons.io.IOUtils; -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 com.fasterxml.jackson.databind.node.ObjectNode; - -abstract class RESTAPIServlet extends HttpServlet { - private static final long serialVersionUID = 1L; - - private final ILangCompilationProvider compilationProvider; - private final IParserFactory parserFactory; - private final transient IStatementExecutorFactory statementExecutorFactory; - - public RESTAPIServlet(ILangCompilationProvider compilationProvider, - IStatementExecutorFactory statementExecutorFactory) { - this.compilationProvider = compilationProvider; - this.parserFactory = compilationProvider.getParserFactory(); - this.statementExecutorFactory = statementExecutorFactory; - } - - /** - * Initialize the Content-Type of the response, and construct a - * SessionConfig with the appropriate output writer and output-format - * based on the Accept: header and other servlet parameters. - */ - static SessionConfig initResponse(HttpServletRequest request, HttpServletResponse response) throws IOException { - response.setCharacterEncoding("utf-8"); - - // CLEAN_JSON output is the default; most generally useful for a - // programmatic HTTP API - OutputFormat format = OutputFormat.CLEAN_JSON; - - // First check the "output" servlet parameter. - String output = request.getParameter("output"); - String accept = request.getHeader("Accept"); - if (accept == null) { - accept = ""; - } - if (output != null) { - if (output.equals("CSV")) { - format = OutputFormat.CSV; - } else if (output.equals("ADM")) { - format = OutputFormat.ADM; - } - } else { - // Second check the Accept: HTTP header. - if (accept.contains("application/x-adm")) { - format = OutputFormat.ADM; - } else if (accept.contains("text/csv")) { - format = OutputFormat.CSV; - } - } - - // If it's JSON, check for the "lossless" flag - - if (format == OutputFormat.CLEAN_JSON - && ("true".equals(request.getParameter("lossless")) || accept.contains("lossless=true"))) { - format = OutputFormat.LOSSLESS_JSON; - } - - SessionConfig.ResultDecorator handlePrefix = (AlgebricksAppendable app) -> app.append("{ \"").append("handle") - .append("\": "); - SessionConfig.ResultDecorator handlePostfix = (AlgebricksAppendable app) -> app.append(" }"); - - SessionConfig sessionConfig = new SessionConfig(response.getWriter(), format, null, null, handlePrefix, - handlePostfix); - - // If it's JSON or ADM, check for the "wrapper-array" flag. Default is - // "true" for JSON and "false" for ADM. (Not applicable for CSV.) - boolean wrapper_array; - switch (format) { - case CLEAN_JSON: - case LOSSLESS_JSON: - wrapper_array = true; - break; - default: - wrapper_array = false; - break; - } - String wrapper_param = request.getParameter("wrapper-array"); - if (wrapper_param != null) { - wrapper_array = Boolean.valueOf(wrapper_param); - } else if (accept.contains("wrap-array=true")) { - wrapper_array = true; - } else if (accept.contains("wrap-array=false")) { - wrapper_array = false; - } - sessionConfig.set(SessionConfig.FORMAT_WRAPPER_ARRAY, wrapper_array); - - // Now that format is set, output the content-type - switch (format) { - case ADM: - response.setContentType("application/x-adm"); - break; - case CLEAN_JSON: - // No need to reflect "clean-ness" in output type; fall through - case LOSSLESS_JSON: - response.setContentType("application/json"); - break; - case CSV: { - // Check for header parameter or in Accept:. - if ("present".equals(request.getParameter("header")) || accept.contains("header=present")) { - response.setContentType("text/csv; header=present"); - sessionConfig.set(SessionConfig.FORMAT_CSV_HEADER, true); - } else { - response.setContentType("text/csv; header=absent"); - } - } - } - - return sessionConfig; - } - - @Override - protected void doPost(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - StringWriter sw = new StringWriter(); - IOUtils.copy(request.getInputStream(), sw, StandardCharsets.UTF_8.name()); - String query = sw.toString(); - handleRequest(request, response, query); - } - - @Override - public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { - String query = getQueryParameter(request); - handleRequest(request, response, query); - } - - public void handleRequest(HttpServletRequest request, HttpServletResponse response, String query) - throws IOException { - // enable cross-origin resource sharing - response.addHeader("Access-Control-Allow-Origin", "*"); - response.addHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); - - SessionConfig sessionConfig = initResponse(request, response); - QueryTranslator.ResultDelivery resultDelivery = whichResultDelivery(request); - - ServletContext context = getServletContext(); - IHyracksClientConnection hcc; - IHyracksDataset hds; - - try { - synchronized (context) { - hcc = (IHyracksClientConnection) context.getAttribute(HYRACKS_CONNECTION_ATTR); - hds = (IHyracksDataset) context.getAttribute(HYRACKS_DATASET_ATTR); - if (hds == null) { - hds = new HyracksDataset(hcc, ResultReader.FRAME_SIZE, ResultReader.NUM_READERS); - context.setAttribute(HYRACKS_DATASET_ATTR, hds); - } - } - - IParser parser = parserFactory.createParser(query); - List aqlStatements = parser.parse(); - if (!containsForbiddenStatements(aqlStatements)) { - MetadataManager.INSTANCE.init(); - IStatementExecutor translator = - statementExecutorFactory.create(aqlStatements, sessionConfig, compilationProvider); - translator.compileAndExecute(hcc, hds, resultDelivery); - } - } catch (AsterixException | TokenMgrError | org.apache.asterix.aqlplus.parser.TokenMgrError pe) { - GlobalConfig.ASTERIX_LOGGER.log(Level.SEVERE, pe.getMessage(), pe); - String errorMessage = ResultUtil.buildParseExceptionMessage(pe, query); - ObjectNode errorResp = - ResultUtil.getErrorResponse(2, errorMessage, "", ResultUtil.extractFullStackTrace(pe)); - sessionConfig.out().write(new ObjectMapper().writeValueAsString(errorResp)); - response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - } catch (Exception e) { - GlobalConfig.ASTERIX_LOGGER.log(Level.SEVERE, e.getMessage(), e); - ResultUtil.apiErrorHandler(sessionConfig.out(), e); - response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - } - } - - private boolean containsForbiddenStatements(List aqlStatements) throws AsterixException { - for (Statement st : aqlStatements) { - if ((st.getCategory() & getAllowedCategories()) == 0) { - throw new AsterixException(String.format(getErrorMessage(), st.getKind())); - } - } - return false; - } - - protected QueryTranslator.ResultDelivery whichResultDelivery(HttpServletRequest request) { - String mode = request.getParameter("mode"); - if (mode != null) { - if ("asynchronous".equals(mode) || "async".equals(mode)) { - return QueryTranslator.ResultDelivery.ASYNC; - } else if ("asynchronous-deferred".equals(mode) || "deferred".equals(mode)) { - return QueryTranslator.ResultDelivery.DEFERRED; - } - } - return QueryTranslator.ResultDelivery.IMMEDIATE; - } - - protected abstract String getQueryParameter(HttpServletRequest request); - - protected abstract byte getAllowedCategories(); - - protected abstract String getErrorMessage(); -}