vxquery-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From prest...@apache.org
Subject [4/4] vxquery git commit: [VXQUERY-180] REST Server implementation
Date Fri, 25 Aug 2017 16:59:12 GMT
[VXQUERY-180] REST Server implementation

- Implemented REST API
- Altered CLI to use REST API
- Migrated XTests to use REST API

details:
- Implemented the REST Server to start through the cluster controller
  application.
- CLI now calls the REST API (remote if given, local one else) to
  execute queries.
- Migrated XTests to use the REST API to run queries related to tests


Project: http://git-wip-us.apache.org/repos/asf/vxquery/repo
Commit: http://git-wip-us.apache.org/repos/asf/vxquery/commit/f2e5fd90
Tree: http://git-wip-us.apache.org/repos/asf/vxquery/tree/f2e5fd90
Diff: http://git-wip-us.apache.org/repos/asf/vxquery/diff/f2e5fd90

Branch: refs/heads/master
Commit: f2e5fd90f5c9788d0cdc5e381e70e5428f5722e6
Parents: 4a38f67
Author: erandiganepola <erandiganepola@gmail.com>
Authored: Sun Jun 4 14:32:29 2017 +0530
Committer: Erandi Ganepola <erandiganepola@gmail.com>
Committed: Fri Aug 25 06:55:23 2017 +0530

----------------------------------------------------------------------
 pom.xml                                         |  15 +
 src/site/apt/user_query.apt                     |  35 +-
 vxquery-cli/pom.xml                             |  64 +--
 .../java/org/apache/vxquery/cli/VXQuery.java    | 576 +++++++++----------
 vxquery-cli/src/site/markdown/index.md          | 116 ++++
 vxquery-cli/src/site/site.xml                   |  57 +-
 .../exceptions/VXQueryRuntimeException.java     |  34 ++
 .../VXQueryServletRuntimeException.java         |  34 ++
 .../metadata/VXQueryMetadataProvider.java       |   1 -
 vxquery-rest/pom.xml                            |  56 ++
 .../apache/vxquery/app/VXQueryApplication.java  | 179 ++++++
 .../vxquery/app/util/LocalClusterUtil.java      | 187 ++++++
 .../org/apache/vxquery/app/util/RestUtils.java  | 200 +++++++
 .../java/org/apache/vxquery/rest/Constants.java |  71 +++
 .../org/apache/vxquery/rest/RestServer.java     |  84 +++
 .../vxquery/rest/request/QueryRequest.java      | 165 ++++++
 .../rest/request/QueryResultRequest.java        |  57 ++
 .../vxquery/rest/response/APIResponse.java      |  87 +++
 .../rest/response/AsyncQueryResponse.java       |  47 ++
 .../org/apache/vxquery/rest/response/Error.java | 101 ++++
 .../vxquery/rest/response/ErrorResponse.java    |  56 ++
 .../apache/vxquery/rest/response/Metrics.java   |  42 ++
 .../vxquery/rest/response/QueryResponse.java    |  88 +++
 .../rest/response/QueryResultResponse.java      |  49 ++
 .../rest/response/SyncQueryResponse.java        |  34 ++
 .../vxquery/rest/service/HyracksJobContext.java |  53 ++
 .../org/apache/vxquery/rest/service/State.java  |  30 +
 .../org/apache/vxquery/rest/service/Status.java |  51 ++
 .../vxquery/rest/service/VXQueryConfig.java     | 100 ++++
 .../vxquery/rest/service/VXQueryService.java    | 482 ++++++++++++++++
 .../vxquery/rest/servlet/QueryAPIServlet.java   | 139 +++++
 .../rest/servlet/QueryResultAPIServlet.java     |  67 +++
 .../vxquery/rest/servlet/RestAPIServlet.java    | 168 ++++++
 vxquery-rest/src/site/markdown/index.md         | 249 ++++++++
 vxquery-rest/src/site/markdown/specification.md | 102 ++++
 vxquery-rest/src/site/site.xml                  |  53 ++
 .../vxquery/rest/AbstractRestServerTest.java    | 225 ++++++++
 .../apache/vxquery/rest/ErrorResponseTest.java  | 200 +++++++
 .../vxquery/rest/SuccessAsyncResponseTest.java  | 289 ++++++++++
 .../vxquery/rest/SuccessSyncResponseTest.java   | 215 +++++++
 .../src/test/resources/vxquery.properties       |  30 +
 vxquery-server/pom.xml                          |  10 +-
 vxquery-xtest/pom.xml                           |   6 +
 .../apache/vxquery/xtest/TestClusterUtil.java   |  81 +--
 .../org/apache/vxquery/xtest/TestRunner.java    | 239 +++-----
 .../java/org/apache/vxquery/xtest/XTest.java    |  13 +-
 .../vxquery/xtest/AbstractXQueryTest.java       |   9 +-
 .../GhcndRecords/Partition-2/q03_records-1.txt  |   3 +
 .../GhcndRecords/Partition-2/q03_records-2.txt  |   3 +
 .../GhcndRecords/Partition-2/q03_records-3.txt  |   3 +
 .../GhcndRecords/Partition-2/q03_records-4.txt  |   3 +
 .../GhcndRecords/Partition-2/q03_records-5.txt  |   3 +
 .../GhcndRecords/Partition-4/q03_records-1.txt  |   3 +
 .../GhcndRecords/Partition-4/q03_records-2.txt  |   3 +
 .../GhcndRecords/Partition-4/q03_records-3.txt  |   3 +
 .../GhcndRecords/Partition-4/q03_records-4.txt  |   3 +
 .../GhcndRecords/Partition-4/q03_records-5.txt  |   3 +
 .../Json/Parser/Partition-1/q15_parser-1.txt    |   3 +
 .../Json/Parser/Partition-1/q15_parser-2.txt    |   3 +
 .../Json/Parser/Partition-1/q15_parser-3.txt    |   3 +
 .../Json/Parser/Partition-1/q15_parser-4.txt    |   3 +
 .../Json/Parser/Partition-1/q15_parser-5.txt    |   3 +
 .../Json/Parser/Partition-2/q15_parser-1.txt    |   3 +
 .../Json/Parser/Partition-2/q15_parser-2.txt    |   3 +
 .../Json/Parser/Partition-2/q15_parser-3.txt    |   3 +
 .../Json/Parser/Partition-2/q15_parser-4.txt    |   3 +
 .../Json/Parser/Partition-2/q15_parser-5.txt    |   3 +
 .../Json/Parser/Partition-4/q15_parser-1.txt    |   3 +
 .../Json/Parser/Partition-4/q15_parser-2.txt    |   3 +
 .../Json/Parser/Partition-4/q15_parser-3.txt    |   3 +
 .../Json/Parser/Partition-4/q15_parser-4.txt    |   3 +
 .../Json/Parser/Partition-4/q15_parser-5.txt    |   3 +
 .../test/resources/cat/JsonParserQueries.xml    |  19 +-
 73 files changed, 4714 insertions(+), 626 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/vxquery/blob/f2e5fd90/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 5f03a49..7e298c5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -251,6 +251,18 @@
 
             <dependency>
                 <groupId>org.apache.hyracks</groupId>
+                <artifactId>hyracks-http</artifactId>
+                <version>${hyracks.fullstack.version}</version>
+            </dependency>
+
+            <dependency>
+                <groupId>io.netty</groupId>
+                <artifactId>netty-all</artifactId>
+                <version>4.1.6.Final</version>
+            </dependency>
+            
+            <dependency>
+                <groupId>org.apache.hyracks</groupId>
                 <artifactId>algebricks-compiler</artifactId>
                 <version>${hyracks.version}</version>
             </dependency>
@@ -670,6 +682,8 @@
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <hyracks.version>0.2.17-incubating</hyracks.version>
+        <hyracks.fullstack.version>0.3.1</hyracks.fullstack.version>
         <hyracks.version>0.3.0</hyracks.version>
         <apache-rat-plugin.version>0.11</apache-rat-plugin.version>
     </properties>
@@ -680,5 +694,6 @@
         <module>vxquery-cli</module>
         <module>vxquery-xtest</module>
         <module>vxquery-benchmark</module>
+        <module>vxquery-rest</module>
     </modules>
 </project>

http://git-wip-us.apache.org/repos/asf/vxquery/blob/f2e5fd90/src/site/apt/user_query.apt
----------------------------------------------------------------------
diff --git a/src/site/apt/user_query.apt b/src/site/apt/user_query.apt
index c5132c3..f4d0dd5 100644
--- a/src/site/apt/user_query.apt
+++ b/src/site/apt/user_query.apt
@@ -35,21 +35,26 @@ vxq "path-to"\test.xq
   Command line options for all systems.
 
 ----------------------------------------
