You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@asterixdb.apache.org by im...@apache.org on 2015/08/25 18:43:59 UTC
[11/51] [partial] incubator-asterixdb git commit: Change folder
structure for Java repackage
http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-app/src/main/java/org/apache/asterix/api/common/FeedWorkCollection.java
----------------------------------------------------------------------
diff --git a/asterix-app/src/main/java/org/apache/asterix/api/common/FeedWorkCollection.java b/asterix-app/src/main/java/org/apache/asterix/api/common/FeedWorkCollection.java
new file mode 100644
index 0000000..736a270
--- /dev/null
+++ b/asterix-app/src/main/java/org/apache/asterix/api/common/FeedWorkCollection.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.asterix.api.common;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import edu.uci.ics.asterix.api.common.SessionConfig.OutputFormat;
+import edu.uci.ics.asterix.aql.base.Statement;
+import edu.uci.ics.asterix.aql.expression.DataverseDecl;
+import edu.uci.ics.asterix.aql.expression.Identifier;
+import edu.uci.ics.asterix.aql.expression.SubscribeFeedStatement;
+import edu.uci.ics.asterix.aql.translator.AqlTranslator;
+import edu.uci.ics.asterix.common.feeds.FeedConnectionRequest;
+import edu.uci.ics.asterix.common.feeds.FeedConnectionRequest.ConnectionStatus;
+import edu.uci.ics.asterix.common.feeds.api.IFeedWork;
+import edu.uci.ics.asterix.common.feeds.api.IFeedWorkEventListener;
+import edu.uci.ics.asterix.feeds.FeedCollectInfo;
+import edu.uci.ics.asterix.om.util.AsterixAppContextInfo;
+import edu.uci.ics.hyracks.api.job.JobId;
+
+/**
+ * A collection of feed management related task, each represented as an implementation of {@code IFeedWork}.
+ */
+public class FeedWorkCollection {
+
+ private static Logger LOGGER = Logger.getLogger(FeedWorkCollection.class.getName());
+
+ /**
+ * The task of subscribing to a feed to obtain data.
+ */
+ public static class SubscribeFeedWork implements IFeedWork {
+
+ private final Runnable runnable;
+
+ private final FeedConnectionRequest request;
+
+ @Override
+ public Runnable getRunnable() {
+ return runnable;
+ }
+
+ public SubscribeFeedWork(String[] locations, FeedConnectionRequest request) {
+ this.runnable = new SubscribeFeedWorkRunnable(locations, request);
+ this.request = request;
+ }
+
+ private static class SubscribeFeedWorkRunnable implements Runnable {
+
+ private final FeedConnectionRequest request;
+ private final String[] locations;
+
+ public SubscribeFeedWorkRunnable(String[] locations, FeedConnectionRequest request) {
+ this.request = request;
+ this.locations = locations;
+ }
+
+ @Override
+ public void run() {
+ try {
+ PrintWriter writer = new PrintWriter(System.out, true);
+ SessionConfig pc = new SessionConfig(writer, OutputFormat.ADM);
+ DataverseDecl dataverseDecl = new DataverseDecl(new Identifier(request.getReceivingFeedId()
+ .getDataverse()));
+ SubscribeFeedStatement subscribeStmt = new SubscribeFeedStatement(locations, request);
+ List<Statement> statements = new ArrayList<Statement>();
+ statements.add(dataverseDecl);
+ statements.add(subscribeStmt);
+ AqlTranslator translator = new AqlTranslator(statements, pc);
+ translator.compileAndExecute(AsterixAppContextInfo.getInstance().getHcc(), null, AqlTranslator.ResultDelivery.SYNC);
+ if (LOGGER.isLoggable(Level.INFO)) {
+ LOGGER.info("Submitted connection requests for execution: " + request);
+ }
+ } catch (Exception e) {
+ if (LOGGER.isLoggable(Level.SEVERE)) {
+ LOGGER.severe("Exception in executing " + request);
+ }
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ public static class FeedSubscribeWorkEventListener implements IFeedWorkEventListener {
+
+ @Override
+ public void workFailed(IFeedWork work, Exception e) {
+ if (LOGGER.isLoggable(Level.WARNING)) {
+ LOGGER.warning(" Feed subscription request " + ((SubscribeFeedWork) work).request
+ + " failed with exception " + e);
+ }
+ }
+
+ @Override
+ public void workCompleted(IFeedWork work) {
+ ((SubscribeFeedWork) work).request.setSubscriptionStatus(ConnectionStatus.ACTIVE);
+ if (LOGGER.isLoggable(Level.INFO)) {
+ LOGGER.warning(" Feed subscription request " + ((SubscribeFeedWork) work).request + " completed ");
+ }
+ }
+
+ }
+
+ public FeedConnectionRequest getRequest() {
+ return request;
+ }
+
+ @Override
+ public String toString() {
+ return "SubscribeFeedWork for [" + request + "]";
+ }
+
+ }
+
+ /**
+ * The task of activating a set of feeds.
+ */
+ public static class ActivateFeedWork implements IFeedWork {
+
+ private final Runnable runnable;
+
+ @Override
+ public Runnable getRunnable() {
+ return runnable;
+ }
+
+ public ActivateFeedWork(List<FeedCollectInfo> feedsToRevive) {
+ this.runnable = new FeedsActivateRunnable(feedsToRevive);
+ }
+
+ public ActivateFeedWork() {
+ this.runnable = new FeedsActivateRunnable();
+ }
+
+ private static class FeedsActivateRunnable implements Runnable {
+
+ private List<FeedCollectInfo> feedsToRevive;
+ private Mode mode;
+
+ public enum Mode {
+ REVIVAL_POST_NODE_REJOIN
+ }
+
+ public FeedsActivateRunnable(List<FeedCollectInfo> feedsToRevive) {
+ this.feedsToRevive = feedsToRevive;
+ }
+
+ public FeedsActivateRunnable() {
+ }
+
+ @Override
+ public void run() {
+ switch (mode) {
+ case REVIVAL_POST_NODE_REJOIN:
+ try {
+ Thread.sleep(10000);
+ } catch (InterruptedException e1) {
+ if (LOGGER.isLoggable(Level.INFO)) {
+ LOGGER.info("Attempt to resume feed interrupted");
+ }
+ throw new IllegalStateException(e1.getMessage());
+ }
+ for (FeedCollectInfo finfo : feedsToRevive) {
+ try {
+ JobId jobId = AsterixAppContextInfo.getInstance().getHcc().startJob(finfo.jobSpec);
+ if (LOGGER.isLoggable(Level.INFO)) {
+ LOGGER.info("Resumed feed :" + finfo.feedConnectionId + " job id " + jobId);
+ LOGGER.info("Job:" + finfo.jobSpec);
+ }
+ } catch (Exception e) {
+ if (LOGGER.isLoggable(Level.WARNING)) {
+ LOGGER.warning("Unable to resume feed " + finfo.feedConnectionId + " "
+ + e.getMessage());
+ }
+ }
+ }
+ }
+ }
+
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-app/src/main/java/org/apache/asterix/api/common/Job.java
----------------------------------------------------------------------
diff --git a/asterix-app/src/main/java/org/apache/asterix/api/common/Job.java b/asterix-app/src/main/java/org/apache/asterix/api/common/Job.java
new file mode 100644
index 0000000..f45a6c0
--- /dev/null
+++ b/asterix-app/src/main/java/org/apache/asterix/api/common/Job.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.asterix.api.common;
+
+import edu.uci.ics.hyracks.api.job.JobSpecification;
+
+public class Job {
+
+ public enum SubmissionMode {
+ SYNCHRONOUS,
+ ASYNCHRONOUS
+ }
+
+ private final JobSpecification jobSpec;
+ private final SubmissionMode submissionMode;
+
+ public Job(JobSpecification jobSpecification, SubmissionMode submissionMode) {
+ this.jobSpec = jobSpecification;
+ this.submissionMode = submissionMode;
+ }
+
+ public Job(JobSpecification jobSpec) {
+ this.jobSpec = jobSpec;
+ this.submissionMode = SubmissionMode.SYNCHRONOUS;
+ }
+
+ public JobSpecification getJobSpec() {
+ return jobSpec;
+ }
+
+ public SubmissionMode getSubmissionMode() {
+ return submissionMode;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-app/src/main/java/org/apache/asterix/api/common/SessionConfig.java
----------------------------------------------------------------------
diff --git a/asterix-app/src/main/java/org/apache/asterix/api/common/SessionConfig.java b/asterix-app/src/main/java/org/apache/asterix/api/common/SessionConfig.java
new file mode 100644
index 0000000..27d981e
--- /dev/null
+++ b/asterix-app/src/main/java/org/apache/asterix/api/common/SessionConfig.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.asterix.api.common;
+
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * SessionConfig captures several different parameters for controlling
+ * the execution of an APIFramework call.
+ * <li> It specifies how the execution will proceed (for instance,
+ * whether to optimize, or whether to execute at all).
+ * <li> It allows you specify where the primary execution output will
+ * be sent.
+ * <li> It also allows you to request additional output for optional
+ * out-of-band data about the execution (query plan, etc).
+ * <li> It allows you to specify the output format for the primary
+ * execution output - JSON, CSV, etc.
+ * <li> It allows you to specify output format-specific parameters.
+ */
+
+public class SessionConfig {
+ /**
+ * Used to specify the output format for the primary execution.
+ */
+ public enum OutputFormat {
+ ADM,
+ JSON,
+ CSV
+ };
+
+ /**
+ * Produce out-of-band output for Hyracks Job.
+ */
+ public static final String OOB_HYRACKS_JOB = "oob-hyracks-job";
+
+ /**
+ * Produce out-of-band output for Expression Tree.
+ */
+ public static final String OOB_EXPR_TREE = "oob-expr-tree";
+
+ /**
+ * Produce out-of-band output for Rewritten Expression Tree.
+ */
+ public static final String OOB_REWRITTEN_EXPR_TREE = "oob-rewritten-expr-tree";
+
+ /**
+ * Produce out-of-band output for Logical Plan.
+ */
+ public static final String OOB_LOGICAL_PLAN = "oob-logical-plan";
+
+ /**
+ * Produce out-of-band output for Optimized Logical Plan.
+ */
+ public static final String OOB_OPTIMIZED_LOGICAL_PLAN = "oob-optimized-logical-plan";
+
+ /**
+ * Format flag: print only physical ops (for optimizer tests).
+ */
+ public static final String FORMAT_ONLY_PHYSICAL_OPS = "format-only-physical-ops";
+
+ /**
+ * Format flag: wrap out-of-band data in HTML.
+ */
+ public static final String FORMAT_HTML = "format-html";
+
+ /**
+ * Format flag: print CSV header line.
+ */
+ public static final String FORMAT_CSV_HEADER = "format-csv-header";
+
+ // Standard execution flags.
+ private final boolean executeQuery;
+ private final boolean generateJobSpec;
+ private final boolean optimize;
+
+ // Output path for primary execution.
+ private final PrintWriter out;
+
+ // Output format.
+ private final OutputFormat fmt;
+
+ // Flags.
+ private final Map<String,Boolean> flags;
+
+ /**
+ * Create a SessionConfig object with all default values:
+ *
+ * - All format flags set to "false".
+ * - All out-of-band outputs set to "null".
+ * - "Optimize" set to "true".
+ * - "Execute Query" set to "true".
+ * - "Generate Job Spec" set to "true".
+ * @param out PrintWriter for execution output.
+ * @param fmt Output format for execution output.
+ */
+ public SessionConfig(PrintWriter out, OutputFormat fmt) {
+ this(out, fmt, true, true, true);
+ }
+
+ /**
+ * Create a SessionConfig object with all optional values set to defaults:
+ *
+ * - All format flags set to "false".
+ * - All out-of-band outputs set to "false".
+ * @param out PrintWriter for execution output.
+ * @param fmt Output format for execution output.
+ * @param optimize Whether to optimize the execution.
+ * @param executeQuery Whether to execute the query or not.
+ * @param generateJobSpec Whether to generate the Hyracks job specification (if
+ * false, job cannot be executed).
+ */
+ public SessionConfig(PrintWriter out, OutputFormat fmt, boolean optimize, boolean executeQuery, boolean generateJobSpec) {
+ this.out = out;
+ this.fmt = fmt;
+ this.optimize = optimize;
+ this.executeQuery = executeQuery;
+ this.generateJobSpec = generateJobSpec;
+ this.flags = new HashMap<String,Boolean>();
+ }
+
+ /**
+ * Retrieve the PrintWriter to produce output to.
+ */
+ public PrintWriter out() {
+ return this.out;
+ }
+
+ /**
+ * Retrieve the OutputFormat for this execution.
+ */
+ public OutputFormat fmt() {
+ return this.fmt;
+ }
+
+ /**
+ * Retrieve the value of the "execute query" flag.
+ */
+ public boolean isExecuteQuery() {
+ return executeQuery;
+ }
+
+ /**
+ * Retrieve the value of the "optimize" flag.
+ */
+ public boolean isOptimize() {
+ return optimize;
+ }
+
+ /**
+ * Retrieve the value of the "generate job spec" flag.
+ */
+ public boolean isGenerateJobSpec() {
+ return generateJobSpec;
+ }
+
+ /**
+ * Specify all out-of-band settings at once. For convenience of older code.
+ */
+ public void setOOBData(boolean expr_tree, boolean rewritten_expr_tree,
+ boolean logical_plan, boolean optimized_logical_plan,
+ boolean hyracks_job) {
+ this.set(OOB_EXPR_TREE, expr_tree);
+ this.set(OOB_REWRITTEN_EXPR_TREE, rewritten_expr_tree);
+ this.set(OOB_LOGICAL_PLAN, logical_plan);
+ this.set(OOB_OPTIMIZED_LOGICAL_PLAN, optimized_logical_plan);
+ this.set(OOB_HYRACKS_JOB, hyracks_job);
+ }
+
+ /**
+ * Specify a flag.
+ * @param flag One of the OOB_ or FORMAT_ constants from this class.
+ * @param value Value for the flag (all flags default to "false").
+ */
+ public void set(String flag, boolean value) {
+ flags.put(flag, Boolean.valueOf(value));
+ }
+
+ /**
+ * Retrieve the setting of a format-specific flag.
+ * @param flag One of the FORMAT_ constants from this class.
+ * @returns true or false (all flags default to "false").
+ */
+ public boolean is(String flag) {
+ Boolean value = flags.get(flag);
+ return value == null ? false : value.booleanValue();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/APIServlet.java
----------------------------------------------------------------------
diff --git a/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/APIServlet.java b/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/APIServlet.java
new file mode 100644
index 0000000..4984741
--- /dev/null
+++ b/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/APIServlet.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.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 java.util.List;
+import java.util.logging.Level;
+
+import javax.imageio.ImageIO;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import edu.uci.ics.asterix.api.common.SessionConfig;
+import edu.uci.ics.asterix.api.common.SessionConfig.OutputFormat;
+import edu.uci.ics.asterix.aql.base.Statement;
+import edu.uci.ics.asterix.aql.parser.AQLParser;
+import edu.uci.ics.asterix.aql.parser.ParseException;
+import edu.uci.ics.asterix.aql.parser.TokenMgrError;
+import edu.uci.ics.asterix.aql.translator.AqlTranslator;
+import edu.uci.ics.asterix.common.config.GlobalConfig;
+import edu.uci.ics.asterix.metadata.MetadataManager;
+import edu.uci.ics.asterix.result.ResultReader;
+import edu.uci.ics.asterix.result.ResultUtils;
+import edu.uci.ics.hyracks.api.client.IHyracksClientConnection;
+import edu.uci.ics.hyracks.api.dataset.IHyracksDataset;
+import edu.uci.ics.hyracks.client.dataset.HyracksDataset;
+
+public class APIServlet extends HttpServlet {
+ private static final long serialVersionUID = 1L;
+
+ private static final String HYRACKS_CONNECTION_ATTR = "edu.uci.ics.asterix.HYRACKS_CONNECTION";
+
+ private static final String HYRACKS_DATASET_ATTR = "edu.uci.ics.asterix.HYRACKS_DATASET";
+
+ @Override
+ public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ OutputFormat format;
+ boolean csv_and_header = false;
+ String output = request.getParameter("output-format");
+ if (output.equals("ADM")) {
+ format = OutputFormat.ADM;
+ }
+ else if (output.equals("CSV")) {
+ format = OutputFormat.CSV;
+ }
+ else if (output.equals("CSV-Header")) {
+ format = OutputFormat.CSV;
+ csv_and_header = true;
+ }
+ else {
+ // Default output format
+ format = OutputFormat.JSON;
+ }
+
+ String query = request.getParameter("query");
+ String printExprParam = request.getParameter("print-expr-tree");
+ String printRewrittenExprParam = request.getParameter("print-rewritten-expr-tree");
+ String printLogicalPlanParam = request.getParameter("print-logical-plan");
+ String printOptimizedLogicalPlanParam = request.getParameter("print-optimized-logical-plan");
+ String printJob = request.getParameter("print-job");
+ String executeQuery = request.getParameter("execute-query");
+ response.setCharacterEncoding("utf-8");
+ response.setContentType("text/html");
+ 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);
+ }
+ }
+ AQLParser parser = new AQLParser(query);
+ List<Statement> aqlStatements = parser.parse();
+ SessionConfig sessionConfig = new SessionConfig(out, format, true, isSet(executeQuery), true);
+ sessionConfig.set(SessionConfig.FORMAT_HTML, true);
+ sessionConfig.set(SessionConfig.FORMAT_CSV_HEADER, csv_and_header);
+ sessionConfig.setOOBData(isSet(printExprParam), isSet(printRewrittenExprParam),
+ isSet(printLogicalPlanParam), isSet(printOptimizedLogicalPlanParam),
+ isSet(printJob));
+ MetadataManager.INSTANCE.init();
+ AqlTranslator aqlTranslator = new AqlTranslator(aqlStatements, sessionConfig);
+ double duration = 0;
+ long startTime = System.currentTimeMillis();
+ aqlTranslator.compileAndExecute(hcc, hds, AqlTranslator.ResultDelivery.SYNC);
+ long endTime = System.currentTimeMillis();
+ duration = (endTime - startTime) / 1000.00;
+ out.println("<PRE>Duration of all jobs: " + duration + " sec</PRE>");
+ } catch (ParseException | TokenMgrError | edu.uci.ics.asterix.aqlplus.parser.TokenMgrError pe) {
+ GlobalConfig.ASTERIX_LOGGER.log(Level.INFO, pe.toString(), pe);
+ ResultUtils.webUIParseExceptionHandler(out, pe, query);
+ } catch (Exception e) {
+ GlobalConfig.ASTERIX_LOGGER.log(Level.SEVERE, e.getMessage(), e);
+ ResultUtils.webUIErrorHandler(out, e);
+ }
+ }
+
+ @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 = "/webui/querytemplate.html";
+ } else {
+ resourcePath = requestURI;
+ }
+
+ InputStream is = APIServlet.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);
+ line = br.readLine();
+ }
+
+ PrintWriter out = response.getWriter();
+ out.println(sb.toString());
+ }
+
+ private static boolean isSet(String requestParameter) {
+ return (requestParameter != null && requestParameter.equals("true"));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/AQLAPIServlet.java
----------------------------------------------------------------------
diff --git a/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/AQLAPIServlet.java b/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/AQLAPIServlet.java
new file mode 100644
index 0000000..60e1261
--- /dev/null
+++ b/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/AQLAPIServlet.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.asterix.api.http.servlet;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import edu.uci.ics.asterix.aql.base.Statement.Kind;
+
+public class AQLAPIServlet extends RESTAPIServlet {
+
+ private static final long serialVersionUID = 1L;
+
+ private static final String AQL_STMT_PARAM_NAME = "aql";
+
+ private static final List<Kind> allowedStatements = new ArrayList<>();
+
+ static {
+ for (Kind k : Kind.values()) {
+ allowedStatements.add(k);
+ }
+ }
+
+ @Override
+ protected String getQueryParameter(HttpServletRequest request) {
+ return request.getParameter(AQL_STMT_PARAM_NAME);
+ }
+
+ @Override
+ protected List<Kind> getAllowedStatements() {
+ return allowedStatements;
+ }
+
+ @Override
+ protected String getErrorMessage() {
+ throw new IllegalStateException();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ConnectorAPIServlet.java
----------------------------------------------------------------------
diff --git a/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ConnectorAPIServlet.java b/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ConnectorAPIServlet.java
new file mode 100644
index 0000000..267aac5
--- /dev/null
+++ b/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ConnectorAPIServlet.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.asterix.api.http.servlet;
+
+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 org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import edu.uci.ics.asterix.feeds.CentralFeedManager;
+import edu.uci.ics.asterix.metadata.MetadataManager;
+import edu.uci.ics.asterix.metadata.MetadataTransactionContext;
+import edu.uci.ics.asterix.metadata.declared.AqlMetadataProvider;
+import edu.uci.ics.asterix.metadata.entities.Dataset;
+import edu.uci.ics.asterix.metadata.utils.DatasetUtils;
+import edu.uci.ics.asterix.om.types.ARecordType;
+import edu.uci.ics.hyracks.api.client.IHyracksClientConnection;
+import edu.uci.ics.hyracks.api.client.NodeControllerInfo;
+import edu.uci.ics.hyracks.dataflow.std.file.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 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;
+
+ private static final String HYRACKS_CONNECTION_ATTR = "edu.uci.ics.asterix.HYRACKS_CONNECTION";
+
+ @Override
+ public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ response.setContentType("text/html");
+ response.setCharacterEncoding("utf-8");
+ PrintWriter out = response.getWriter();
+ try {
+ JSONObject jsonResponse = new JSONObject();
+ 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.
+ AqlMetadataProvider metadataProvider = new AqlMetadataProvider(null, CentralFeedManager.getInstance());
+ 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(dataverseName, dataset.getItemTypeName());
+ List<List<String>> primaryKeys = DatasetUtils.getPartitioningKeys(dataset);
+ StringBuilder pkStrBuf = new StringBuilder();
+ for (List<String> 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(), hcc.getNodeControllerInfos());
+ // 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(JSONObject jsonResponse, FileSplit[] fileSplits, ARecordType recordType,
+ String primaryKeys, Map<String, NodeControllerInfo> nodeMap) throws Exception {
+ JSONArray partititons = new JSONArray();
+ // Adds a primary key.
+ jsonResponse.put("keys", primaryKeys);
+ // Adds record type.
+ jsonResponse.put("type", recordType.toJSON());
+ // Generates file partitions.
+ for (FileSplit split : fileSplits) {
+ String ipAddress = nodeMap.get(split.getNodeName()).getNetworkAddress().getAddress().toString();
+ String path = split.getLocalFile().getFile().getAbsolutePath();
+ FilePartition partition = new FilePartition(ipAddress, path);
+ partititons.put(partition.toJSONObject());
+ }
+ // Generates the response object which contains the splits.
+ jsonResponse.put("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 JSONObject toJSONObject() throws JSONException {
+ JSONObject partition = new JSONObject();
+ partition.put("ip", ipAddress);
+ partition.put("path", path);
+ return partition;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/DDLAPIServlet.java
----------------------------------------------------------------------
diff --git a/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/DDLAPIServlet.java b/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/DDLAPIServlet.java
new file mode 100644
index 0000000..e43a15a
--- /dev/null
+++ b/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/DDLAPIServlet.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.asterix.api.http.servlet;
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import edu.uci.ics.asterix.aql.base.Statement;
+import edu.uci.ics.asterix.aql.base.Statement.Kind;
+
+public class DDLAPIServlet extends RESTAPIServlet {
+ private static final long serialVersionUID = 1L;
+
+ protected String getQueryParameter(HttpServletRequest request) {
+ return request.getParameter("ddl");
+ }
+
+ protected List<Statement.Kind> getAllowedStatements() {
+ Kind[] statementsArray = { Kind.DATAVERSE_DECL, Kind.DATAVERSE_DROP, Kind.DATASET_DECL, Kind.NODEGROUP_DECL,
+ Kind.NODEGROUP_DROP, Kind.TYPE_DECL, Kind.TYPE_DROP, Kind.CREATE_INDEX, Kind.INDEX_DECL,
+ Kind.CREATE_DATAVERSE, Kind.DATASET_DROP, Kind.INDEX_DROP, Kind.CREATE_FUNCTION, Kind.FUNCTION_DROP,
+ Kind.CREATE_PRIMARY_FEED, Kind.CREATE_SECONDARY_FEED, Kind.DROP_FEED, Kind.CREATE_FEED_POLICY, Kind.DROP_FEED_POLICY };
+ return Arrays.asList(statementsArray);
+ }
+
+ protected String getErrorMessage() {
+ return "Invalid statement: Non-DDL statement %s to the DDL API.";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/FeedServlet.java
----------------------------------------------------------------------
diff --git a/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/FeedServlet.java b/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/FeedServlet.java
new file mode 100644
index 0000000..3fe1ff7
--- /dev/null
+++ b/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/FeedServlet.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.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 java.util.Collection;
+
+import javax.imageio.ImageIO;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import edu.uci.ics.asterix.common.feeds.FeedActivity;
+import edu.uci.ics.asterix.common.feeds.FeedActivity.FeedActivityDetails;
+import edu.uci.ics.asterix.common.feeds.FeedConnectionId;
+import edu.uci.ics.asterix.common.feeds.FeedId;
+import edu.uci.ics.asterix.common.feeds.api.IFeedLoadManager;
+import edu.uci.ics.asterix.common.feeds.api.IFeedRuntime.FeedRuntimeType;
+import edu.uci.ics.asterix.feeds.CentralFeedManager;
+
+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;
+ if (requestURI.startsWith("/webui/static")) {
+ outStr = sb.toString();
+ } else {
+ Collection<FeedActivity> lfa = CentralFeedManager.getInstance().getFeedLoadManager().getFeedActivities();
+ StringBuilder ldStr = new StringBuilder();
+ ldStr.append("<br />");
+ ldStr.append("<br />");
+ if (lfa == null || lfa.isEmpty()) {
+ ldStr.append("Currently there are no active feeds in AsterixDB");
+ } else {
+ ldStr.append("Active Feeds");
+ }
+ insertTable(ldStr, lfa);
+ outStr = String.format(sb.toString(), ldStr.toString());
+
+ }
+
+ PrintWriter out = response.getWriter();
+ out.println(outStr);
+ }
+
+ private void insertTable(StringBuilder html, Collection<FeedActivity> list) {
+ html.append("<table style=\"width:100%\">");
+ html.append("<th>" + FeedServletUtil.Constants.TABLE_HEADER_FEED_NAME + "</th>");
+ html.append("<th>" + FeedServletUtil.Constants.TABLE_HEADER_DATASET_NAME + "</th>");
+ html.append("<th>" + FeedServletUtil.Constants.TABLE_HEADER_ACTIVE_SINCE + "</th>");
+ html.append("<th>" + FeedServletUtil.Constants.TABLE_HEADER_INTAKE_STAGE + "</th>");
+ html.append("<th>" + FeedServletUtil.Constants.TABLE_HEADER_COMPUTE_STAGE + "</th>");
+ html.append("<th>" + FeedServletUtil.Constants.TABLE_HEADER_STORE_STAGE + "</th>");
+ html.append("<th>" + FeedServletUtil.Constants.TABLE_HEADER_INTAKE_RATE + "</th>");
+ html.append("<th>" + FeedServletUtil.Constants.TABLE_HEADER_STORE_RATE + "</th>");
+ for (FeedActivity activity : list) {
+ insertRow(html, activity);
+ }
+ }
+
+ private void insertRow(StringBuilder html, FeedActivity activity) {
+ String intake = activity.getFeedActivityDetails().get(FeedActivityDetails.INTAKE_LOCATIONS);
+ String compute = activity.getFeedActivityDetails().get(FeedActivityDetails.COMPUTE_LOCATIONS);
+ String store = activity.getFeedActivityDetails().get(FeedActivityDetails.STORAGE_LOCATIONS);
+
+ IFeedLoadManager loadManager = CentralFeedManager.getInstance().getFeedLoadManager();
+ FeedConnectionId connectionId = new FeedConnectionId(new FeedId(activity.getDataverseName(),
+ activity.getFeedName()), activity.getDatasetName());
+ int intakeRate = loadManager.getOutflowRate(connectionId, FeedRuntimeType.COLLECT) * intake.split(",").length;
+ int storeRate = loadManager.getOutflowRate(connectionId, FeedRuntimeType.STORE) * store.split(",").length;
+
+ html.append("<tr>");
+ html.append("<td>" + activity.getFeedName() + "</td>");
+ html.append("<td>" + activity.getDatasetName() + "</td>");
+ html.append("<td>" + activity.getConnectTimestamp() + "</td>");
+ //html.append("<td>" + insertLink(html, FeedDashboardServlet.getParameterizedURL(activity), "Details") + "</td>");
+ html.append("<td>" + intake + "</td>");
+ html.append("<td>" + compute + "</td>");
+ html.append("<td>" + store + "</td>");
+ String color = "black";
+ if (intakeRate > storeRate) {
+ color = "red";
+ }
+ if (intakeRate < 0) {
+ html.append("<td>" + "UNKNOWN" + "</td>");
+ } else {
+ html.append("<td>" + insertColoredText("" + intakeRate, color) + " rec/sec" + "</td>");
+ }
+ if (storeRate < 0) {
+ html.append("<td>" + "UNKNOWN" + "</td>");
+ } else {
+ html.append("<td>" + insertColoredText("" + storeRate, color) + " rec/sec" + "</td>");
+ }
+ html.append("</tr>");
+ }
+
+ private String insertLink(StringBuilder html, String url, String displayText) {
+ return ("<a href=\"" + url + "\">" + displayText + "</a>");
+ }
+
+ private String insertColoredText(String s, String color) {
+ return "<font color=\"" + color + "\">" + s + "</font>";
+ }
+}
+
+
http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/FeedServletUtil.java
----------------------------------------------------------------------
diff --git a/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/FeedServletUtil.java b/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/FeedServletUtil.java
new file mode 100644
index 0000000..76e2614
--- /dev/null
+++ b/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/FeedServletUtil.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.asterix.api.http.servlet;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.Socket;
+import java.nio.CharBuffer;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import edu.uci.ics.asterix.common.feeds.FeedConnectionId;
+import edu.uci.ics.asterix.feeds.FeedLifecycleListener;
+import edu.uci.ics.asterix.metadata.feeds.RemoteSocketMessageListener;
+
+public class FeedServletUtil {
+
+ private static final Logger LOGGER = Logger.getLogger(FeedServletUtil.class.getName());
+ private static final char EOL = (char) "\n".getBytes()[0];
+
+ public static final class Constants {
+ public static final String TABLE_HEADER_FEED_NAME = "Feed";
+ public static final String TABLE_HEADER_DATASET_NAME = "Dataset";
+ public static final String TABLE_HEADER_ACTIVE_SINCE = "Timestamp";
+ public static final String TABLE_HEADER_INTAKE_STAGE = "Intake Stage";
+ public static final String TABLE_HEADER_COMPUTE_STAGE = "Compute Stage";
+ public static final String TABLE_HEADER_STORE_STAGE = "Store Stage";
+ public static final String TABLE_HEADER_INTAKE_RATE = "Intake";
+ public static final String TABLE_HEADER_STORE_RATE = "Store";
+ }
+
+ public static void initiateSubscription(FeedConnectionId feedId, String host, int port) throws IOException {
+ LinkedBlockingQueue<String> outbox = new LinkedBlockingQueue<String>();
+ int subscriptionPort = port + 1;
+ Socket sc = new Socket(host, subscriptionPort);
+ InputStream in = sc.getInputStream();
+
+ CharBuffer buffer = CharBuffer.allocate(50);
+ char ch = 0;
+ while (ch != EOL) {
+ buffer.put(ch);
+ ch = (char) in.read();
+ }
+ buffer.flip();
+ String s = new String(buffer.array());
+ int feedSubscriptionPort = Integer.parseInt(s.trim());
+ if (LOGGER.isLoggable(Level.INFO)) {
+ LOGGER.info("Response from Super Feed Manager Report Service " + port + " will connect at " + host + " "
+ + port);
+ }
+
+ // register the feed subscription queue with FeedLifecycleListener
+ FeedLifecycleListener.INSTANCE.registerFeedReportQueue(feedId, outbox);
+ RemoteSocketMessageListener listener = new RemoteSocketMessageListener(host, feedSubscriptionPort, outbox);
+ listener.start();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/HyracksProperties.java
----------------------------------------------------------------------
diff --git a/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/HyracksProperties.java b/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/HyracksProperties.java
new file mode 100644
index 0000000..2805d7f
--- /dev/null
+++ b/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/HyracksProperties.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.asterix.api.http.servlet;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+public class HyracksProperties {
+ private final InputStream is;
+
+ private final Properties properties;
+
+ private static String HYRACKS_IP = "127.0.0.1";
+
+ private static int HYRACKS_PORT = 1098;
+
+ public HyracksProperties() throws IOException {
+ is = HyracksProperties.class.getClassLoader().getResourceAsStream("hyracks-deployment.properties");
+ properties = new Properties();
+ properties.load(is);
+ }
+
+ public String getHyracksIPAddress() {
+ String strIP = properties.getProperty("cc.ip");
+ if (strIP == null) {
+ strIP = HYRACKS_IP;
+ }
+ return strIP;
+ }
+
+ public int getHyracksPort() {
+ String strPort = properties.getProperty("cc.port");
+ int port = HYRACKS_PORT;
+ if (strPort != null) {
+ port = Integer.parseInt(strPort);
+ }
+ return port;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryAPIServlet.java
----------------------------------------------------------------------
diff --git a/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryAPIServlet.java b/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryAPIServlet.java
new file mode 100644
index 0000000..c3dc1f9
--- /dev/null
+++ b/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryAPIServlet.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.asterix.api.http.servlet;
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import edu.uci.ics.asterix.aql.base.Statement;
+import edu.uci.ics.asterix.aql.base.Statement.Kind;
+
+public class QueryAPIServlet extends RESTAPIServlet {
+ private static final long serialVersionUID = 1L;
+
+ protected String getQueryParameter(HttpServletRequest request) {
+ return request.getParameter("query");
+ }
+
+ protected List<Statement.Kind> getAllowedStatements() {
+ Kind[] statementsArray = { Kind.DATAVERSE_DECL, Kind.FUNCTION_DECL, Kind.QUERY, Kind.SET, Kind.WRITE, Kind.RUN };
+ return Arrays.asList(statementsArray);
+ }
+
+ protected String getErrorMessage() {
+ return "Invalid statement: Non-query statement %s to the query API.";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryResultAPIServlet.java
----------------------------------------------------------------------
diff --git a/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryResultAPIServlet.java b/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryResultAPIServlet.java
new file mode 100644
index 0000000..3caed6b
--- /dev/null
+++ b/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryResultAPIServlet.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.asterix.api.http.servlet;
+
+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 org.json.JSONArray;
+import org.json.JSONObject;
+
+import edu.uci.ics.asterix.api.common.SessionConfig;
+import edu.uci.ics.asterix.result.ResultReader;
+import edu.uci.ics.asterix.result.ResultUtils;
+import edu.uci.ics.hyracks.api.client.HyracksConnection;
+import edu.uci.ics.hyracks.api.client.IHyracksClientConnection;
+import edu.uci.ics.hyracks.api.dataset.IHyracksDataset;
+import edu.uci.ics.hyracks.api.dataset.ResultSetId;
+import edu.uci.ics.hyracks.api.job.JobId;
+import edu.uci.ics.hyracks.client.dataset.HyracksDataset;
+
+public class QueryResultAPIServlet extends HttpServlet {
+ private static final long serialVersionUID = 1L;
+
+ private static final String HYRACKS_CONNECTION_ATTR = "edu.uci.ics.asterix.HYRACKS_CONNECTION";
+
+ private static final String HYRACKS_DATASET_ATTR = "edu.uci.ics.asterix.HYRACKS_DATASET";
+
+ @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 {
+ 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);
+ }
+ }
+ JSONObject handleObj = new JSONObject(strHandle);
+ JSONArray handle = handleObj.getJSONArray("handle");
+ JobId jobId = new JobId(handle.getLong(0));
+ ResultSetId rsId = new ResultSetId(handle.getLong(1));
+
+ ResultReader resultReader = new ResultReader(hcc, 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);
+ ResultUtils.displayResults(resultReader, sessionConfig);
+
+ } catch (Exception e) {
+ out.println(e.getMessage());
+ e.printStackTrace(out);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryStatusAPIServlet.java
----------------------------------------------------------------------
diff --git a/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryStatusAPIServlet.java b/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryStatusAPIServlet.java
new file mode 100644
index 0000000..d793bfb
--- /dev/null
+++ b/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryStatusAPIServlet.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.asterix.api.http.servlet;
+
+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 org.json.JSONArray;
+import org.json.JSONObject;
+
+import edu.uci.ics.asterix.result.ResultReader;
+import edu.uci.ics.hyracks.api.client.IHyracksClientConnection;
+import edu.uci.ics.hyracks.api.dataset.IHyracksDataset;
+import edu.uci.ics.hyracks.api.dataset.ResultSetId;
+import edu.uci.ics.hyracks.api.job.JobId;
+import edu.uci.ics.hyracks.client.dataset.HyracksDataset;
+
+public class QueryStatusAPIServlet extends HttpServlet {
+ private static final long serialVersionUID = 1L;
+
+ private static final String HYRACKS_CONNECTION_ATTR = "edu.uci.ics.asterix.HYRACKS_CONNECTION";
+
+ private static final String HYRACKS_DATASET_ATTR = "edu.uci.ics.asterix.HYRACKS_DATASET";
+
+ @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);
+ }
+ }
+ JSONObject handleObj = new JSONObject(strHandle);
+ JSONArray handle = handleObj.getJSONArray("handle");
+ JobId jobId = new JobId(handle.getLong(0));
+ ResultSetId rsId = new ResultSetId(handle.getLong(1));
+
+ /* TODO(madhusudancs): We need to find a way to JSON serialize default format obtained from
+ * metadataProvider in the AQLTranslator and store it as part of the result handle.
+ */
+ ResultReader resultReader = new ResultReader(hcc, hds);
+ resultReader.open(jobId, rsId);
+
+ JSONObject jsonResponse = new JSONObject();
+ 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/incubator-asterixdb/blob/34d81630/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/RESTAPIServlet.java
----------------------------------------------------------------------
diff --git a/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/RESTAPIServlet.java b/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/RESTAPIServlet.java
new file mode 100644
index 0000000..dd19c97
--- /dev/null
+++ b/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/RESTAPIServlet.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.asterix.api.http.servlet;
+
+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 org.apache.commons.io.IOUtils;
+import org.json.JSONObject;
+
+import edu.uci.ics.asterix.api.common.SessionConfig;
+import edu.uci.ics.asterix.api.common.SessionConfig.OutputFormat;
+import edu.uci.ics.asterix.aql.base.Statement;
+import edu.uci.ics.asterix.aql.base.Statement.Kind;
+import edu.uci.ics.asterix.aql.parser.AQLParser;
+import edu.uci.ics.asterix.aql.parser.ParseException;
+import edu.uci.ics.asterix.aql.parser.TokenMgrError;
+import edu.uci.ics.asterix.aql.translator.AqlTranslator;
+import edu.uci.ics.asterix.common.config.GlobalConfig;
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.metadata.MetadataManager;
+import edu.uci.ics.asterix.result.ResultReader;
+import edu.uci.ics.asterix.result.ResultUtils;
+import edu.uci.ics.hyracks.api.client.IHyracksClientConnection;
+import edu.uci.ics.hyracks.api.dataset.IHyracksDataset;
+import edu.uci.ics.hyracks.client.dataset.HyracksDataset;
+
+abstract class RESTAPIServlet extends HttpServlet {
+ private static final long serialVersionUID = 1L;
+
+ private static final String HYRACKS_CONNECTION_ATTR = "edu.uci.ics.asterix.HYRACKS_CONNECTION";
+
+ private static final String HYRACKS_DATASET_ATTR = "edu.uci.ics.asterix.HYRACKS_DATASET";
+
+ /**
+ * 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");
+
+ // JSON output is the default; most generally useful for a
+ // programmatic HTTP API
+ OutputFormat format = OutputFormat.JSON;
+
+ // First check the "output" servlet parameter.
+ String output = request.getParameter("output");
+ String accept = request.getHeader("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 != null) {
+ if (accept.contains("application/x-adm")) {
+ format = OutputFormat.ADM;
+ } else if (accept.contains("text/csv")) {
+ format = OutputFormat.CSV;
+ }
+ }
+ }
+
+ SessionConfig sessionConfig = new SessionConfig(response.getWriter(), format);
+
+ // Now that format is set, output the content-type
+ switch (format) {
+ case ADM:
+ response.setContentType("application/x-adm");
+ break;
+ case JSON:
+ response.setContentType("application/json");
+ break;
+ case CSV: {
+ // Check for header parameter or in Accept:.
+ if ("present".equals(request.getParameter("header")) ||
+ (accept != null && 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 {
+ SessionConfig sessionConfig = initResponse(request, response);
+ AqlTranslator.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);
+ }
+ }
+
+ AQLParser parser = new AQLParser(query);
+ List<Statement> aqlStatements = parser.parse();
+ if (!containsForbiddenStatements(aqlStatements)) {
+ MetadataManager.INSTANCE.init();
+ AqlTranslator aqlTranslator = new AqlTranslator(aqlStatements, sessionConfig);
+ aqlTranslator.compileAndExecute(hcc, hds, resultDelivery);
+ }
+ } catch (ParseException | TokenMgrError | edu.uci.ics.asterix.aqlplus.parser.TokenMgrError pe) {
+ GlobalConfig.ASTERIX_LOGGER.log(Level.SEVERE, pe.getMessage(), pe);
+ String errorMessage = ResultUtils.buildParseExceptionMessage(pe, query);
+ JSONObject errorResp = ResultUtils.getErrorResponse(2, errorMessage, "", "");
+ sessionConfig.out().write(errorResp.toString());
+ response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ } catch (Exception e) {
+ GlobalConfig.ASTERIX_LOGGER.log(Level.SEVERE, e.getMessage(), e);
+ ResultUtils.apiErrorHandler(sessionConfig.out(), e);
+ response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ }
+ }
+
+ private boolean containsForbiddenStatements(List<Statement> aqlStatements) throws AsterixException {
+ for (Statement st : aqlStatements) {
+ if (!getAllowedStatements().contains(st.getKind())) {
+ throw new AsterixException(String.format(getErrorMessage(), st.getKind()));
+ }
+ }
+ return false;
+ }
+
+ protected AqlTranslator.ResultDelivery whichResultDelivery(HttpServletRequest request) {
+ String mode = request.getParameter("mode");
+ if (mode != null) {
+ if (mode.equals("asynchronous")) {
+ return AqlTranslator.ResultDelivery.ASYNC;
+ } else if (mode.equals("asynchronous-deferred")) {
+ return AqlTranslator.ResultDelivery.ASYNC_DEFERRED;
+ }
+ }
+ return AqlTranslator.ResultDelivery.SYNC;
+ }
+
+ protected abstract String getQueryParameter(HttpServletRequest request);
+
+ protected abstract List<Kind> getAllowedStatements();
+
+ protected abstract String getErrorMessage();
+}
http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ShutdownAPIServlet.java
----------------------------------------------------------------------
diff --git a/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ShutdownAPIServlet.java b/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ShutdownAPIServlet.java
new file mode 100644
index 0000000..4e16254
--- /dev/null
+++ b/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ShutdownAPIServlet.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.asterix.api.http.servlet;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.charset.StandardCharsets;
+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 org.apache.commons.io.IOUtils;
+
+import edu.uci.ics.asterix.api.common.SessionConfig.OutputFormat;
+import edu.uci.ics.asterix.common.config.GlobalConfig;
+import edu.uci.ics.asterix.result.ResultUtils;
+import edu.uci.ics.hyracks.api.client.IHyracksClientConnection;
+
+public class ShutdownAPIServlet extends HttpServlet {
+ private static final long serialVersionUID = 1L;
+
+ private static final String HYRACKS_CONNECTION_ATTR = "edu.uci.ics.asterix.HYRACKS_CONNECTION";
+
+ private static final String HYRACKS_DATASET_ATTR = "edu.uci.ics.asterix.HYRACKS_DATASET";
+
+ @Override
+ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,
+ IOException {
+
+ response.setContentType("application/json");
+ response.setCharacterEncoding("utf-8");
+
+ PrintWriter out = response.getWriter();
+ OutputFormat format = OutputFormat.JSON;
+ String accept = request.getHeader("Accept");
+ if ((accept == null) || (accept.contains("application/x-adm"))) {
+ format = OutputFormat.ADM;
+ } else if (accept.contains("application/json")) {
+ format = OutputFormat.JSON;
+ }
+ StringWriter sw = new StringWriter();
+ IOUtils.copy(request.getInputStream(), sw, StandardCharsets.UTF_8.name());
+
+ ServletContext context = getServletContext();
+ IHyracksClientConnection hcc;
+ try {
+ synchronized (context) {
+ hcc = (IHyracksClientConnection) context.getAttribute(HYRACKS_CONNECTION_ATTR);
+ response.setStatus(HttpServletResponse.SC_ACCEPTED);
+ hcc.stopCluster();
+ }
+ } catch (Exception e) {
+ GlobalConfig.ASTERIX_LOGGER.log(Level.SEVERE, e.getMessage(), e);
+ ResultUtils.apiErrorHandler(out, e);
+ response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ }
+ }
+
+ @Override
+ public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/UpdateAPIServlet.java
----------------------------------------------------------------------
diff --git a/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/UpdateAPIServlet.java b/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/UpdateAPIServlet.java
new file mode 100644
index 0000000..4bbd712
--- /dev/null
+++ b/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/UpdateAPIServlet.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.asterix.api.http.servlet;
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import edu.uci.ics.asterix.aql.base.Statement;
+import edu.uci.ics.asterix.aql.base.Statement.Kind;
+
+public class UpdateAPIServlet extends RESTAPIServlet {
+ private static final long serialVersionUID = 1L;
+
+ protected String getQueryParameter(HttpServletRequest request) {
+ return request.getParameter("statements");
+ }
+
+ protected List<Statement.Kind> getAllowedStatements() {
+ Kind[] statementsArray = { Kind.DATAVERSE_DECL, Kind.DELETE, Kind.INSERT, Kind.UPDATE, Kind.DML_CMD_LIST,
+ Kind.LOAD, Kind.CONNECT_FEED, Kind.DISCONNECT_FEED, Kind.SET, Kind.COMPACT, Kind.EXTERNAL_DATASET_REFRESH };
+ return Arrays.asList(statementsArray);
+ }
+
+ protected String getErrorMessage() {
+ return "Invalid statement: Non-Update statement %s to the Update API.";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-app/src/main/java/org/apache/asterix/api/java/AsterixJavaClient.java
----------------------------------------------------------------------
diff --git a/asterix-app/src/main/java/org/apache/asterix/api/java/AsterixJavaClient.java b/asterix-app/src/main/java/org/apache/asterix/api/java/AsterixJavaClient.java
new file mode 100644
index 0000000..54804e7
--- /dev/null
+++ b/asterix-app/src/main/java/org/apache/asterix/api/java/AsterixJavaClient.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.asterix.api.java;
+
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.util.List;
+
+import edu.uci.ics.asterix.api.common.APIFramework;
+import edu.uci.ics.asterix.api.common.Job;
+import edu.uci.ics.asterix.api.common.SessionConfig;
+import edu.uci.ics.asterix.api.common.SessionConfig.OutputFormat;
+import edu.uci.ics.asterix.aql.base.Statement;
+import edu.uci.ics.asterix.aql.parser.AQLParser;
+import edu.uci.ics.asterix.aql.parser.ParseException;
+import edu.uci.ics.asterix.aql.translator.AqlTranslator;
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.metadata.MetadataManager;
+import edu.uci.ics.hyracks.api.client.IHyracksClientConnection;
+import edu.uci.ics.hyracks.api.job.JobSpecification;
+
+public class AsterixJavaClient {
+ private IHyracksClientConnection hcc;
+ private Reader queryText;
+ private PrintWriter writer;
+
+ private Job[] dmlJobs;
+ private JobSpecification queryJobSpec;
+
+ public AsterixJavaClient(IHyracksClientConnection hcc, Reader queryText, PrintWriter writer) {
+ this.hcc = hcc;
+ this.queryText = queryText;
+ this.writer = writer;
+ }
+
+ public AsterixJavaClient(IHyracksClientConnection hcc, Reader queryText) {
+ this(hcc, queryText, new PrintWriter(System.out, true));
+ }
+
+ public void compile() throws Exception {
+ compile(true, false, false, false, false, false, false);
+ }
+
+ public void compile(boolean optimize, boolean printRewrittenExpressions, boolean printLogicalPlan,
+ boolean printOptimizedPlan, boolean printPhysicalOpsOnly, boolean generateBinaryRuntime, boolean printJob)
+ throws Exception {
+ queryJobSpec = null;
+ dmlJobs = null;
+
+ if (queryText == null) {
+ return;
+ }
+ int ch;
+ StringBuilder builder = new StringBuilder();
+ while ((ch = queryText.read()) != -1) {
+ builder.append((char) ch);
+ }
+ AQLParser parser = new AQLParser(builder.toString());
+ List<Statement> aqlStatements;
+ try {
+ aqlStatements = parser.parse();
+ } catch (ParseException pe) {
+ throw new AsterixException(pe);
+ }
+ MetadataManager.INSTANCE.init();
+
+ SessionConfig conf = new SessionConfig(writer, OutputFormat.ADM, optimize, true, generateBinaryRuntime);
+ conf.setOOBData(false, printRewrittenExpressions, printLogicalPlan,
+ printOptimizedPlan, printJob);
+ if (printPhysicalOpsOnly) {
+ conf.set(SessionConfig.FORMAT_ONLY_PHYSICAL_OPS, true);
+ }
+
+ AqlTranslator aqlTranslator = new AqlTranslator(aqlStatements, conf);
+ aqlTranslator.compileAndExecute(hcc, null, AqlTranslator.ResultDelivery.SYNC);
+ writer.flush();
+ }
+
+ public void execute() throws Exception {
+ if (dmlJobs != null) {
+ APIFramework.executeJobArray(hcc, dmlJobs, writer);
+ }
+ if (queryJobSpec != null) {
+ APIFramework.executeJobArray(hcc, new JobSpecification[] { queryJobSpec }, writer);
+ }
+ }
+
+}