Till Westmann has uploaded a new change for review.
https://asterix-gerrit.ics.uci.edu/1508
Change subject: ASTERIXDB-1786: Remove Hyracks Servlets.
......................................................................
ASTERIXDB-1786: Remove Hyracks Servlets.
Change-Id: Ifcd240591d12baab2db4ce3163c635a1dde5c4ba
---
M asterixdb/asterix-app/pom.xml
M
asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ApiServlet.java
M
asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryWebInterfaceServlet.java
M asterixdb/asterix-common/pom.xml
M asterixdb/pom.xml
M hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/pom.xml
M
hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/ClusterControllerService.java
M
hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/web/JobsRESTAPIFunction.java
M
hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/web/WebServer.java
M
hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/web/util/JSONOutputRequestHandler.java
M hyracks-fullstack/hyracks/hyracks-http/pom.xml
M
hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/AbstractServlet.java
A
hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/StaticResourceServlet.java
M hyracks-fullstack/pom.xml
14 files changed, 205 insertions(+), 130 deletions(-)
git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb
refs/changes/08/1508/1
diff --git a/asterixdb/asterix-app/pom.xml b/asterixdb/asterix-app/pom.xml
index 99e58df..7ce71b7 100644
--- a/asterixdb/asterix-app/pom.xml
+++ b/asterixdb/asterix-app/pom.xml
@@ -463,7 +463,6 @@
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
- <version>4.1.6.Final</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
diff --git
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ApiServlet.java
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ApiServlet.java
index 95eb6fb..db824aa 100644
---
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ApiServlet.java
+++
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ApiServlet.java
@@ -82,7 +82,7 @@
this.componentProvider = componentProvider;
}
- public void doPost(IServletRequest request, IServletResponse response) {
+ protected void doPost(IServletRequest request, IServletResponse response) {
// Query language
ILangCompilationProvider compilationProvider =
"AQL".equals(request.getParameter("query-language"))
? aqlCompilationProvider : sqlppCompilationProvider;
@@ -156,7 +156,7 @@
}
}
- public void doGet(IServletRequest request, IServletResponse response) {
+ protected void doGet(IServletRequest request, IServletResponse response) {
String resourcePath = null;
String requestURI = request.getHttpRequest().uri();
@@ -188,7 +188,7 @@
outputStream.close();
return;
}
- String type =
IServlet.ContentType.mime(QueryWebInterfaceServlet.extension(resourcePath));
+ String type = IServlet.ContentType.mime(extension(resourcePath));
ServletUtils.setContentType(response, "".equals(type) ?
IServlet.ContentType.TEXT_PLAIN : type,
IServlet.Encoding.UTF8);
writeOutput(response, is, resourcePath);
@@ -199,6 +199,11 @@
}
}
+ public static String extension(String path) {
+ int i = path.lastIndexOf('.');
+ return i < 1 ? "" : path.substring(i);
+ }
+
private void writeOutput(IServletResponse response, InputStream is, String
resourcePath) throws IOException {
try (InputStreamReader isr = new InputStreamReader(is); BufferedReader
br = new BufferedReader(isr)) {
StringBuilder sb = new StringBuilder();
diff --git
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryWebInterfaceServlet.java
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryWebInterfaceServlet.java
index 96df30f..bc9b115 100644
---
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryWebInterfaceServlet.java
+++
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryWebInterfaceServlet.java
@@ -19,8 +19,6 @@
package org.apache.asterix.api.http.server;
import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.concurrent.ConcurrentMap;
import java.util.logging.Level;
@@ -28,85 +26,35 @@
import org.apache.asterix.common.config.ExternalProperties;
import org.apache.asterix.runtime.utils.AppContextInfo;
-import org.apache.commons.io.IOUtils;
import org.apache.hyracks.http.api.IServlet;
import org.apache.hyracks.http.api.IServletRequest;
import org.apache.hyracks.http.api.IServletResponse;
-import org.apache.hyracks.http.server.AbstractServlet;
+import org.apache.hyracks.http.server.StaticResourceServlet;
import org.apache.hyracks.http.server.util.ServletUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
-import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpResponseStatus;
-public class QueryWebInterfaceServlet extends AbstractServlet {
+public class QueryWebInterfaceServlet extends StaticResourceServlet {
private static final Logger LOGGER =
Logger.getLogger(QueryWebInterfaceServlet.class.getName());
public QueryWebInterfaceServlet(ConcurrentMap<String, Object> ctx,
String[] paths) {
super(ctx, paths);
}
- @Override
- public void handle(IServletRequest request, IServletResponse response) {
- try {
- if (request.getHttpRequest().method() == HttpMethod.GET) {
- doGet(request, response);
- } else if (request.getHttpRequest().method() == HttpMethod.POST) {
- doPost(response);
- } else {
- response.setStatus(HttpResponseStatus.METHOD_NOT_ALLOWED);
- }
- } catch (IOException e) {
- LOGGER.log(Level.WARNING, "Failure setting content type", e);
- response.setStatus(HttpResponseStatus.INTERNAL_SERVER_ERROR);
- return;
- }
- }
-
- private void doGet(IServletRequest request, IServletResponse response)
throws IOException {
- String resourcePath = null;
+ protected void doGet(IServletRequest request, IServletResponse response)
throws IOException {
String requestURI = request.getHttpRequest().uri();
- response.setStatus(HttpResponseStatus.OK);
-
if ("/".equals(requestURI)) {
ServletUtils.setContentType(response,
IServlet.ContentType.TEXT_HTML);
- resourcePath = "/queryui/queryui.html";
+ deliverResource("/queryui/queryui.html", response);
} else {
- resourcePath = requestURI;
- }
-
- try (InputStream is =
QueryWebInterfaceServlet.class.getResourceAsStream(resourcePath)) {
- if (is == null) {
- response.setStatus(HttpResponseStatus.NOT_FOUND);
- return;
- }
- int i = resourcePath.lastIndexOf('.');
- if (i >= 0) {
- String extension = resourcePath.substring(i);
- String mime = IServlet.ContentType.mime(extension);
- if (mime != null) {
- OutputStream out = response.outputStream();
- ServletUtils.setContentType(response, mime);
- try {
- IOUtils.copy(is, out);
- } catch (Exception e) {
- LOGGER.log(Level.WARNING, "Failure copying response",
e);
- } finally {
- if (out != null) {
- IOUtils.closeQuietly(out);
- }
- IOUtils.closeQuietly(is);
- }
- return;
- }
- }
- response.setStatus(HttpResponseStatus.BAD_REQUEST);
+ deliverResource(requestURI, response);
}
}
- private void doPost(IServletResponse response) throws IOException {
+ protected void doPost(IServletRequest request, IServletResponse response)
throws IOException {
ServletUtils.setContentType(response,
IServlet.ContentType.APPLICATION_JSON, IServlet.Encoding.UTF8);
ExternalProperties externalProperties =
AppContextInfo.INSTANCE.getExternalProperties();
response.setStatus(HttpResponseStatus.OK);
@@ -125,10 +73,5 @@
} catch (Exception e) {
LOGGER.log(Level.SEVERE, "Failure setting response status", e);
}
- }
-
- public static String extension(String path) {
- int i = path.lastIndexOf('.');
- return i < 1 ? "" : path.substring(i);
}
}
diff --git a/asterixdb/asterix-common/pom.xml b/asterixdb/asterix-common/pom.xml
index c2f1c6a..d642b57 100644
--- a/asterixdb/asterix-common/pom.xml
+++ b/asterixdb/asterix-common/pom.xml
@@ -295,7 +295,6 @@
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
- <version>4.1.6.Final</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
diff --git a/asterixdb/pom.xml b/asterixdb/pom.xml
index 57488bc..8226764 100644
--- a/asterixdb/pom.xml
+++ b/asterixdb/pom.xml
@@ -1011,6 +1011,11 @@
<version>2.33</version>
</dependency>
<dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-all</artifactId>
+ <version>4.1.6.Final</version>
+ </dependency>
+ <dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
diff --git
a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/pom.xml
b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/pom.xml
index c960da9..76ce1b3 100644
--- a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/pom.xml
+++ b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/pom.xml
@@ -75,10 +75,19 @@
<dependencies>
<dependency>
<groupId>org.apache.hyracks</groupId>
+ <artifactId>hyracks-http</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hyracks</groupId>
<artifactId>hyracks-control-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-all</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
</dependency>
diff --git
a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/ClusterControllerService.java
b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/ClusterControllerService.java
index 37c4177..897a47a 100644
---
a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/ClusterControllerService.java
+++
b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/ClusterControllerService.java
@@ -137,7 +137,7 @@
IIPCI ciIPCI = new ClientInterfaceIPCI(this);
clientIPC = new IPCSystem(new
InetSocketAddress(ccConfig.clientNetIpAddress, ccConfig.clientNetPort), ciIPCI,
new JavaSerializationBasedPayloadSerializerDeserializer());
- webServer = new WebServer(this);
+ webServer = new WebServer(this, ccConfig.httpPort);
// WorkQueue is in charge of heartbeat as well as other events.
workQueue = new WorkQueue("ClusterController", Thread.MAX_PRIORITY);
@@ -173,7 +173,6 @@
LOGGER.log(Level.INFO, "Starting ClusterControllerService: " + this);
clusterIPC.start();
clientIPC.start();
- webServer.setPort(ccConfig.httpPort);
webServer.start();
info = new ClusterControllerInfo(ccConfig.clientNetIpAddress,
ccConfig.clientNetPort,
webServer.getListeningPort());
diff --git
a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/web/JobsRESTAPIFunction.java
b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/web/JobsRESTAPIFunction.java
index 892807b..ebd055d 100644
---
a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/web/JobsRESTAPIFunction.java
+++
b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/web/JobsRESTAPIFunction.java
@@ -18,9 +18,6 @@
*/
package org.apache.hyracks.control.cc.web;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
import org.apache.hyracks.api.job.JobId;
import org.apache.hyracks.control.cc.ClusterControllerService;
import org.apache.hyracks.control.cc.web.util.IJSONOutputFunction;
@@ -28,6 +25,9 @@
import org.apache.hyracks.control.cc.work.GetJobRunJSONWork;
import org.apache.hyracks.control.cc.work.GetJobSummariesJSONWork;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
public class JobsRESTAPIFunction implements IJSONOutputFunction {
private ClusterControllerService ccs;
diff --git
a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/web/WebServer.java
b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/web/WebServer.java
index 8fe68c1..ba94a37 100644
---
a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/web/WebServer.java
+++
b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/web/WebServer.java
@@ -19,63 +19,63 @@
package org.apache.hyracks.control.cc.web;
import java.util.EnumSet;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import javax.servlet.DispatcherType;
import org.apache.hyracks.control.cc.ClusterControllerService;
import
org.apache.hyracks.control.cc.adminconsole.HyracksAdminConsoleApplication;
+import org.apache.hyracks.control.cc.web.util.IJSONOutputFunction;
import org.apache.hyracks.control.cc.web.util.JSONOutputRequestHandler;
-import org.apache.hyracks.control.cc.web.util.RoutingHandler;
+import org.apache.hyracks.http.server.HttpServer;
+import org.apache.hyracks.http.server.WebManager;
import org.apache.wicket.Application;
import org.apache.wicket.RuntimeConfigurationType;
import org.apache.wicket.protocol.http.ContextParamWebApplicationFactory;
import org.apache.wicket.protocol.http.WicketFilter;
-import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.server.handler.ContextHandler;
-import org.eclipse.jetty.server.handler.ContextHandlerCollection;
-import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletContextHandler;
public class WebServer {
private final ClusterControllerService ccs;
- private final Server server;
- private final ServerConnector connector;
- private final HandlerCollection handlerCollection;
+ private final int listeningPort;
+ private final ConcurrentMap<String, Object> ctx;
+ private final WebManager webMgr;
+ private final HttpServer server;
- public WebServer(ClusterControllerService ccs) throws Exception {
+ public WebServer(ClusterControllerService ccs, int port) throws Exception {
this.ccs = ccs;
- server = new Server();
-
- connector = new ServerConnector(server);
-
- server.setConnectors(new Connector[] { connector });
-
- handlerCollection = new ContextHandlerCollection();
- server.setHandler(handlerCollection);
+ listeningPort = port;
+ ctx = new ConcurrentHashMap<String, Object>();
+ webMgr = new WebManager();
+ server = new HttpServer(webMgr.getBosses(), webMgr.getWorkers(),
listeningPort);
addHandlers();
+ webMgr.add(server);
}
private void addHandlers() {
- ContextHandler handler = new ContextHandler("/rest");
- RoutingHandler rh = new RoutingHandler();
- rh.addHandler("jobs", new JSONOutputRequestHandler(new
JobsRESTAPIFunction(ccs)));
- rh.addHandler("nodes", new JSONOutputRequestHandler(new
NodesRESTAPIFunction(ccs)));
- rh.addHandler("statedump", new JSONOutputRequestHandler(new
StateDumpRESTAPIFunction(ccs)));
- handler.setHandler(rh);
- addHandler(handler);
+ addJSONHandler("/rest/jobs/*", new JobsRESTAPIFunction(ccs));
+ addJSONHandler("/rest/nodes", new NodesRESTAPIFunction(ccs));
+ addJSONHandler("/rest/statedump", new StateDumpRESTAPIFunction(ccs));
+ /* TODO(tillw)
addHandler(createAdminConsoleHandler());
addHandler(createStaticResourcesHandler());
+ /*
/** the service of uploading/downloading deployment jars */
+ /* TODO(tillw)
handler = new ContextHandler("/applications");
handler.setHandler(new ApplicationInstallationHandler(ccs));
addHandler(handler);
+ */
+ }
+
+ private void addJSONHandler(String path, IJSONOutputFunction fn) {
+ server.addLet(new JSONOutputRequestHandler(ctx, new String[] { path },
fn));
}
private Handler createAdminConsoleHandler() {
@@ -102,23 +102,15 @@
return handler;
}
- public void setPort(int port) {
- connector.setPort(port);
- }
-
public int getListeningPort() {
- return connector.getLocalPort();
+ return listeningPort;
}
public void start() throws Exception {
- server.start();
+ webMgr.start();
}
public void stop() throws Exception {
- server.stop();
- }
-
- public void addHandler(Handler handler) {
- handlerCollection.addHandler(handler);
+ webMgr.stop();
}
}
diff --git
a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/web/util/JSONOutputRequestHandler.java
b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/web/util/JSONOutputRequestHandler.java
index e736406..88283d0 100644
---
a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/web/util/JSONOutputRequestHandler.java
+++
b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/web/util/JSONOutputRequestHandler.java
@@ -18,42 +18,52 @@
*/
package org.apache.hyracks.control.cc.web.util;
-import java.io.IOException;
+import java.util.concurrent.ConcurrentMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
+import org.apache.hyracks.http.api.IServlet;
+import org.apache.hyracks.http.api.IServletRequest;
+import org.apache.hyracks.http.api.IServletResponse;
+import org.apache.hyracks.http.server.AbstractServlet;
+import org.apache.hyracks.http.server.util.ServletUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
-import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.handler.AbstractHandler;
-public class JSONOutputRequestHandler extends AbstractHandler {
+import io.netty.handler.codec.http.HttpMethod;
+import io.netty.handler.codec.http.HttpResponseStatus;
+
+public class JSONOutputRequestHandler extends AbstractServlet {
+
+ private static final Logger LOGGER =
Logger.getLogger(JSONOutputRequestHandler.class.getName());
private final IJSONOutputFunction fn;
- public JSONOutputRequestHandler(IJSONOutputFunction fn) {
+ public JSONOutputRequestHandler(ConcurrentMap<String, Object> ctx,
String[] paths, IJSONOutputFunction fn) {
+ super(ctx, paths);
this.fn = fn;
}
@Override
- public void handle(String target, Request baseRequest, HttpServletRequest
request, HttpServletResponse response)
- throws IOException, ServletException {
- while (target.startsWith("/")) {
- target = target.substring(1);
+ public void handle(IServletRequest request, IServletResponse response) {
+ if (request.getHttpRequest().method() != HttpMethod.GET) {
+ response.setStatus(HttpResponseStatus.METHOD_NOT_ALLOWED);
+ return;
}
- while (target.endsWith("/")) {
- target = target.substring(0, target.length() - 1);
+ String path = path(request);
+ while (path.startsWith("/")) {
+ path = path.substring(1);
}
- String[] parts = target.split("/");
+ String[] parts = path.split("/");
try {
ObjectNode result = fn.invoke(parts);
- response.setContentType("application/json");
+ ServletUtils.setContentType(response,
IServlet.ContentType.APPLICATION_JSON, IServlet.Encoding.UTF8);
ObjectMapper om = new ObjectMapper();
- om.writer().writeValue(response.getWriter(),result);
- baseRequest.setHandled(true);
+ om.writer().writeValue(response.writer(), result);
} catch (Exception e) {
- e.printStackTrace();
+ LOGGER.log(Level.WARNING, "Unhandled Exception thrown from " +
getClass().getName(), e);
+ response.setStatus(HttpResponseStatus.BAD_REQUEST);
+ response.writer().print(e.getMessage());
}
}
}
diff --git a/hyracks-fullstack/hyracks/hyracks-http/pom.xml
b/hyracks-fullstack/hyracks/hyracks-http/pom.xml
index 8dc57a2..fb2a39d 100644
--- a/hyracks-fullstack/hyracks/hyracks-http/pom.xml
+++ b/hyracks-fullstack/hyracks/hyracks-http/pom.xml
@@ -28,7 +28,10 @@
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
- <version>4.1.6.Final</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
diff --git
a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/AbstractServlet.java
b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/AbstractServlet.java
index 7d24994..dd38911 100644
---
a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/AbstractServlet.java
+++
b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/AbstractServlet.java
@@ -18,6 +18,7 @@
*/
package org.apache.hyracks.http.server;
+import java.util.Arrays;
import java.util.concurrent.ConcurrentMap;
import org.apache.hyracks.http.api.IServlet;
@@ -69,4 +70,9 @@
}
return request.getHttpRequest().uri().substring(trim);
}
+
+ @Override
+ public String toString() {
+ return this.getClass().getSimpleName() + Arrays.toString(paths);
+ }
}
diff --git
a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/StaticResourceServlet.java
b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/StaticResourceServlet.java
new file mode 100644
index 0000000..5f9bb68
--- /dev/null
+++
b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/StaticResourceServlet.java
@@ -0,0 +1,100 @@
+/*
+ * 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.hyracks.http.server;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.concurrent.ConcurrentMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.hyracks.http.api.IServlet;
+import org.apache.hyracks.http.api.IServletRequest;
+import org.apache.hyracks.http.api.IServletResponse;
+
+import io.netty.handler.codec.http.HttpMethod;
+import org.apache.commons.io.IOUtils;
+import io.netty.handler.codec.http.HttpResponseStatus;
+import org.apache.hyracks.http.server.util.ServletUtils;
+
+public class StaticResourceServlet extends AbstractServlet {
+
+ private static final Logger LOGGER =
Logger.getLogger(StaticResourceServlet.class.getName());
+
+ public StaticResourceServlet(ConcurrentMap<String, Object> ctx, String[]
paths) {
+ super(ctx, paths);
+ }
+
+ @Override
+ public void handle(IServletRequest request, IServletResponse response) {
+ try {
+ if (request.getHttpRequest().method() == HttpMethod.GET) {
+ doGet(request, response);
+ } else if (request.getHttpRequest().method() == HttpMethod.POST) {
+ doPost(request, response);
+ } else {
+ response.setStatus(HttpResponseStatus.METHOD_NOT_ALLOWED);
+ }
+ } catch (IOException e) {
+ LOGGER.log(Level.WARNING, "Failure setting content type", e);
+ response.setStatus(HttpResponseStatus.INTERNAL_SERVER_ERROR);
+ }
+ }
+
+ protected void doGet(IServletRequest request, IServletResponse response)
throws IOException {
+ String resourcePath = request.getHttpRequest().uri();
+ deliverResource(resourcePath, response);
+ }
+
+ protected void deliverResource(String resourcePath, IServletResponse
response) throws IOException {
+ response.setStatus(HttpResponseStatus.OK);
+ try (InputStream is =
StaticResourceServlet.class.getResourceAsStream(resourcePath)) {
+ if (is == null) {
+ response.setStatus(HttpResponseStatus.NOT_FOUND);
+ return;
+ }
+ int i = resourcePath.lastIndexOf('.');
+ if (i >= 0) {
+ String extension = resourcePath.substring(i);
+ String mime = ContentType.mime(extension);
+ if (mime != null) {
+ OutputStream out = response.outputStream();
+ ServletUtils.setContentType(response, mime);
+ try {
+ IOUtils.copy(is, out);
+ } catch (Exception e) {
+ LOGGER.log(Level.WARNING, "Failure copying response",
e);
+ } finally {
+ if (out != null) {
+ IOUtils.closeQuietly(out);
+ }
+ IOUtils.closeQuietly(is);
+ }
+ return;
+ }
+ }
+ response.setStatus(HttpResponseStatus.BAD_REQUEST);
+ }
+ }
+
+ protected void doPost(IServletRequest request, IServletResponse response)
throws IOException {
+ response.setStatus(HttpResponseStatus.METHOD_NOT_ALLOWED);
+ }
+}
diff --git a/hyracks-fullstack/pom.xml b/hyracks-fullstack/pom.xml
index 5ddbf92..f972818 100644
--- a/hyracks-fullstack/pom.xml
+++ b/hyracks-fullstack/pom.xml
@@ -84,6 +84,11 @@
<version>${jetty.version}</version>
</dependency>
<dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-all</artifactId>
+ <version>4.1.6.Final</version>
+ </dependency>
+ <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
--
To view, visit https://asterix-gerrit.ics.uci.edu/1508
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ifcd240591d12baab2db4ce3163c635a1dde5c4ba
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Till Westmann <[email protected]>