--O N                       : Optimization Level. Default: Full Optimization
--available-processors N    : Number of available processors. (default java's available processors)
--client-net-ip-address VAL : IP Address of the ClusterController
--client-net-port N         : Port of the ClusterController (default 1098)
--compileonly               : Compile the query and stop
--frame-size N              : Frame size in bytes. (default 65536)
--local-node-controllers N  : Number of local node controllers (default 1)
--repeatexec N              : Number of times to repeat execution
--showast                   : Show abstract syntax tree
--showoet                   : Show optimized expression tree
--showquery                 : Show query string
--showrp                    : Show Runtime plan
--showtet                   : Show translated expression tree
--timing                    : Produce timing information
--hdfs-conf VAL             : The folder containing the HDFS configuration files
+ -O N                      : Optimization Level. (default: Full Optimization)
+ -available-processors N   : Number of available processors. (default: java's available processors)
+ -buffer-size N            : Disk read buffer size in bytes.
+ -compileonly              : Compile the query and stop.
+ -frame-size N             : Frame size in bytes. (default: 65,536)
+ -hdfs-conf VAL            : Directory path to Hadoop configuration files
+ -join-hash-size N         : Join hash size in bytes. (default: 67,108,864)
+ -local-node-controllers N : Number of local node controllers. (default: 1)
+ -maximum-data-size N      : Maximum possible data size in bytes. (default: 150,323,855,000)
+ -repeatexec N             : Number of times to repeat execution.
+ -rest-ip-address VAL      : IP Address of the REST Server.
+ -rest-port N              : Port of REST Server.
+ -result-file VAL          : File path to save the query result.
+ -showast                  : Show abstract syntax tree.
+ -showoet                  : Show optimized expression tree.
+ -showquery                : Show query string.
+ -showrp                   : Show Runtime plan.
+ -showtet                  : Show translated expression tree.
+ -timing                   : Produce timing information.
+ -timing-ignore-queries N  : Ignore the first X number of quereies.
 ----------------------------------------
 
 * Java Options

http://git-wip-us.apache.org/repos/asf/vxquery/blob/f2e5fd90/vxquery-cli/pom.xml
----------------------------------------------------------------------
diff --git a/vxquery-cli/pom.xml b/vxquery-cli/pom.xml
index 52c32ad..e7ad16a 100644
--- a/vxquery-cli/pom.xml
+++ b/vxquery-cli/pom.xml
@@ -14,7 +14,8 @@
   See the License for the specific language governing permissions and
   limitations under the License.
 -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
     <modelVersion>4.0.0</modelVersion>
 
     <parent>
@@ -61,12 +62,6 @@
                     </execution>
                 </executions>
             </plugin>
-      <!--
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-site-plugin</artifactId>
-      </plugin>
-      -->
             <plugin>
                 <artifactId>maven-antrun-plugin</artifactId>
                 <executions>
@@ -82,64 +77,11 @@
     <dependencies>
         <dependency>
             <groupId>org.apache.vxquery</groupId>
-            <artifactId>apache-vxquery-core</artifactId>
+            <artifactId>apache-vxquery-rest</artifactId>
             <version>0.7-SNAPSHOT</version>
-            <scope>compile</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.hyracks</groupId>
-            <artifactId>hyracks-api</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.hyracks</groupId>
-            <artifactId>hyracks-client</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.hyracks</groupId>
-            <artifactId>hyracks-control-cc</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.hyracks</groupId>
-            <artifactId>hyracks-control-nc</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.hyracks</groupId>
-            <artifactId>algebricks-common</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.hyracks</groupId>
-            <artifactId>algebricks-core</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.hyracks</groupId>
-            <artifactId>hyracks-control-common</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.hyracks</groupId>
-            <artifactId>hyracks-dataflow-std</artifactId>
-        </dependency>
-
-        <dependency>
-                <groupId>org.apache.hyracks</groupId>
-                <artifactId>hyracks-hdfs-core</artifactId>
-        </dependency>
-
-        <dependency>
-                <groupId>org.apache.hyracks</groupId>
-                <artifactId>hyracks-hdfs-2.x</artifactId>
         </dependency>
     </dependencies>
 
-
-
     <reporting>
         <plugins>
             <plugin>

http://git-wip-us.apache.org/repos/asf/vxquery/blob/f2e5fd90/vxquery-cli/src/main/java/org/apache/vxquery/cli/VXQuery.java
----------------------------------------------------------------------
diff --git a/vxquery-cli/src/main/java/org/apache/vxquery/cli/VXQuery.java b/vxquery-cli/src/main/java/org/apache/vxquery/cli/VXQuery.java
index 25ff9c4..23d5eaa 100644
--- a/vxquery-cli/src/main/java/org/apache/vxquery/cli/VXQuery.java
+++ b/vxquery-cli/src/main/java/org/apache/vxquery/cli/VXQuery.java
@@ -14,73 +14,57 @@
  */
 package org.apache.vxquery.cli;
 
-import java.io.ByteArrayOutputStream;
+import static org.apache.vxquery.rest.Constants.HttpHeaderValues.CONTENT_TYPE_JSON;
+
 import java.io.File;
-import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.io.StringReader;
-import java.net.InetAddress;
-import java.nio.file.Files;
+import java.io.PrintStream;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Date;
-import java.util.EnumSet;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
+import java.util.logging.LogManager;
+
+import javax.xml.bind.JAXBException;
 
 import org.apache.commons.io.FileUtils;
-import org.apache.hyracks.api.client.HyracksConnection;
-import org.apache.hyracks.api.client.IHyracksClientConnection;
-import org.apache.hyracks.api.client.NodeControllerInfo;
-import org.apache.hyracks.api.comm.IFrame;
-import org.apache.hyracks.api.comm.IFrameTupleAccessor;
-import org.apache.hyracks.api.comm.VSizeFrame;
-import org.apache.hyracks.api.dataset.IHyracksDataset;
-import org.apache.hyracks.api.dataset.IHyracksDatasetReader;
-import org.apache.hyracks.api.dataset.ResultSetId;
-import org.apache.hyracks.api.job.JobFlag;
-import org.apache.hyracks.api.job.JobId;
-import org.apache.hyracks.api.job.JobSpecification;
-import org.apache.hyracks.client.dataset.HyracksDataset;
-import org.apache.hyracks.control.cc.ClusterControllerService;
-import org.apache.hyracks.control.common.controllers.CCConfig;
-import org.apache.hyracks.control.common.controllers.NCConfig;
-import org.apache.hyracks.control.nc.NodeControllerService;
-import org.apache.hyracks.control.nc.resources.memory.FrameManager;
-import org.apache.hyracks.dataflow.common.comm.io.ResultFrameTupleAccessor;
-import org.apache.vxquery.compiler.CompilerControlBlock;
-import org.apache.vxquery.compiler.algebricks.VXQueryGlobalDataFactory;
-import org.apache.vxquery.context.DynamicContext;
-import org.apache.vxquery.context.DynamicContextImpl;
-import org.apache.vxquery.context.RootStaticContextImpl;
-import org.apache.vxquery.context.StaticContextImpl;
-import org.apache.vxquery.exceptions.SystemException;
-import org.apache.vxquery.result.ResultUtils;
-import org.apache.vxquery.xmlquery.query.Module;
-import org.apache.vxquery.xmlquery.query.VXQueryCompilationListener;
-import org.apache.vxquery.xmlquery.query.XMLQueryCompiler;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpHeaders;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.utils.HttpClientUtils;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.vxquery.app.util.LocalClusterUtil;
+import org.apache.vxquery.app.util.RestUtils;
+import org.apache.vxquery.rest.request.QueryRequest;
+import org.apache.vxquery.rest.response.AsyncQueryResponse;
+import org.apache.vxquery.rest.response.Error;
+import org.apache.vxquery.rest.response.ErrorResponse;
+import org.apache.vxquery.rest.response.Metrics;
+import org.apache.vxquery.rest.response.SyncQueryResponse;
+import org.apache.vxquery.rest.service.VXQueryConfig;
 import org.kohsuke.args4j.Argument;
 import org.kohsuke.args4j.CmdLineParser;
 import org.kohsuke.args4j.Option;
 
+/**
+ * CLI for VXQuery. This class is using the REST API to execute statements given by the user.
+ *
+ * @author Erandi Ganepola
+ */
 public class VXQuery {
+
     private final CmdLineOptions opts;
-    private final CmdLineOptions indexOpts;
-
-    private ClusterControllerService cc;
-    private NodeControllerService[] ncs;
-    private IHyracksClientConnection hcc;
-    private IHyracksDataset hds;
-    private List<String> collectionList;
-    private ResultSetId resultSetId;
-    private static List<String> timingMessages = new ArrayList<>();
-    private static long sumTiming;
-    private static long sumSquaredTiming;
-    private static long minTiming = Long.MAX_VALUE;
-    private static long maxTiming = Long.MIN_VALUE;
+
+    private static LocalClusterUtil localClusterUtil;
+    private String restIpAddress;
+    private int restPort;
+
+    private static List<Metrics> metricsList = new ArrayList<>();
+    private int executionIteration;
 
     /**
      * Constructor to use command line options passed.
@@ -90,26 +74,17 @@ public class VXQuery {
      */
     public VXQuery(CmdLineOptions opts) {
         this.opts = opts;
-        // The index query returns only the result, without any other information.
-        this.indexOpts = opts;
-        indexOpts.showAST = false;
-        indexOpts.showOET = false;
-        indexOpts.showQuery = false;
-        indexOpts.showRP = false;
-        indexOpts.showTET = false;
-        indexOpts.timing = false;
-        indexOpts.compileOnly = false;
-        this.collectionList = new ArrayList<String>();
     }
 
     /**
      * Main method to get command line options and execute query process.
      *
      * @param args
-     * @throws Exception
+     *            command line arguments
      */
-    public static void main(String[] args) throws Exception {
-        Date start = new Date();
+    public static void main(String[] args) {
+        LogManager.getLogManager().reset();
+
         final CmdLineOptions opts = new CmdLineOptions();
         CmdLineParser parser = new CmdLineParser(opts);
 
@@ -120,243 +95,249 @@ public class VXQuery {
             parser.printUsage(System.err);
             return;
         }
-        if (opts.arguments.isEmpty()) {
+
+        if (opts.xqFiles.isEmpty()) {
             parser.printUsage(System.err);
             return;
         }
-        VXQuery vxq = new VXQuery(opts);
-        vxq.execute();
-        // if -timing argument passed, show the starting and ending times
-        if (opts.timing) {
-            Date end = new Date();
-            timingMessage("Execution time: " + (end.getTime() - start.getTime()) + " ms");
-            if (opts.repeatExec > opts.timingIgnoreQueries) {
-                Double mean = (double) (sumTiming) / (opts.repeatExec - opts.timingIgnoreQueries);
-                double sd = Math.sqrt(sumSquaredTiming / (opts.repeatExec - opts.timingIgnoreQueries) - mean * mean);
-                timingMessage("Average execution time: " + mean + " ms");
-                timingMessage("Standard deviation: " + String.format("%.4f", sd));
-                timingMessage("Coefficient of variation: " + String.format("%.4f", sd / mean));
-                timingMessage("Minimum execution time: " + minTiming + " ms");
-                timingMessage("Maximum execution time: " + maxTiming + " ms");
-            }
-            System.out.println("Timing Summary:");
-            for (String time : timingMessages) {
-                System.out.println("  " + time);
-            }
-        }
 
+        VXQuery vxq = new VXQuery(opts);
+        vxq.execute(opts.xqFiles);
     }
 
-    /**
-     * Creates a new Hyracks connection with: the client IP address and port provided, if IP address is provided in command line. Otherwise create a new virtual
-     * cluster with Hyracks nodes. Queries passed are run either way. After running queries, if a virtual cluster has been created, it is shut down.
-     *
-     * @throws Exception
-     */
-    private void execute() throws Exception {
-        System.setProperty("vxquery.buffer_size", Integer.toString(opts.bufferSize));
+    private void execute(List<String> xqFiles) {
+        if (opts.restIpAddress == null) {
+            System.out.println("No REST Ip address given. Creating a local hyracks cluster");
 
-        if (opts.clientNetIpAddress != null) {
-            hcc = new HyracksConnection(opts.clientNetIpAddress, opts.clientNetPort);
-            runQueries();
-        } else {
-            if (!opts.compileOnly) {
-                startLocalHyracks();
+            VXQueryConfig vxqConfig = new VXQueryConfig();
+            vxqConfig.setAvailableProcessors(opts.availableProcessors);
+            vxqConfig.setFrameSize(opts.frameSize);
+            vxqConfig.setHdfsConf(opts.hdfsConf);
+            vxqConfig.setJoinHashSize(opts.joinHashSize);
+            vxqConfig.setMaximumDataSize(opts.maximumDataSize);
+
+            localClusterUtil = new LocalClusterUtil();
+            try {
+                localClusterUtil.init(vxqConfig);
+                restIpAddress = localClusterUtil.getIpAddress();
+                restPort = localClusterUtil.getRestPort();
+            } catch (Exception e) {
+                System.err.println("Unable to start local hyracks cluster due to: " + e.getMessage());
+                e.printStackTrace();
+                return;
             }
+        } else {
+            restIpAddress = opts.restIpAddress;
+            restPort = opts.restPort;
+        }
+
+        System.out.println("Running queries given in: " + Arrays.toString(xqFiles.toArray()));
+        runQueries(xqFiles);
+
+        if (localClusterUtil != null) {
             try {
-                runQueries();
-            } finally {
-                if (!opts.compileOnly) {
-                    stopLocalHyracks();
-                }
+                localClusterUtil.deinit();
+            } catch (Exception e) {
+                System.err.println("Error occurred when stopping local hyracks: " + e.getMessage());
             }
         }
     }
 
-    /**
-     * Reads the contents of the files passed in the list of arguments to a string. If -showquery argument is passed, output the query as string. Run the query
-     * for the string.
-     *
-     * @throws IOException
-     * @throws SystemException
-     * @throws Exception
-     */
+    public void runQueries(List<String> xqFiles) {
+        for (String xqFile : xqFiles) {
+            String query;
+            try {
+                query = slurp(xqFile);
+            } catch (IOException e) {
+                System.err.println(String.format("Error occurred when reading XQuery file %s with message: %s", xqFile,
+                        e.getMessage()));
+                continue;
+            }
 
-    private void runQueries() throws Exception {
-        List<String> queries = opts.arguments;
-        // Run the showIndexes query before executing any target query, to store the index metadata
-        List<String> queriesIndex = new ArrayList<String>();
-        queriesIndex.add("vxquery-xtest/src/test/resources/Queries/XQuery/Indexing/Partition-1/showIndexes.xq");
-        OutputStream resultStream = new ByteArrayOutputStream();
-        executeQuery(queriesIndex.get(0), 1, resultStream, indexOpts);
-        ByteArrayOutputStream bos = (ByteArrayOutputStream) resultStream;
-        String result = new String(bos.toByteArray());
-        String[] collections = result.split("\n");
-        this.collectionList = Arrays.asList(collections);
-        executeQueries(queries);
-    }
+            System.out.println();
+            System.out.println("====================================================");
+            System.out.println("\tQuery - '" + xqFile + "'");
+            System.out.println("====================================================");
 
-    public void executeQueries(List<String> queries) throws Exception {
-        for (String query : queries) {
-            OutputStream resultStream = System.out;
-            if (opts.resultFile != null) {
-                resultStream = new FileOutputStream(new File(opts.resultFile));
+            QueryRequest request = createQueryRequest(opts, query);
+            metricsList.clear();
+
+            for (int i = 0; i < opts.repeatExec; i++) {
+                System.out.println("**** Repetition : " + (i + 1) + " ****");
+
+                executionIteration = i;
+                sendQueryRequest(xqFile, request, this);
+            }
+
+            if (opts.repeatExec > 1) {
+                showTimingSummary();
             }
-            executeQuery(query, opts.repeatExec, resultStream, opts);
         }
     }
 
-    public void executeQuery(String query, int repeatedExecution, OutputStream resultStream, CmdLineOptions options)
-            throws Exception {
-        PrintWriter writer = new PrintWriter(resultStream, true);
-        String qStr = slurp(query);
-        if (opts.showQuery) {
-            writer.println(qStr);
+    private void onSuccess(String xqFile, QueryRequest request, SyncQueryResponse response) {
+        if (response == null) {
+            System.err.println(String.format("Unable to execute query %s", request.getStatement()));
+            return;
         }
-        VXQueryCompilationListener listener = new VXQueryCompilationListener(opts.showAST, opts.showTET, opts.showOET,
-                opts.showRP);
 
-        Date start = opts.timing ? new Date() : null;
+        if (opts.showQuery) {
+            printField("Query", response.getStatement());
+        }
 
-        Map<String, NodeControllerInfo> nodeControllerInfos = null;
-        if (hcc != null) {
-            nodeControllerInfos = hcc.getNodeControllerInfos();
+        if (request.isShowMetrics()) {
+            String metrics = String.format("Compile Time:\t%d\nElapsed Time:\t%d",
+                    response.getMetrics().getCompileTime(), response.getMetrics().getElapsedTime());
+            printField("Metrics", metrics);
         }
-        XMLQueryCompiler compiler = new XMLQueryCompiler(listener, nodeControllerInfos, opts.frameSize,
-                opts.availableProcessors, opts.joinHashSize, opts.maximumDataSize, opts.hdfsConf);
-        resultSetId = createResultSetId();
-        CompilerControlBlock ccb = new CompilerControlBlock(new StaticContextImpl(RootStaticContextImpl.INSTANCE),
-                resultSetId, null);
-        compiler.compile(query, new StringReader(qStr), ccb, opts.optimizationLevel, this.collectionList);
-        // if -timing argument passed, show the starting and ending times
-        Date end = opts.timing ? new Date() : null;
-        if (opts.timing) {
-            timingMessage("Compile time: " + (end.getTime() - start.getTime()) + " ms");
+
+        if (request.isShowAbstractSyntaxTree()) {
+            printField("Abstract Syntax Tree", response.getAbstractSyntaxTree());
         }
-        if (opts.compileOnly) {
-            return;
+
+        if (request.isShowTranslatedExpressionTree()) {
+            printField("Translated Expression Tree", response.getTranslatedExpressionTree());
         }
 
-        Module module = compiler.getModule();
-        JobSpecification js = module.getHyracksJobSpecification();
-
-        DynamicContext dCtx = new DynamicContextImpl(module.getModuleContext());
-        js.setGlobalJobDataFactory(new VXQueryGlobalDataFactory(dCtx.createFactory()));
-
-        // Repeat execution for number of times provided in -repeatexec argument
-        for (int i = 0; i < repeatedExecution; ++i) {
-            start = opts.timing ? new Date() : null;
-            runJob(js, writer);
-            // if -timing argument passed, show the starting and ending times
-            if (opts.timing) {
-                end = new Date();
-                long currentRun = end.getTime() - start.getTime();
-                if ((i + 1) > opts.timingIgnoreQueries) {
-                    sumTiming += currentRun;
-                    sumSquaredTiming += currentRun * currentRun;
-                    if (currentRun < minTiming) {
-                        minTiming = currentRun;
-                    }
-                    if (maxTiming < currentRun) {
-                        maxTiming = currentRun;
-                    }
-                }
-                timingMessage("Job (" + (i + 1) + ") execution time: " + currentRun + " ms");
-            }
+        if (request.isShowOptimizedExpressionTree()) {
+            printField("Optimized Expression Tree", response.getOptimizedExpressionTree());
         }
-    }
 
-    /**
-     * Creates a Hyracks dataset, if not already existing with the job frame size, and 1 reader. Allocates a new buffer of size specified in the frame of Hyracks
-     * node. Creates new dataset reader with the current job ID and result set ID. Outputs the string in buffer for each frame.
-     *
-     * @param spec
-     *            JobSpecification object, containing frame size. Current specified job.
-     * @param writer
-     *            Writer for output of job.
-     * @throws Exception
-     */
-    private void runJob(JobSpecification spec, PrintWriter writer) throws Exception {
-        int nReaders = 1;
-        if (hds == null) {
-            hds = new HyracksDataset(hcc, spec.getFrameSize(), nReaders);
+        if (request.isShowRuntimePlan()) {
+            printField("Runtime Plan", response.getRuntimePlan());
         }
 
-        JobId jobId = hcc.startJob(spec, EnumSet.of(JobFlag.PROFILE_RUNTIME));
+        printField("Results", response.getResults());
 
-        FrameManager resultDisplayFrameMgr = new FrameManager(spec.getFrameSize());
-        IFrame frame = new VSizeFrame(resultDisplayFrameMgr);
-        IHyracksDatasetReader reader = hds.createReader(jobId, resultSetId);
-        IFrameTupleAccessor frameTupleAccessor = new ResultFrameTupleAccessor();
+        if (executionIteration >= opts.timingIgnoreQueries) {
+            metricsList.add(response.getMetrics());
+        }
+    }
 
-        while (reader.read(frame) > 0) {
-            writer.print(ResultUtils.getStringFromBuffer(frame.getBuffer(), frameTupleAccessor));
-            writer.flush();
-            frame.getBuffer().clear();
+    private void onFailure(String xqFile, ErrorResponse response) {
+        if (response == null) {
+            System.err.println(String.format("Unable to execute query in %s", xqFile));
+            return;
         }
 
-        hcc.waitForCompletion(jobId);
-    }
+        System.err.println();
+        System.err.println("------------------------ Errors ---------------------");
 
-    /**
-     * Create a unique result set id to get the correct query back from the cluster.
-     *
-     * @return Result Set id generated with current system time.
-     */
-    protected ResultSetId createResultSetId() {
-        return new ResultSetId(System.nanoTime());
+        Error error = response.getError();
+        String errorMsg = String.format("Code:\t %d\nMessage:\t %s", error.getCode(), error.getMessage());
+        printField(System.err, String.format("Errors for '%s'", xqFile), errorMsg);
     }
 
     /**
-     * Start local virtual cluster with cluster controller node and node controller nodes. IP address provided for node controller is localhost. Unassigned ports
-     * 39000 and 39001 are used for client and cluster port respectively. Creates a new Hyracks connection with the IP address and client ports.
+     * Submits a query to be executed by the REST API. Will call {@link #onFailure(String, ErrorResponse)} if any error
+     * occurs when submitting the query. Else will call {@link #onSuccess(String, QueryRequest, SyncQueryResponse)} with
+     * the {@link AsyncQueryResponse}
      *
-     * @throws Exception
+     * @param xqFile
+     *            .xq file with the query to be executed
+     * @param request
+     *            {@link QueryRequest} instance to be submitted to REST API
+     * @param cli
+     *            cli class instance
      */
-    public void startLocalHyracks() throws Exception {
-        String localAddress = InetAddress.getLocalHost().getHostAddress();
-        CCConfig ccConfig = new CCConfig();
-        ccConfig.clientNetIpAddress = localAddress;
-        ccConfig.clientNetPort = 39000;
-        ccConfig.clusterNetIpAddress = localAddress;
-        ccConfig.clusterNetPort = 39001;
-        ccConfig.httpPort = 39002;
-        ccConfig.profileDumpPeriod = 10000;
-        cc = new ClusterControllerService(ccConfig);
-        cc.start();
-
-        ncs = new NodeControllerService[opts.localNodeControllers];
-        for (int i = 0; i < ncs.length; i++) {
-            NCConfig ncConfig = new NCConfig();
-            ncConfig.ccHost = "localhost";
-            ncConfig.ccPort = 39001;
-            ncConfig.clusterNetIPAddress = localAddress;
-            ncConfig.dataIPAddress = localAddress;
-            ncConfig.resultIPAddress = localAddress;
-            ncConfig.nodeId = "nc" + (i + 1);
-            //TODO: enable index folder as a cli option for on-the-fly indexing queries
-            ncConfig.ioDevices = Files.createTempDirectory(ncConfig.nodeId).toString();
-            ncs[i] = new NodeControllerService(ncConfig);
-            ncs[i].start();
+    private static void sendQueryRequest(String xqFile, QueryRequest request, VXQuery cli) {
+        URI uri = null;
+        try {
+            uri = RestUtils.buildQueryURI(request, cli.restIpAddress, cli.restPort);
+        } catch (URISyntaxException e) {
+            System.err.println(
+                    String.format("Unable to build URI to call REST API for query: %s", request.getStatement()));
+            cli.onFailure(xqFile, null);
         }
 
-        hcc = new HyracksConnection(ccConfig.clientNetIpAddress, ccConfig.clientNetPort);
+        CloseableHttpClient httpClient = HttpClients.custom().build();
+        try {
+            HttpGet httpGet = new HttpGet(uri);
+            httpGet.setHeader(HttpHeaders.ACCEPT, CONTENT_TYPE_JSON);
+
+            try (CloseableHttpResponse httpResponse = httpClient.execute(httpGet)) {
+                HttpEntity entity = httpResponse.getEntity();
+
+                String response = RestUtils.readEntity(entity);
+                if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
+                    cli.onSuccess(xqFile, request,
+                            RestUtils.mapEntity(response, SyncQueryResponse.class, CONTENT_TYPE_JSON));
+                } else {
+                    cli.onFailure(xqFile, RestUtils.mapEntity(response, ErrorResponse.class, CONTENT_TYPE_JSON));
+                }
+            } catch (IOException e) {
+                System.err.println("Error occurred when reading entity: " + e.getMessage());
+                cli.onFailure(xqFile, null);
+            } catch (JAXBException e) {
+                System.err.println("Error occurred when mapping query response: " + e.getMessage());
+                cli.onFailure(xqFile, null);
+            }
+        } finally {
+            HttpClientUtils.closeQuietly(httpClient);
+        }
     }
 
     /**
-     * Shuts down the virtual cluster, along with all nodes and node execution, network and queue managers.
-     *
-     * @throws Exception
+     * Once the query in a given .xq file has been executed (with repeated executions as well), this method calculates
+     * mean, standard deviation, minimum and maximum execution times.
      */
-    public void stopLocalHyracks() throws Exception {
-        for (int i = 0; i < ncs.length; i++) {
-            ncs[i].stop();
+    private void showTimingSummary() {
+        double sumTime = 0;
+        double sumSquaredTime = 0;
+        long minTime = Long.MAX_VALUE;
+        long maxTime = Long.MIN_VALUE;
+
+        for (int i = 0; i < metricsList.size(); i++) {
+            Metrics metrics = metricsList.get(i);
+            long totalTime = metrics.getCompileTime() + metrics.getElapsedTime();
+
+            sumTime += totalTime;
+            sumSquaredTime += totalTime * totalTime;
+
+            if (totalTime < minTime) {
+                minTime = totalTime;
+            }
+
+            if (totalTime > maxTime) {
+                maxTime = totalTime;
+            }
         }
-        cc.stop();
+
+        double mean = sumTime / (opts.repeatExec - opts.timingIgnoreQueries);
+        double sd = Math.sqrt(sumSquaredTime / (opts.repeatExec - opts.timingIgnoreQueries) - mean * mean);
+
+        System.out.println();
+        System.out.println("\t**** Timing Summary ****");
+        System.out.println("----------------------------------------------------");
+        System.out.println(String.format("Repetitions:\t%d, Timing Ignored Iterations:\t%d", opts.repeatExec,
+                opts.timingIgnoreQueries));
+        System.out.println("Average execution time:\t" + mean + " ms");
+        System.out.println("Standard deviation:\t" + String.format("%.4f", sd));
+        System.out.println("Coefficient of variation:\t" + String.format("%.4f", sd / mean));
+        System.out.println("Minimum execution time:\t" + minTime + " ms");
+        System.out.println("Maximum execution time:\t" + maxTime + " ms");
+        System.out.println();
+    }
+
+    private static QueryRequest createQueryRequest(CmdLineOptions opts, String query) {
+        QueryRequest request = new QueryRequest(query);
+        request.setCompileOnly(opts.compileOnly);
+        request.setOptimization(opts.optimizationLevel);
+        request.setFrameSize(opts.frameSize);
+        request.setRepeatExecutions(opts.repeatExec);
+        request.setShowMetrics(opts.timing);
+        request.setShowAbstractSyntaxTree(opts.showAST);
+        request.setShowTranslatedExpressionTree(opts.showTET);
+        request.setShowOptimizedExpressionTree(opts.showOET);
+        request.setShowRuntimePlan(opts.showRP);
+        request.setAsync(false);
+
+        return request;
     }
 
     /**
-     * Reads the contents of file given in query into a String. The file is always closed. For XML files UTF-8 encoding is used.
+     * Reads the contents of file given in query into a String. The file is always closed. For XML files UTF-8 encoding
+     * is used.
      *
      * @param query
      *            The query with filename to be processed
@@ -367,46 +348,49 @@ public class VXQuery {
         return FileUtils.readFileToString(new File(query), "UTF-8");
     }
 
-    /**
-     * Save and print out the timing message.
-     *
-     * @param message
-     */
-    private static void timingMessage(String message) {
-        System.out.println(message);
-        timingMessages.add(message);
+    private static void printField(PrintStream out, String field, String value) {
+        out.println();
+        field = field + ":";
+        out.print(field);
+
+        String[] lines = value.split("\n");
+        for (int i = 0; i < lines.length; i++) {
+            int margin = 4;
+            if (i != 0) {
+                margin += field.length();
+            }
+            System.out.print(String.format("%1$" + margin + "s%2$s\n", "", lines[i]));
+        }
+    }
+
+    private static void printField(String field, String value) {
+        printField(System.out, field, value);
     }
 
     /**
      * Helper class with fields and methods to handle all command line options
      */
     private static class CmdLineOptions {
-        @Option(name = "-available-processors", usage = "Number of available processors. (default: java's available processors)")
-        private int availableProcessors = -1;
+        @Option(name = "-rest-ip-address", usage = "IP Address of the REST Server")
+        private String restIpAddress = null;
 
-        @Option(name = "-client-net-ip-address", usage = "IP Address of the ClusterController.")
-        private String clientNetIpAddress = null;
+        @Option(name = "-rest-port", usage = "Port of REST Server")
+        private int restPort = 8085;
 
-        @Option(name = "-client-net-port", usage = "Port of the ClusterController. (default: 1098)")
-        private int clientNetPort = 1098;
+        @Option(name = "-compileonly", usage = "Compile the query and stop.")
+        private boolean compileOnly;
 
-        @Option(name = "-local-node-controllers", usage = "Number of local node controllers. (default: 1)")
-        private int localNodeControllers = 1;
+        @Option(name = "-O", usage = "Optimization Level. (default: Full Optimization)")
+        private int optimizationLevel = Integer.MAX_VALUE;
 
         @Option(name = "-frame-size", usage = "Frame size in bytes. (default: 65,536)")
         private int frameSize = 65536;
 
-        @Option(name = "-join-hash-size", usage = "Join hash size in bytes. (default: 67,108,864)")
-        private long joinHashSize = -1;
-
-        @Option(name = "-maximum-data-size", usage = "Maximum possible data size in bytes. (default: 150,323,855,000)")
-        private long maximumDataSize = -1;
-
-        @Option(name = "-buffer-size", usage = "Disk read buffer size in bytes.")
-        private int bufferSize = -1;
+        @Option(name = "-repeatexec", usage = "Number of times to repeat execution.")
+        private int repeatExec = 1;
 
-        @Option(name = "-O", usage = "Optimization Level. (default: Full Optimization)")
-        private int optimizationLevel = Integer.MAX_VALUE;
+        @Option(name = "-timing", usage = "Produce timing information.")
+        private boolean timing;
 
         @Option(name = "-showquery", usage = "Show query string.")
         private boolean showQuery;
@@ -423,29 +407,33 @@ public class VXQuery {
         @Option(name = "-showrp", usage = "Show Runtime plan.")
         private boolean showRP;
 
-        @Option(name = "-compileonly", usage = "Compile the query and stop.")
-        private boolean compileOnly;
+        // Optional (Not supported by REST API) parameters. Only used for creating a
+        // local hyracks cluster
+        @Option(name = "-join-hash-size", usage = "Join hash size in bytes. (default: 67,108,864)")
+        private long joinHashSize = -1;
 
-        @Option(name = "-repeatexec", usage = "Number of times to repeat execution.")
-        private int repeatExec = 1;
+        @Option(name = "-maximum-data-size", usage = "Maximum possible data size in bytes. (default: 150,323,855,000)")
+        private long maximumDataSize = -1;
+
+        @Option(name = "-buffer-size", usage = "Disk read buffer size in bytes.")
+        private int bufferSize = -1;
 
         @Option(name = "-result-file", usage = "File path to save the query result.")
         private String resultFile = null;
 
-        @Option(name = "-timing", usage = "Produce timing information.")
-        private boolean timing;
-
         @Option(name = "-timing-ignore-queries", usage = "Ignore the first X number of quereies.")
-        private int timingIgnoreQueries = 2;
-
-        @Option(name = "-x", usage = "Bind an external variable")
-        private Map<String, String> bindings = new HashMap<>();
+        private int timingIgnoreQueries = 0;
 
         @Option(name = "-hdfs-conf", usage = "Directory path to Hadoop configuration files")
         private String hdfsConf = null;
 
+        @Option(name = "-available-processors", usage = "Number of available processors. (default: java's available processors)")
+        private int availableProcessors = -1;
+
+        @Option(name = "-local-node-controllers", usage = "Number of local node controllers. (default: 1)")
+        private int localNodeControllers = 1;
+
         @Argument
-        private List<String> arguments = new ArrayList<>();
+        private List<String> xqFiles = new ArrayList<>();
     }
-
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/vxquery/blob/f2e5fd90/vxquery-cli/src/site/markdown/index.md
----------------------------------------------------------------------
diff --git a/vxquery-cli/src/site/markdown/index.md b/vxquery-cli/src/site/markdown/index.md
new file mode 100644
index 0000000..758c947
--- /dev/null
+++ b/vxquery-cli/src/site/markdown/index.md
@@ -0,0 +1,116 @@
+<!--
+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.
+-->
+# VXQuery CLI
+
+VXQuery CLI is the command line utility which can be used to execute XQueries 
+with ease. No pre-configuration needs to be done in order to execute an XQuery.
+
+---
+
+## Quick Start
+
+***
+
+### Requirements
+
+- Apache VXQuery™ source archive (apache-vxquery-X.Y-source-release.zip)
+- JDK >= 1.8
+- Apache Maven >= 3.2
+
+***
+
+### Installing
+
+VXQuery CLI comes bundled with the VXQuery source distribution 
+(apache-vxquery-X.Y-source-release.zip).
+
+First, run `mvn package`.
+
+```
+$ unzip apache-vxquery-X.Y-source-release.zip
+$ cd apache-vxquery-X.Y
+$ mvn package -DskipTests
+```
+
+**vxquery-cli** binaries are located at `vxquery-cli/target/appassembler/bin`. 
+There are 2 files in this directory, **vxq** which is the bash executable for unix
+based systems and **vxq.bat** for windows systems. Depending on the platform,
+suitable executable needs to be selected.
+
+***
+
+### Executing a Query
+
+#### Put the query into a file
+
+VXQuery CLI takes a file location as the argument where this file includes the 
+query(statement) to be executed. Suppose the following query needs to be executed.
+
+```
+for $x in doc("books.xml")/bookstore/book
+where $x/price>30
+order by $x/title
+return $x/title
+```
+This statement is querying for the book titles in **books.xml** where price of
+the book is greater than 30. Also this query asks for the results to be ordered by
+*title* as well. Now, create a file (say **test.xq**) and put the above query as
+the content.
+
+**NOTE:** You can replace **books.xml** with any XML file that you have and want 
+to run a query on.
+
+#### Execute the query
+
+We need to invoke the matching executable according to your platform (unix/windows) 
+inside `vxquery-cli/target/appassembler/bin` directory. To execute the query, run:
+
+```
+sh ./apache-vxquery-X.Y/vxquery-cli/target/appassembler/bin/vxq path/to/test.xq
+```
+
+***
+
+## Command Line Options
+
+```
+ -O N                      : Optimization Level. (default: Full Optimization)
+ -available-processors N   : Number of available processors. (default: java's available processors)
+ -buffer-size N            : Disk read buffer size in bytes.
+ -compileonly              : Compile the query and stop.
+ -frame-size N             : Frame size in bytes. (default: 65,536)
+ -hdfs-conf VAL            : Directory path to Hadoop configuration files
+ -join-hash-size N         : Join hash size in bytes. (default: 67,108,864)
+ -local-node-controllers N : Number of local node controllers. (default: 1)
+ -maximum-data-size N      : Maximum possible data size in bytes. (default: 150,323,855,000)
+ -repeatexec N             : Number of times to repeat execution.
+ -rest-ip-address VAL      : IP Address of the REST Server.
+ -rest-port N              : Port of REST Server.
+ -result-file VAL          : File path to save the query result.
+ -showast                  : Show abstract syntax tree.
+ -showoet                  : Show optimized expression tree.
+ -showquery                : Show query string.
+ -showrp                   : Show Runtime plan.
+ -showtet                  : Show translated expression tree.
+ -timing                   : Produce timing information.
+ -timing-ignore-queries N  : Ignore the first X number of quereies.
+```
+
+**NOTE:** Normally, CLI starts a local VXQuery Server to execute the query. But,
+if you already have a VXQuery Server running, you can send the query to the 
+inbuilt *REST Server* running in that server by specifying the **port** and **ip address** 
+of the REST Server through options `-rest-ip-address` and `-rest-port`.

http://git-wip-us.apache.org/repos/asf/vxquery/blob/f2e5fd90/vxquery-cli/src/site/site.xml
----------------------------------------------------------------------
diff --git a/vxquery-cli/src/site/site.xml b/vxquery-cli/src/site/site.xml
index 4d35a0f..8b3198d 100644
--- a/vxquery-cli/src/site/site.xml
+++ b/vxquery-cli/src/site/site.xml
@@ -15,34 +15,39 @@ See the License for the specific language governing permissions and
 limitations under the License.
 -->
 <project name="VXQuery">
-  <bannerLeft>
-    <name>VXQuery</name>
-    <src>../images/VXQuery.png</src>
-    <href>../index.html</href>
-  </bannerLeft>
+    <bannerLeft>
+        <name>VXQuery</name>
+        <src>../images/VXQuery.png</src>
+        <href>../index.html</href>
+    </bannerLeft>
 
-  <bannerRight>
-    <name>Apache Software Foundation</name>
-    <src>../images/asf_logo_wide.png</src>
-    <href>http://www.apache.org/</href>
-  </bannerRight>
+    <bannerRight>
+        <name>Apache Software Foundation</name>
+        <src>../images/asf_logo_wide.png</src>
+        <href>http://www.apache.org/</href>
+    </bannerRight>
 
-  <skin>
-    <groupId>org.apache.maven.skins</groupId>
-    <artifactId>maven-fluido-skin</artifactId>
-    <version>1.5</version>
-  </skin>
+    <skin>
+        <groupId>org.apache.maven.skins</groupId>
+        <artifactId>maven-fluido-skin</artifactId>
+        <version>1.5</version>
+    </skin>
 
-  <body>
-    <menu ref="reports"/>
-    <footer><![CDATA[
-      <div class="row-fluid">Apache VXQuery, VXQuery, Apache, the Apache
-        feather logo, and the Apache VXQuery project logo are either
-        registered trademarks or trademarks of The Apache Software
-        Foundation in the United States and other countries.
-        All other marks mentioned may be trademarks or registered
-        trademarks of their respective owners.</div>
-    ]]></footer>
-  </body>
+    <body>
+        <menu name="VXQuery CLI">
+            <item name="Overview" href="index.html"/>
+        </menu>
+
+        <menu ref="reports"/>
+        <footer><![CDATA[
+            <div class="row-fluid">Apache VXQuery, VXQuery, Apache, the Apache
+                feather logo, and the Apache VXQuery project logo are either
+                registered trademarks or trademarks of The Apache Software
+                Foundation in the United States and other countries.
+                All other marks mentioned may be trademarks or registered
+                trademarks of their respective owners.
+            </div>]]>
+        </footer>
+    </body>
 </project>
 

http://git-wip-us.apache.org/repos/asf/vxquery/blob/f2e5fd90/vxquery-core/src/main/java/org/apache/vxquery/exceptions/VXQueryRuntimeException.java
----------------------------------------------------------------------
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/exceptions/VXQueryRuntimeException.java b/vxquery-core/src/main/java/org/apache/vxquery/exceptions/VXQueryRuntimeException.java
new file mode 100644
index 0000000..7f748b7
--- /dev/null
+++ b/vxquery-core/src/main/java/org/apache/vxquery/exceptions/VXQueryRuntimeException.java
@@ -0,0 +1,34 @@
+/*
+ * 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.vxquery.exceptions;
+
+/**
+ * A runtime exception to be thrown by the VXQuery and related classes of the rest server
+ *
+ * @author Erandi Ganepola
+ */
+public class VXQueryRuntimeException extends RuntimeException {
+
+    public VXQueryRuntimeException(String message) {
+        super(message);
+    }
+
+    public VXQueryRuntimeException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}

http://git-wip-us.apache.org/repos/asf/vxquery/blob/f2e5fd90/vxquery-core/src/main/java/org/apache/vxquery/exceptions/VXQueryServletRuntimeException.java
----------------------------------------------------------------------
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/exceptions/VXQueryServletRuntimeException.java b/vxquery-core/src/main/java/org/apache/vxquery/exceptions/VXQueryServletRuntimeException.java
new file mode 100644
index 0000000..f05cd6f
--- /dev/null
+++ b/vxquery-core/src/main/java/org/apache/vxquery/exceptions/VXQueryServletRuntimeException.java
@@ -0,0 +1,34 @@
+/*
+ * 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.vxquery.exceptions;
+
+/**
+ * A runtime exception class to be used to be thrown when runtime errors occur within servlets.
+ *
+ * @author Erandi Ganepola
+ */
+public class VXQueryServletRuntimeException extends VXQueryRuntimeException {
+
+    public VXQueryServletRuntimeException(String message) {
+        super(message);
+    }
+
+    public VXQueryServletRuntimeException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}

http://git-wip-us.apache.org/repos/asf/vxquery/blob/f2e5fd90/vxquery-core/src/main/java/org/apache/vxquery/metadata/VXQueryMetadataProvider.java
----------------------------------------------------------------------
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/metadata/VXQueryMetadataProvider.java b/vxquery-core/src/main/java/org/apache/vxquery/metadata/VXQueryMetadataProvider.java
index 5bb9d1a..1527059 100644
--- a/vxquery-core/src/main/java/org/apache/vxquery/metadata/VXQueryMetadataProvider.java
+++ b/vxquery-core/src/main/java/org/apache/vxquery/metadata/VXQueryMetadataProvider.java
@@ -285,5 +285,4 @@ public class VXQueryMetadataProvider implements IMetadataProvider<String, String
         }
         return indexExists;
     }
-
 }

http://git-wip-us.apache.org/repos/asf/vxquery/blob/f2e5fd90/vxquery-rest/pom.xml
----------------------------------------------------------------------
diff --git a/vxquery-rest/pom.xml b/vxquery-rest/pom.xml
new file mode 100644
index 0000000..052132f
--- /dev/null
+++ b/vxquery-rest/pom.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>apache-vxquery</artifactId>
+        <groupId>org.apache.vxquery</groupId>
+        <version>0.7-SNAPSHOT</version>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <packaging>jar</packaging>
+    <name>VXQuery REST Server</name>
+    <description>Apache VXQuery REST Server</description>
+
+    <artifactId>apache-vxquery-rest</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.vxquery</groupId>
+            <artifactId>apache-vxquery-core</artifactId>
+            <version>0.7-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.hyracks</groupId>
+            <artifactId>hyracks-client</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.hyracks</groupId>
+            <artifactId>hyracks-http</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/vxquery/blob/f2e5fd90/vxquery-rest/src/main/java/org/apache/vxquery/app/VXQueryApplication.java
----------------------------------------------------------------------
diff --git a/vxquery-rest/src/main/java/org/apache/vxquery/app/VXQueryApplication.java b/vxquery-rest/src/main/java/org/apache/vxquery/app/VXQueryApplication.java
new file mode 100644
index 0000000..f5e0165
--- /dev/null
+++ b/vxquery-rest/src/main/java/org/apache/vxquery/app/VXQueryApplication.java
@@ -0,0 +1,179 @@
+/*
+ * 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.vxquery.app;
+
+import static org.apache.vxquery.rest.Constants.Properties.AVAILABLE_PROCESSORS;
+import static org.apache.vxquery.rest.Constants.Properties.HDFS_CONFIG;
+import static org.apache.vxquery.rest.Constants.Properties.JOIN_HASH_SIZE;
+import static org.apache.vxquery.rest.Constants.Properties.MAXIMUM_DATA_SIZE;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.hyracks.api.application.ICCApplicationContext;
+import org.apache.hyracks.api.application.ICCApplicationEntryPoint;
+import org.apache.hyracks.api.client.ClusterControllerInfo;
+import org.apache.vxquery.exceptions.VXQueryRuntimeException;
+import org.apache.vxquery.rest.RestServer;
+import org.apache.vxquery.rest.service.VXQueryConfig;
+import org.apache.vxquery.rest.service.VXQueryService;
+import org.kohsuke.args4j.CmdLineParser;
+import org.kohsuke.args4j.Option;
+
+/**
+ * Main class responsible for starting the {@link RestServer} and
+ * {@link VXQueryService} classes.
+ *
+ * @author Erandi Ganepola
+ */
+public class VXQueryApplication implements ICCApplicationEntryPoint {
+
+    private static final Logger LOGGER = Logger.getLogger(VXQueryApplication.class.getName());
+
+    private VXQueryService vxQueryService;
+    private RestServer restServer;
+
+    @Override
+    public void start(ICCApplicationContext ccAppCtx, String[] args) throws Exception {
+        AppArgs appArgs = new AppArgs();
+        if (args != null) {
+            CmdLineParser parser = new CmdLineParser(appArgs);
+            try {
+                parser.parseArgument(args);
+            } catch (Exception e) {
+                parser.printUsage(System.err);
+                throw new VXQueryRuntimeException("Unable to parse app arguments", e);
+            }
+        }
+
+        VXQueryConfig config =
+                loadConfiguration(ccAppCtx.getCCContext().getClusterControllerInfo(), appArgs.getVxqueryConfig());
+        vxQueryService = new VXQueryService(config);
+        restServer = new RestServer(vxQueryService, appArgs.getRestPort());
+    }
+
+    public synchronized void stop() {
+        try {
+            LOGGER.log(Level.INFO, "Stopping REST server");
+            restServer.stop();
+
+            LOGGER.log(Level.INFO, "Stopping VXQueryService");
+            vxQueryService.stop();
+        } catch (Exception e) {
+            LOGGER.log(Level.SEVERE, "Error occurred when stopping the application", e);
+        }
+    }
+
+    @Override
+    public void startupCompleted() throws Exception {
+        try {
+            LOGGER.log(Level.INFO, "Starting VXQueryService");
+            vxQueryService.start();
+            LOGGER.log(Level.INFO, "VXQueryService started successfully");
+
+            LOGGER.log(Level.INFO, "Starting REST server");
+            restServer.start();
+        } catch (Exception e) {
+            LOGGER.log(Level.SEVERE, "Error occurred when starting application", e);
+            stop();
+            throw new VXQueryRuntimeException("Error occurred when starting application", e);
+        }
+    }
+
+    /**
+     * Loads properties from
+     * 
+     * <pre>
+     * -appConfig foo/bar.properties
+     * </pre>
+     * 
+     * file if specified in the app arguments.
+     *
+     * @param clusterControllerInfo
+     *            cluster controller information
+     * @param propertiesFile
+     *            vxquery configuration properties file, given by
+     * 
+     *            <pre>
+     *            -appConfig
+     *            </pre>
+     * 
+     *            option in app argument
+     * @return A new {@link VXQueryConfig} instance with either default properties
+     *         or properties loaded from the properties file given.
+     */
+    private VXQueryConfig loadConfiguration(ClusterControllerInfo clusterControllerInfo, String propertiesFile) {
+        VXQueryConfig vxqConfig = new VXQueryConfig();
+        if (propertiesFile != null) {
+            try (InputStream in = new FileInputStream(propertiesFile)) {
+                System.getProperties().load(in);
+            } catch (IOException e) {
+                LOGGER.log(Level.SEVERE,
+                        String.format("Error occurred when loading properties file %s", propertiesFile), e);
+            }
+        }
+
+        vxqConfig.setAvailableProcessors(Integer.getInteger(AVAILABLE_PROCESSORS, 1));
+        vxqConfig.setJoinHashSize(Long.getLong(JOIN_HASH_SIZE, -1));
+        vxqConfig.setHdfsConf(System.getProperty(HDFS_CONFIG));
+        vxqConfig.setMaximumDataSize(Long.getLong(MAXIMUM_DATA_SIZE, -1));
+
+        vxqConfig.setHyracksClientIp(clusterControllerInfo.getClientNetAddress());
+        vxqConfig.setHyracksClientPort(clusterControllerInfo.getClientNetPort());
+
+        return vxqConfig;
+    }
+
+    public VXQueryService getVxQueryService() {
+        return vxQueryService;
+    }
+
+    public RestServer getRestServer() {
+        return restServer;
+    }
+
+    /**
+     * Application Arguments bean class
+     */
+    private class AppArgs {
+        @Option(name = "-restPort", usage = "The port on which REST server starts")
+        private int restPort = 8080;
+
+        @Option(name = "-appConfig", usage = "Properties file location which includes VXQueryService Application additional configuration")
+        private String vxqueryConfig = null;
+
+        public String getVxqueryConfig() {
+            return vxqueryConfig;
+        }
+
+        public void setVxqueryConfig(String vxqueryConfig) {
+            this.vxqueryConfig = vxqueryConfig;
+        }
+
+        public int getRestPort() {
+            return restPort;
+        }
+
+        public void setRestPort(int restPort) {
+            this.restPort = restPort;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/vxquery/blob/f2e5fd90/vxquery-rest/src/main/java/org/apache/vxquery/app/util/LocalClusterUtil.java
----------------------------------------------------------------------
diff --git a/vxquery-rest/src/main/java/org/apache/vxquery/app/util/LocalClusterUtil.java b/vxquery-rest/src/main/java/org/apache/vxquery/app/util/LocalClusterUtil.java
new file mode 100644
index 0000000..9b18745
--- /dev/null
+++ b/vxquery-rest/src/main/java/org/apache/vxquery/app/util/LocalClusterUtil.java
@@ -0,0 +1,187 @@
+/*
+ * 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.vxquery.app.util;
+
+import static org.apache.vxquery.rest.Constants.Properties.AVAILABLE_PROCESSORS;
+import static org.apache.vxquery.rest.Constants.Properties.HDFS_CONFIG;
+import static org.apache.vxquery.rest.Constants.Properties.JOIN_HASH_SIZE;
+import static org.apache.vxquery.rest.Constants.Properties.MAXIMUM_DATA_SIZE;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.nio.file.Files;
+import java.util.Arrays;
+
+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.client.dataset.HyracksDataset;
+import org.apache.hyracks.control.cc.ClusterControllerService;
+import org.apache.hyracks.control.common.controllers.CCConfig;
+import org.apache.hyracks.control.common.controllers.NCConfig;
+import org.apache.hyracks.control.nc.NodeControllerService;
+import org.apache.vxquery.app.VXQueryApplication;
+import org.apache.vxquery.rest.service.VXQueryConfig;
+import org.apache.vxquery.rest.service.VXQueryService;
+
+/**
+ * A utility class to start the a local hyracks cluster.
+ *
+ * @author Preston Carman
+ */
+public class LocalClusterUtil {
+    /*
+     * Start local virtual cluster with cluster controller node and node controller
+     * nodes. IP address provided for node controller is localhost. Unassigned ports
+     * 39000 and 39001 are used for client and cluster port respectively.
+     */
+    public static final int DEFAULT_HYRACKS_CC_CLIENT_PORT = 39000;
+    public static final int DEFAULT_HYRACKS_CC_CLUSTER_PORT = 39001;
+    public static final int DEFAULT_HYRACKS_CC_HTTP_PORT = 39002;
+    public static final int DEFAULT_VXQUERY_REST_PORT = 39003;
+
+    // TODO review variable scope after XTest is updated to use the REST service.
+    public ClusterControllerService clusterControllerService;
+    public NodeControllerService nodeControllerSerivce;
+    public IHyracksClientConnection hcc;
+    public IHyracksDataset hds;
+    public VXQueryService vxQueryService;
+
+    public void init(VXQueryConfig config) throws Exception {
+        // Following properties are needed by the app to setup
+        System.setProperty(AVAILABLE_PROCESSORS, String.valueOf(config.getAvailableProcessors()));
+        System.setProperty(JOIN_HASH_SIZE, String.valueOf(config.getJoinHashSize()));
+        System.setProperty(MAXIMUM_DATA_SIZE, String.valueOf(config.getMaximumDataSize()));
+        if (config.getHdfsConf() != null) {
+            System.setProperty(HDFS_CONFIG, config.getHdfsConf());
+        }
+
+        // Cluster controller
+        CCConfig ccConfig = createCCConfig();
+        clusterControllerService = new ClusterControllerService(ccConfig);
+        clusterControllerService.start();
+
+        hcc = new HyracksConnection(ccConfig.clientNetIpAddress, ccConfig.clientNetPort);
+        hds = new HyracksDataset(hcc, config.getFrameSize(), config.getAvailableProcessors());
+
+        // Node controller
+        NCConfig ncConfig = createNCConfig();
+        nodeControllerSerivce = new NodeControllerService(ncConfig);
+        nodeControllerSerivce.start();
+
+        hcc = new HyracksConnection(ccConfig.clientNetIpAddress, ccConfig.clientNetPort);
+
+        // REST controller
+        config.setHyracksClientIp(ccConfig.clientNetIpAddress);
+        config.setHyracksClientPort(ccConfig.clientNetPort);
+        vxQueryService = new VXQueryService(config);
+        vxQueryService.start();
+    }
+
+    protected CCConfig createCCConfig() throws IOException {
+        String localAddress = getIpAddress();
+        CCConfig ccConfig = new CCConfig();
+        ccConfig.clientNetIpAddress = localAddress;
+        ccConfig.clientNetPort = DEFAULT_HYRACKS_CC_CLIENT_PORT;
+        ccConfig.clusterNetIpAddress = localAddress;
+        ccConfig.clusterNetPort = DEFAULT_HYRACKS_CC_CLUSTER_PORT;
+        ccConfig.httpPort = DEFAULT_HYRACKS_CC_HTTP_PORT;
+        ccConfig.profileDumpPeriod = 10000;
+        ccConfig.appCCMainClass = VXQueryApplication.class.getName();
+        ccConfig.appArgs = Arrays.asList("-restPort", String.valueOf(DEFAULT_VXQUERY_REST_PORT));
+
+        return ccConfig;
+    }
+
+    protected NCConfig createNCConfig() throws IOException {
+        String localAddress = getIpAddress();
+        NCConfig ncConfig = new NCConfig();
+        ncConfig.ccHost = "localhost";
+        ncConfig.ccPort = DEFAULT_HYRACKS_CC_CLUSTER_PORT;
+        ncConfig.clusterNetIPAddress = localAddress;
+        ncConfig.dataIPAddress = localAddress;
+        ncConfig.resultIPAddress = localAddress;
+        ncConfig.nodeId = "test_node";
+        ncConfig.ioDevices = Files.createTempDirectory(ncConfig.nodeId).toString();
+        return ncConfig;
+    }
+
+    public IHyracksClientConnection getHyracksClientConnection() {
+        return hcc;
+    }
+
+    public VXQueryService getVxQueryService() {
+        return vxQueryService;
+    }
+
+    public void deinit() throws Exception {
+        vxQueryService.stop();
+        nodeControllerSerivce.stop();
+        clusterControllerService.stop();
+    }
+
+    public static void main(String[] args) {
+        LocalClusterUtil localClusterUtil = new LocalClusterUtil();
+        VXQueryConfig config = new VXQueryConfig();
+        run(localClusterUtil, config);
+    }
+
+    protected static void run(final LocalClusterUtil localClusterUtil, VXQueryConfig config) {
+        Runtime.getRuntime().addShutdownHook(new Thread() {
+            @Override
+            public void run() {
+                try {
+                    localClusterUtil.deinit();
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        });
+
+        try {
+            localClusterUtil.init(config);
+            while (true) {
+                Thread.sleep(10000);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.exit(1);
+        }
+    }
+
+    public String getIpAddress() throws UnknownHostException {
+        return InetAddress.getLocalHost().getHostAddress();
+    }
+
+    public int getRestPort() {
+        return DEFAULT_VXQUERY_REST_PORT;
+    }
+
+    @Deprecated
+    public IHyracksClientConnection getConnection() {
+        return hcc;
+    }
+
+    @Deprecated
+    public IHyracksDataset getDataset() {
+        return hds;
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/vxquery/blob/f2e5fd90/vxquery-rest/src/main/java/org/apache/vxquery/app/util/RestUtils.java
----------------------------------------------------------------------
diff --git a/vxquery-rest/src/main/java/org/apache/vxquery/app/util/RestUtils.java b/vxquery-rest/src/main/java/org/apache/vxquery/app/util/RestUtils.java
new file mode 100644
index 0000000..fe91836
--- /dev/null
+++ b/vxquery-rest/src/main/java/org/apache/vxquery/app/util/RestUtils.java
@@ -0,0 +1,200 @@
+/*
+ * 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.vxquery.app.util;
+
+import static org.apache.vxquery.rest.Constants.MODE_ASYNC;
+import static org.apache.vxquery.rest.Constants.MODE_SYNC;
+import static org.apache.vxquery.rest.Constants.HttpHeaderValues.CONTENT_TYPE_JSON;
+import static org.apache.vxquery.rest.Constants.HttpHeaderValues.CONTENT_TYPE_XML;
+import static org.apache.vxquery.rest.Constants.Parameters.COMPILE_ONLY;
+import static org.apache.vxquery.rest.Constants.Parameters.FRAME_SIZE;
+import static org.apache.vxquery.rest.Constants.Parameters.METRICS;
+import static org.apache.vxquery.rest.Constants.Parameters.MODE;
+import static org.apache.vxquery.rest.Constants.Parameters.OPTIMIZATION;
+import static org.apache.vxquery.rest.Constants.Parameters.REPEAT_EXECUTIONS;
+import static org.apache.vxquery.rest.Constants.Parameters.SHOW_AST;
+import static org.apache.vxquery.rest.Constants.Parameters.SHOW_OET;
+import static org.apache.vxquery.rest.Constants.Parameters.SHOW_RP;
+import static org.apache.vxquery.rest.Constants.Parameters.SHOW_TET;
+import static org.apache.vxquery.rest.Constants.Parameters.STATEMENT;
+import static org.apache.vxquery.rest.Constants.URLs.QUERY_ENDPOINT;
+import static org.apache.vxquery.rest.Constants.URLs.QUERY_RESULT_ENDPOINT;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.StringReader;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+
+import org.apache.htrace.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.http.HttpEntity;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.vxquery.rest.request.QueryRequest;
+import org.apache.vxquery.rest.request.QueryResultRequest;
+
+/**
+ * A set of utility methods used by the REST related tasks
+ *
+ * @author Erandi Ganepola
+ */
+public class RestUtils {
+
+    private RestUtils() {
+    }
+
+    /**
+     * Builds the {@link URI} once the {@link QueryRequest} is given. Only the
+     * parameters given (different from the default values) are put in the
+     * {@link URI}
+     * 
+     * @param request
+     *            {@link QueryRequest} to be converted to a {@link URI}
+     * @param restIpAddress
+     *            Ip address of the REST server
+     * @param restPort
+     *            port of the REST server
+     * @return generated {@link URI}
+     * @throws URISyntaxException
+     */
+    public static URI buildQueryURI(QueryRequest request, String restIpAddress, int restPort)
+            throws URISyntaxException {
+        URIBuilder builder =
+                new URIBuilder().setScheme("http").setHost(restIpAddress).setPort(restPort).setPath(QUERY_ENDPOINT);
+
+        if (request.getStatement() != null) {
+            builder.addParameter(STATEMENT, request.getStatement());
+        }
+        if (request.isCompileOnly()) {
+            builder.addParameter(COMPILE_ONLY, String.valueOf(request.isCompileOnly()));
+        }
+        if (request.getOptimization() != QueryRequest.DEFAULT_OPTIMIZATION) {
+            builder.addParameter(OPTIMIZATION, String.valueOf(request.getOptimization()));
+        }
+        if (request.getFrameSize() != QueryRequest.DEFAULT_FRAMESIZE) {
+            builder.addParameter(FRAME_SIZE, String.valueOf(request.getFrameSize()));
+        }
+        if (request.getRepeatExecutions() != 1) {
+            builder.addParameter(REPEAT_EXECUTIONS, String.valueOf(request.getRepeatExecutions()));
+        }
+        if (request.isShowMetrics()) {
+            builder.addParameter(METRICS, String.valueOf(request.isShowMetrics()));
+        }
+        if (request.isShowAbstractSyntaxTree()) {
+            builder.addParameter(SHOW_AST, String.valueOf(request.isShowAbstractSyntaxTree()));
+        }
+        if (request.isShowTranslatedExpressionTree()) {
+            builder.addParameter(SHOW_TET, String.valueOf(request.isShowTranslatedExpressionTree()));
+        }
+        if (request.isShowOptimizedExpressionTree()) {
+            builder.addParameter(SHOW_OET, String.valueOf(request.isShowOptimizedExpressionTree()));
+        }
+        if (request.isShowRuntimePlan()) {
+            builder.addParameter(SHOW_RP, String.valueOf(request.isShowRuntimePlan()));
+        }
+        if (!request.isAsync()) {
+            builder.addParameter(MODE, request.isAsync() ? MODE_ASYNC : MODE_SYNC);
+        }
+
+        return builder.build();
+    }
+
+    /**
+     * Builds the query result {@link URI} given the {@link QueryResultRequest}
+     * 
+     * @param resultRequest
+     *            result request
+     * @param restIpAddress
+     *            rest server's ip
+     * @param restPort
+     *            port of the rest server
+     * @return generated {@link URI}
+     * @throws URISyntaxException
+     */
+    public static URI buildQueryResultURI(QueryResultRequest resultRequest, String restIpAddress, int restPort)
+            throws URISyntaxException {
+        URIBuilder builder = new URIBuilder().setScheme("http").setHost(restIpAddress).setPort(restPort)
+                .setPath(QUERY_RESULT_ENDPOINT.replace("*", String.valueOf(resultRequest.getResultId())));
+
+        if (resultRequest.isShowMetrics()) {
+            builder.setParameter(METRICS, String.valueOf(resultRequest.isShowMetrics()));
+        }
+
+        return builder.build();
+    }
+
+    /**
+     * Reads the entity from an {@link HttpEntity}
+     * 
+     * @param entity
+     *            entity instance to be read
+     * @return entity read by this method as a string
+     * @throws IOException
+     */
+    public static String readEntity(HttpEntity entity) throws IOException {
+        StringBuilder responseBody = new StringBuilder();
+
+        try (InputStream in = entity.getContent()) {
+            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+            String line;
+            while ((line = reader.readLine()) != null) {
+                responseBody.append(line);
+            }
+        }
+        return responseBody.toString();
+    }
+
+    /**
+     * Maps the object in the string representation to a java object. To map json
+     * entities, this method use {@link ObjectMapper}. For XML this method use
+     * {@link Unmarshaller}.
+     * 
+     * @param entity
+     *            string representation of the object
+     * @param type
+     *            the class to which the string needs to be mapped to
+     * @param contentType
+     *            json or XML
+     * @param <T>
+     *            content's class type
+     * @return mapped object
+     * @throws IOException
+     * @throws JAXBException
+     */
+    public static <T> T mapEntity(String entity, Class<T> type, String contentType) throws IOException, JAXBException {
+        if (contentType == null) {
+            contentType = CONTENT_TYPE_JSON;
+        }
+
+        switch (contentType) {
+            case CONTENT_TYPE_XML:
+                JAXBContext jaxbContext = JAXBContext.newInstance(type);
+                Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
+                return type.cast(unmarshaller.unmarshal(new StringReader(entity)));
+            case CONTENT_TYPE_JSON:
+            default:
+                ObjectMapper jsonMapper = new ObjectMapper();
+                return jsonMapper.readValue(entity, type);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/vxquery/blob/f2e5fd90/vxquery-rest/src/main/java/org/apache/vxquery/rest/Constants.java
----------------------------------------------------------------------
diff --git a/vxquery-rest/src/main/java/org/apache/vxquery/rest/Constants.java b/vxquery-rest/src/main/java/org/apache/vxquery/rest/Constants.java
new file mode 100644
index 0000000..4ba79ec
--- /dev/null
+++ b/vxquery-rest/src/main/java/org/apache/vxquery/rest/Constants.java
@@ -0,0 +1,71 @@
+/*
+ * 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.vxquery.rest;
+
+public class Constants {
+
+    private Constants() {
+    }
+
+    public class Parameters {
+        public static final String STATEMENT = "statement";
+        public static final String RESULT_ID = "resultId ";
+        public static final String COMPILE_ONLY = "compileOnly";
+        public static final String OPTIMIZATION = "optimization";
+        public static final String FRAME_SIZE = "frameSize";
+        public static final String REPEAT_EXECUTIONS = "repeatExecutions";
+        public static final String METRICS = "metrics";
+        public static final String SHOW_AST = "showAbstractSyntaxTree";
+        public static final String SHOW_TET = "showTranslatedExpressionTree";
+        public static final String SHOW_OET = "showOptimizedExpressionTree";
+        public static final String SHOW_RP = "showRuntimePlan";
+        public static final String MODE = "mode";
+    }
+
+    public class URLs {
+        public static final String BASE_PATH = "/vxquery";
+
+        public static final String QUERY_ENDPOINT = BASE_PATH + "/query";
+        public static final String QUERY_RESULT_ENDPOINT = BASE_PATH + "/query/result/*";
+    }
+
+    public class Properties {
+        public static final String AVAILABLE_PROCESSORS = "org.apache.vxquery.available_processors";
+        public static final String LOCAL_NODE_CONTROLLERS = "org.apache.vxquery.local_nc";
+        public static final String JOIN_HASH_SIZE = "org.apache.vxquery.join_hash";
+        public static final String MAXIMUM_DATA_SIZE = "org.apache.vxquery.data_size";
+        public static final String HDFS_CONFIG = "org.apache.vxquery.hdfs_config";
+    }
+
+    public class HttpHeaderValues {
+        public static final String CONTENT_TYPE_JSON = "application/json";
+        public static final String CONTENT_TYPE_XML = "application/xml";
+    }
+
+    public class ErrorCodes {
+        public static final int PROBLEM_WITH_QUERY = 400;
+        public static final int UNFORSEEN_PROBLEM = 500;
+        public static final int INVALID_INPUT = 405;
+        public static final int NOT_FOUND = 404;
+    }
+
+    public static final String RESULT_URL_PREFIX = "/vxquery/query/result/";
+
+    public static final String MODE_ASYNC = "async";
+    public static final String MODE_SYNC = "sync";
+}


Mime
View raw message