Michael Blow has submitted this change and it was merged. Change subject: Merge commit '6312edf' from 'stabilization-f69489' into 'master' ......................................................................
Merge commit '6312edf' from 'stabilization-f69489' into 'master' Change-Id: I6f2daa3ab112d8cb9210ed94db812ac1743bce58 --- M asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NetDiagnosticsApiServlet.java M asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java M hyracks-fullstack/hyracks/hyracks-http/pom.xml M hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/ChunkedResponse.java M hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/FullResponse.java M hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/utils/HttpUtil.java M hyracks-fullstack/hyracks/hyracks-http/src/test/java/org/apache/hyracks/http/PipelinedRequestsTest.java D hyracks-fullstack/hyracks/hyracks-http/src/test/java/org/apache/hyracks/http/test/HttpServerTest.java M hyracks-fullstack/hyracks/hyracks-http/src/test/java/org/apache/hyracks/test/http/HttpServerTest.java R hyracks-fullstack/hyracks/hyracks-http/src/test/java/org/apache/hyracks/test/http/servlet/EchoServlet.java 10 files changed, 50 insertions(+), 474 deletions(-) Approvals: Jenkins: Verified; ; Verified Michael Blow: Looks good to me, approved Objections: Jenkins: Violations found diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NetDiagnosticsApiServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NetDiagnosticsApiServlet.java index badb568..ffcb74d 100644 --- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NetDiagnosticsApiServlet.java +++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NetDiagnosticsApiServlet.java @@ -47,7 +47,7 @@ @Override protected void get(IServletRequest request, IServletResponse response) throws IOException { - HttpUtil.setContentType(response, HttpUtil.ContentType.APPLICATION_JSON, HttpUtil.Encoding.UTF8); + HttpUtil.setContentType(response, HttpUtil.ContentType.APPLICATION_JSON, request); response.setStatus(HttpResponseStatus.OK); final JsonNode netDiagnostics = getNetDiagnostics(); final PrintWriter responseWriter = response.writer(); diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java index de547bb..31b784f 100644 --- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java +++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java @@ -122,7 +122,7 @@ } @Override - protected void post(IServletRequest request, IServletResponse response) { + protected void post(IServletRequest request, IServletResponse response) throws IOException { handleRequest(request, response); } @@ -509,28 +509,14 @@ return "http://" + host + path + handlePath(delivery); } - private void handleRequest(IServletRequest request, IServletResponse response) { + private void handleRequest(IServletRequest request, IServletResponse response) throws IOException { final IRequestReference requestRef = receptionist.welcome(request); long elapsedStart = System.nanoTime(); -<<<<<<< HEAD (47d2f3 [NO ISSUE][OTH] Add API To Ensure Request Requirements) long errorCount = 1; -======= - HttpUtil.setContentType(response, HttpUtil.ContentType.APPLICATION_JSON, request); - final PrintWriter httpWriter = response.writer(); - - ResultDelivery delivery = parseResultDelivery(param.getMode()); - - final ResultProperties resultProperties = param.getMaxResultReads() == null ? new ResultProperties(delivery) - : new ResultProperties(delivery, Long.parseLong(param.getMaxResultReads())); - - String handleUrl = getHandleUrl(param.getHost(), param.getPath(), delivery); - SessionOutput sessionOutput = createSessionOutput(param, handleUrl, httpWriter); - SessionConfig sessionConfig = sessionOutput.config(); - ->>>>>>> BRANCH (6312ed [NO ISSUE][HTTP] Character encoding fixes) Stats stats = new Stats(); RequestExecutionState execution = new RequestExecutionState(); List<ExecutionWarning> warnings = Collections.emptyList(); + HttpUtil.setContentType(response, HttpUtil.ContentType.APPLICATION_JSON, request); PrintWriter httpWriter = response.writer(); SessionOutput sessionOutput = createSessionOutput(httpWriter); QueryServiceRequestParameters param = new QueryServiceRequestParameters(); @@ -538,7 +524,6 @@ // buffer the output until we are ready to set the status of the response message correctly sessionOutput.hold(); sessionOutput.out().print("{\n"); - HttpUtil.setContentType(response, HttpUtil.ContentType.APPLICATION_JSON, HttpUtil.Encoding.UTF8); Map<String, String> optionalParams = null; if (optionalParamProvider != null) { optionalParams = optionalParamProvider.apply(request); diff --git a/hyracks-fullstack/hyracks/hyracks-http/pom.xml b/hyracks-fullstack/hyracks/hyracks-http/pom.xml index 38e7f49..b6dee00 100644 --- a/hyracks-fullstack/hyracks/hyracks-http/pom.xml +++ b/hyracks-fullstack/hyracks/hyracks-http/pom.xml @@ -89,8 +89,6 @@ <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> </dependency> -<<<<<<< HEAD (47d2f3 [NO ISSUE][OTH] Add API To Ensure Request Requirements) -======= <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-all</artifactId> @@ -103,6 +101,5 @@ <type>test-jar</type> <scope>test</scope> </dependency> ->>>>>>> BRANCH (6312ed [NO ISSUE][HTTP] Character encoding fixes) </dependencies> </project> \ No newline at end of file diff --git a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/ChunkedResponse.java b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/ChunkedResponse.java index b1d6ac9..2b2bdef 100644 --- a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/ChunkedResponse.java +++ b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/ChunkedResponse.java @@ -68,14 +68,9 @@ private static final Logger LOGGER = LogManager.getLogger(); private final ChannelHandlerContext ctx; private final ChunkedNettyOutputStream outputStream; -<<<<<<< HEAD (47d2f3 [NO ISSUE][OTH] Add API To Ensure Request Requirements) - private final PrintWriter writer; private final HttpServerHandler<?> handler; - private DefaultHttpResponse response; -======= private PrintWriter writer; - private HttpResponse response; ->>>>>>> BRANCH (6312ed [NO ISSUE][HTTP] Character encoding fixes) + private DefaultHttpResponse response; private boolean headerSent; private ByteBuf error; private ChannelFuture future; diff --git a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/FullResponse.java b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/FullResponse.java index e8a6e1c..f1ff92c 100644 --- a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/FullResponse.java +++ b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/FullResponse.java @@ -44,15 +44,9 @@ public class FullResponse implements IServletResponse { private final ChannelHandlerContext ctx; private final ByteArrayOutputStream baos; -<<<<<<< HEAD (47d2f3 [NO ISSUE][OTH] Add API To Ensure Request Requirements) - private final PrintWriter writer; private final DefaultFullHttpResponse response; private final HttpServerHandler<?> handler; -======= - private final FullHttpResponse response; - private final boolean keepAlive; private PrintWriter writer; ->>>>>>> BRANCH (6312ed [NO ISSUE][HTTP] Character encoding fixes) private ChannelFuture future; public FullResponse(HttpServerHandler<?> handler, ChannelHandlerContext ctx, FullHttpRequest request) { diff --git a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/utils/HttpUtil.java b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/utils/HttpUtil.java index 50df784..1a51318 100644 --- a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/utils/HttpUtil.java +++ b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/utils/HttpUtil.java @@ -174,12 +174,12 @@ return clusterURL; } -<<<<<<< HEAD (47d2f3 [NO ISSUE][OTH] Add API To Ensure Request Requirements) public static void setConnectionHeader(HttpRequest request, DefaultHttpResponse response) { final boolean keepAlive = io.netty.handler.codec.http.HttpUtil.isKeepAlive(request); final AsciiString connectionHeaderValue = keepAlive ? HttpHeaderValues.KEEP_ALIVE : HttpHeaderValues.CLOSE; response.headers().set(HttpHeaderNames.CONNECTION, connectionHeaderValue); -======= + } + public static String getPreferredCharset(IServletRequest request) { return getPreferredCharset(request, DEFAULT_RESPONSE_CHARSET); } @@ -252,6 +252,5 @@ public int hashCode() { return Objects.hash(value, weight); } ->>>>>>> BRANCH (6312ed [NO ISSUE][HTTP] Character encoding fixes) } } diff --git a/hyracks-fullstack/hyracks/hyracks-http/src/test/java/org/apache/hyracks/http/PipelinedRequestsTest.java b/hyracks-fullstack/hyracks/hyracks-http/src/test/java/org/apache/hyracks/http/PipelinedRequestsTest.java index 0c96eb6..c0117f1 100644 --- a/hyracks-fullstack/hyracks/hyracks-http/src/test/java/org/apache/hyracks/http/PipelinedRequestsTest.java +++ b/hyracks-fullstack/hyracks/hyracks-http/src/test/java/org/apache/hyracks/http/PipelinedRequestsTest.java @@ -52,7 +52,7 @@ import org.apache.hyracks.http.server.HttpServerConfigBuilder; import org.apache.hyracks.http.server.InterruptOnCloseHandler; import org.apache.hyracks.http.server.WebManager; -import org.apache.hyracks.http.servlet.SleepyServlet; +import org.apache.hyracks.test.http.servlet.SleepyServlet; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.junit.Assert; diff --git a/hyracks-fullstack/hyracks/hyracks-http/src/test/java/org/apache/hyracks/http/test/HttpServerTest.java b/hyracks-fullstack/hyracks/hyracks-http/src/test/java/org/apache/hyracks/http/test/HttpServerTest.java deleted file mode 100644 index 2acf868..0000000 --- a/hyracks-fullstack/hyracks/hyracks-http/src/test/java/org/apache/hyracks/http/test/HttpServerTest.java +++ /dev/null @@ -1,433 +0,0 @@ -<<<<<<< HEAD (47d2f3 [NO ISSUE][OTH] Add API To Ensure Request Requirements) -/* - * 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.test; - -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.lang.reflect.Field; -import java.net.InetAddress; -import java.net.Socket; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.atomic.AtomicInteger; - -import org.apache.commons.lang3.RandomStringUtils; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.util.EntityUtils; -import org.apache.hyracks.http.HttpTestUtil; -import org.apache.hyracks.http.server.HttpServer; -import org.apache.hyracks.http.server.HttpServerConfig; -import org.apache.hyracks.http.server.HttpServerConfigBuilder; -import org.apache.hyracks.http.server.InterruptOnCloseHandler; -import org.apache.hyracks.http.server.WebManager; -import org.apache.hyracks.http.servlet.ChattyServlet; -import org.apache.hyracks.http.servlet.EchoServlet; -import org.apache.hyracks.http.servlet.SleepyServlet; -import org.apache.hyracks.util.StorageUtil; -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import io.netty.channel.Channel; -import io.netty.handler.codec.http.HttpResponseStatus; - -public class HttpServerTest { - private static final Logger LOGGER = LogManager.getLogger(); - static final boolean PRINT_TO_CONSOLE = false; - static final int PORT = 9898; - static final String HOST = "localhost"; - static final String PROTOCOL = "http"; - static final String PATH = "/"; - static final AtomicInteger SUCCESS_COUNT = new AtomicInteger(); - static final AtomicInteger UNAVAILABLE_COUNT = new AtomicInteger(); - static final AtomicInteger OTHER_COUNT = new AtomicInteger(); - static final AtomicInteger EXCEPTION_COUNT = new AtomicInteger(); - static final List<HttpRequestTask> TASKS = new ArrayList<>(); - static final List<Future<Void>> FUTURES = new ArrayList<>(); - static final ExecutorService executor = Executors.newCachedThreadPool(); - - @Before - public void setUp() { - SUCCESS_COUNT.set(0); - UNAVAILABLE_COUNT.set(0); - OTHER_COUNT.set(0); - EXCEPTION_COUNT.set(0); - FUTURES.clear(); - TASKS.clear(); - } - - @Test - public void testOverloadingServer() throws Exception { - WebManager webMgr = new WebManager(); - int numExecutors = 16; - int serverQueueSize = 16; - int numRequests = 128; - final HttpServerConfig config = HttpServerConfigBuilder.custom().setThreadCount(numExecutors) - .setRequestQueueSize(serverQueueSize).build(); - HttpServer server = new HttpServer(webMgr.getBosses(), webMgr.getWorkers(), PORT, config); - SleepyServlet servlet = new SleepyServlet(server.ctx(), new String[] { PATH }); - server.addServlet(servlet); - webMgr.add(server); - webMgr.start(); - int expectedSuccess = numExecutors + serverQueueSize; - int expectedUnavailable = numRequests - expectedSuccess; - try { - request(expectedSuccess); - waitTillQueued(server, serverQueueSize); - ArrayList<Future<Void>> successSet = started(); - request(expectedUnavailable); - ArrayList<Future<Void>> rejectedSet = started(); - for (Future<Void> f : rejectedSet) { - f.get(); - } - servlet.wakeUp(); - for (Future<Void> f : successSet) { - f.get(); - } - Assert.assertEquals(expectedSuccess, SUCCESS_COUNT.get()); - Assert.assertEquals(expectedUnavailable, UNAVAILABLE_COUNT.get() + EXCEPTION_COUNT.get()); - System.err.println("Number of rejections: " + UNAVAILABLE_COUNT.get()); - System.err.println("Number of exceptions: " + EXCEPTION_COUNT.get()); - Assert.assertEquals(0, OTHER_COUNT.get()); - } catch (Throwable th) { - th.printStackTrace(); - throw th; - } finally { - webMgr.stop(); - } - } - - private void waitTillQueued(HttpServer server, int expectedQueued) throws Exception { - int maxAttempts = 15; - int attempt = 0; - int queued = server.getWorkQueueSize(); - while (queued != expectedQueued) { - attempt++; - if (attempt > maxAttempts) { - throw new Exception("Number of queued requests (" + queued + ") didn't match the expected number (" - + expectedQueued + ")"); - } - Thread.sleep(1000); // NOSONAR polling is the clean way - queued = server.getWorkQueueSize(); - } - } - - @Test - public void testReleaseRejectedRequest() throws Exception { - WebManager webMgr = new WebManager(); - int numRequests = 64; - int numExecutors = 2; - int serverQueueSize = 2; - int numPatches = 60; - final HttpServerConfig config = HttpServerConfigBuilder.custom().setThreadCount(numExecutors) - .setRequestQueueSize(serverQueueSize).build(); - HttpServer server = new HttpServer(webMgr.getBosses(), webMgr.getWorkers(), PORT, config); - SleepyServlet servlet = new SleepyServlet(server.ctx(), new String[] { PATH }); - server.addServlet(servlet); - webMgr.add(server); - webMgr.start(); - request(numExecutors + serverQueueSize); - ArrayList<Future<Void>> stuck = started(); - waitTillQueued(server, serverQueueSize); - try { - try { - for (int i = 0; i < numPatches; i++) { - HttpTestUtil.printMemUsage(); - request(numRequests); - for (Future<Void> f : FUTURES) { - f.get(); - } - FUTURES.clear(); - } - } finally { - HttpTestUtil.printMemUsage(); - servlet.wakeUp(); - for (Future<Void> f : stuck) { - f.get(); - } - } - } finally { - System.err.println("Number of rejections: " + UNAVAILABLE_COUNT.get()); - System.err.println("Number of exceptions: " + EXCEPTION_COUNT.get()); - webMgr.stop(); - HttpTestUtil.printMemUsage(); - } - } - - private ArrayList<Future<Void>> started() { - ArrayList<Future<Void>> started = new ArrayList<>(FUTURES); - FUTURES.clear(); - return started; - } - - @Test - public void testChattyServer() throws Exception { - int numRequests = 48; - int numExecutors = 24; - int serverQueueSize = 24; - HttpTestUtil.printMemUsage(); - WebManager webMgr = new WebManager(); - final HttpServerConfig config = HttpServerConfigBuilder.custom().setThreadCount(numExecutors) - .setRequestQueueSize(serverQueueSize).build(); - HttpServer server = new HttpServer(webMgr.getBosses(), webMgr.getWorkers(), PORT, config); - ChattyServlet servlet = new ChattyServlet(server.ctx(), new String[] { PATH }); - server.addServlet(servlet); - webMgr.add(server); - webMgr.start(); - try { - request(numRequests); - for (Future<Void> thread : FUTURES) { - thread.get(); - } - Assert.assertEquals(numRequests, SUCCESS_COUNT.get()); - Assert.assertEquals(0, UNAVAILABLE_COUNT.get()); - Assert.assertEquals(0, OTHER_COUNT.get()); - } finally { - HttpTestUtil.printMemUsage(); - webMgr.stop(); - HttpTestUtil.printMemUsage(); - } - } - - @Test - public void testMalformedString() throws Exception { - int numExecutors = 16; - int serverQueueSize = 16; - WebManager webMgr = new WebManager(); - final HttpServerConfig config = HttpServerConfigBuilder.custom().setThreadCount(numExecutors) - .setRequestQueueSize(serverQueueSize).build(); - HttpServer server = new HttpServer(webMgr.getBosses(), webMgr.getWorkers(), PORT, config); - SleepyServlet servlet = new SleepyServlet(server.ctx(), new String[] { PATH }); - server.addServlet(servlet); - webMgr.add(server); - webMgr.start(); - try { - StringBuilder response = new StringBuilder(); - try (Socket s = new Socket(InetAddress.getLocalHost(), PORT)) { - PrintWriter pw = new PrintWriter(s.getOutputStream()); - pw.println("GET /?handle=%7B%22handle%22%3A%5B0%2C%200%5D%7 HTTP/1.1"); - pw.println("Host: 127.0.0.1"); - pw.println(); - pw.flush(); - BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())); - String line; - while ((line = br.readLine()) != null && !line.isEmpty()) { - response.append(line).append('\n'); - } - br.close(); - } - String output = response.toString(); - Assert.assertTrue(output.contains(HttpResponseStatus.BAD_REQUEST.toString())); - } catch (Exception e) { - e.printStackTrace(); - throw e; - } finally { - webMgr.stop(); - } - } - - @Test - public void testServerRevival() throws Exception { - int numExecutors = 16; - int serverQueueSize = 16; - int numRequests = 1; - WebManager webMgr = new WebManager(); - final HttpServerConfig config = HttpServerConfigBuilder.custom().setThreadCount(numExecutors) - .setRequestQueueSize(serverQueueSize).build(); - HttpServer server = new HttpServer(webMgr.getBosses(), webMgr.getWorkers(), PORT, config); - ChattyServlet servlet = new ChattyServlet(server.ctx(), new String[] { PATH }); - server.addServlet(servlet); - webMgr.add(server); - webMgr.start(); - try { - // send a request - request(numRequests); - for (Future<Void> thread : FUTURES) { - thread.get(); - } - Assert.assertEquals(numRequests, SUCCESS_COUNT.get()); - // close the channel - Field channelField = server.getClass().getDeclaredField("channel"); - channelField.setAccessible(true); - Field recoveryThreadField = server.getClass().getDeclaredField("recoveryThread"); - recoveryThreadField.setAccessible(true); - Channel channel = (Channel) channelField.get(server); - channel.close(); - Thread.sleep(1000); - final int sleeps = 10; - for (int i = 0; i < sleeps; i++) { - Thread thread = (Thread) recoveryThreadField.get(server); - if (thread == null) { - break; - } - LOGGER.log(Level.WARN, - "Attempt #" + (i + 1) + ". Recovery thread is not null and has id " + thread.getId()); - if (i == sleeps - 1) { - throw new Exception("Http server recovery didn't complete after " + sleeps + "s"); - } - Thread.sleep(1000); - } - for (int i = 0; i < sleeps; i++) { - request(1); - for (Future<Void> thread : FUTURES) { - thread.get(); - } - if (numRequests + 1 == SUCCESS_COUNT.get()) { - break; - } else if (i == sleeps - 1) { - throw new Exception( - "Http server couldn't process requests correctly after recovery for " + sleeps + "s"); - } - } - } finally { - webMgr.stop(); - } - } - - @Test - public void testInterruptOnClientClose() throws Exception { - WebManager webMgr = new WebManager(); - int numExecutors = 1; - int queueSize = 1; - final HttpServerConfig config = - HttpServerConfigBuilder.custom().setThreadCount(numExecutors).setRequestQueueSize(queueSize).build(); - HttpServer server = - new HttpServer(webMgr.getBosses(), webMgr.getWorkers(), PORT, config, InterruptOnCloseHandler.INSTANCE); - SleepyServlet servlet = new SleepyServlet(server.ctx(), new String[] { PATH }); - server.addServlet(servlet); - webMgr.add(server); - webMgr.start(); - try { - request(1); - synchronized (servlet) { - while (servlet.getNumSlept() == 0) { - servlet.wait(); - } - } - request(1); - waitTillQueued(server, 1); - FUTURES.remove(0); - HttpRequestTask request = TASKS.remove(0); - request.request.abort(); - waitTillQueued(server, 0); - synchronized (servlet) { - while (servlet.getNumSlept() == 1) { - servlet.wait(); - } - } - servlet.wakeUp(); - for (Future<Void> f : FUTURES) { - f.get(); - } - FUTURES.clear(); - } finally { - webMgr.stop(); - } - } - - @Test - public void testLargeRequest() throws Exception { - WebManager webMgr = new WebManager(); - // Server with max allowed request size = 512K - final int maxRequestSize = StorageUtil.getIntSizeInBytes(512, StorageUtil.StorageUnit.KILOBYTE); - final HttpServerConfig config = HttpServerConfigBuilder.custom().setMaxRequestSize(maxRequestSize).build(); - HttpServer server = new HttpServer(webMgr.getBosses(), webMgr.getWorkers(), PORT, config); - ChattyServlet servlet = new ChattyServlet(server.ctx(), new String[] { PATH }); - server.addServlet(servlet); - webMgr.add(server); - webMgr.start(); - Exception failure = null; - try { - request(1, maxRequestSize + 1); - for (Future<Void> thread : FUTURES) { - thread.get(); - } - } catch (Exception e) { - failure = e; - } finally { - webMgr.stop(); - } - Assert.assertNotNull(failure); - } - - public static void setPrivateField(Object obj, String filedName, Object value) throws Exception { - Field f = obj.getClass().getDeclaredField(filedName); - f.setAccessible(true); - f.set(obj, value); - } - - @Test - public void chunkedRequestTest() throws Exception { - final WebManager webMgr = new WebManager(); - final int serverRequestChunkSize = StorageUtil.getIntSizeInBytes(1, StorageUtil.StorageUnit.KILOBYTE); - final HttpServerConfig config = HttpServerConfigBuilder.custom().setThreadCount(16).setRequestQueueSize(16) - .setMaxRequestChunkSize(serverRequestChunkSize).build(); - final HttpServer server = new HttpServer(webMgr.getBosses(), webMgr.getWorkers(), PORT, config); - EchoServlet servlet = new EchoServlet(server.ctx(), PATH); - server.addServlet(servlet); - webMgr.add(server); - webMgr.start(); - try (CloseableHttpClient httpClient = HttpClients.createDefault()) { - final URI uri = new URI(HttpServerTest.PROTOCOL, null, HttpServerTest.HOST, HttpServerTest.PORT, - HttpServerTest.PATH, null, null); - final HttpPost postRequest = new HttpPost(uri); - final int requestSize = StorageUtil.getIntSizeInBytes(8, StorageUtil.StorageUnit.KILOBYTE); - final String requestBody = RandomStringUtils.randomAlphanumeric(requestSize); - final StringEntity chunkedEntity = new StringEntity(requestBody); - chunkedEntity.setChunked(true); - postRequest.setEntity(chunkedEntity); - try (CloseableHttpResponse response = httpClient.execute(postRequest)) { - final String responseBody = EntityUtils.toString(response.getEntity()); - Assert.assertEquals(response.getStatusLine().getStatusCode(), HttpResponseStatus.OK.code()); - Assert.assertEquals(responseBody, requestBody); - } - } finally { - webMgr.stop(); - } - } - - private void request(int count) throws URISyntaxException { - request(count, 0); - } - - private void request(int count, int entitySize) throws URISyntaxException { - for (int i = 0; i < count; i++) { - HttpRequestTask requestTask = new HttpRequestTask(entitySize); - Future<Void> next = executor.submit(requestTask); - FUTURES.add(next); - TASKS.add(requestTask); - } - } -} -======= ->>>>>>> BRANCH (6312ed [NO ISSUE][HTTP] Character encoding fixes) diff --git a/hyracks-fullstack/hyracks/hyracks-http/src/test/java/org/apache/hyracks/test/http/HttpServerTest.java b/hyracks-fullstack/hyracks/hyracks-http/src/test/java/org/apache/hyracks/test/http/HttpServerTest.java index ea52b0b..e341e2f 100644 --- a/hyracks-fullstack/hyracks/hyracks-http/src/test/java/org/apache/hyracks/test/http/HttpServerTest.java +++ b/hyracks-fullstack/hyracks/hyracks-http/src/test/java/org/apache/hyracks/test/http/HttpServerTest.java @@ -24,6 +24,7 @@ import java.lang.reflect.Field; import java.net.InetAddress; import java.net.Socket; +import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.List; @@ -32,12 +33,20 @@ import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicInteger; +import org.apache.commons.lang3.RandomStringUtils; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; import org.apache.hyracks.http.server.HttpServer; import org.apache.hyracks.http.server.HttpServerConfig; import org.apache.hyracks.http.server.HttpServerConfigBuilder; import org.apache.hyracks.http.server.InterruptOnCloseHandler; import org.apache.hyracks.http.server.WebManager; import org.apache.hyracks.test.http.servlet.ChattyServlet; +import org.apache.hyracks.test.http.servlet.EchoServlet; import org.apache.hyracks.test.http.servlet.SleepyServlet; import org.apache.hyracks.util.StorageUtil; import org.apache.logging.log4j.Level; @@ -230,7 +239,7 @@ pw.flush(); BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())); String line; - while ((line = br.readLine()) != null) { + while ((line = br.readLine()) != null && !line.isEmpty()) { response.append(line).append('\n'); } br.close(); @@ -369,6 +378,36 @@ Assert.assertNotNull(failure); } + @Test + public void chunkedRequestTest() throws Exception { + final WebManager webMgr = new WebManager(); + final int serverRequestChunkSize = StorageUtil.getIntSizeInBytes(1, StorageUtil.StorageUnit.KILOBYTE); + final HttpServerConfig config = HttpServerConfigBuilder.custom().setThreadCount(16).setRequestQueueSize(16) + .setMaxRequestChunkSize(serverRequestChunkSize).build(); + final HttpServer server = new HttpServer(webMgr.getBosses(), webMgr.getWorkers(), PORT, config); + EchoServlet servlet = new EchoServlet(server.ctx(), PATH); + server.addServlet(servlet); + webMgr.add(server); + webMgr.start(); + try (CloseableHttpClient httpClient = HttpClients.createDefault()) { + final URI uri = new URI(HttpServerTest.PROTOCOL, null, HttpServerTest.HOST, HttpServerTest.PORT, + HttpServerTest.PATH, null, null); + final HttpPost postRequest = new HttpPost(uri); + final int requestSize = StorageUtil.getIntSizeInBytes(8, StorageUtil.StorageUnit.KILOBYTE); + final String requestBody = RandomStringUtils.randomAlphanumeric(requestSize); + final StringEntity chunkedEntity = new StringEntity(requestBody); + chunkedEntity.setChunked(true); + postRequest.setEntity(chunkedEntity); + try (CloseableHttpResponse response = httpClient.execute(postRequest)) { + final String responseBody = EntityUtils.toString(response.getEntity()); + Assert.assertEquals(response.getStatusLine().getStatusCode(), HttpResponseStatus.OK.code()); + Assert.assertEquals(responseBody, requestBody); + } + } finally { + webMgr.stop(); + } + } + private void request(int count) throws URISyntaxException { request(count, 0); } diff --git a/hyracks-fullstack/hyracks/hyracks-http/src/test/java/org/apache/hyracks/http/servlet/EchoServlet.java b/hyracks-fullstack/hyracks/hyracks-http/src/test/java/org/apache/hyracks/test/http/servlet/EchoServlet.java similarity index 95% rename from hyracks-fullstack/hyracks/hyracks-http/src/test/java/org/apache/hyracks/http/servlet/EchoServlet.java rename to hyracks-fullstack/hyracks/hyracks-http/src/test/java/org/apache/hyracks/test/http/servlet/EchoServlet.java index 9298aed..2da86f3 100644 --- a/hyracks-fullstack/hyracks/hyracks-http/src/test/java/org/apache/hyracks/http/servlet/EchoServlet.java +++ b/hyracks-fullstack/hyracks/hyracks-http/src/test/java/org/apache/hyracks/test/http/servlet/EchoServlet.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.hyracks.http.servlet; +package org.apache.hyracks.test.http.servlet; import java.util.concurrent.ConcurrentMap; @@ -40,7 +40,7 @@ protected void post(IServletRequest request, IServletResponse response) throws Exception { final String requestBody = HttpUtil.getRequestBody(request); response.setStatus(HttpResponseStatus.OK); - HttpUtil.setContentType(response, HttpUtil.ContentType.TEXT_PLAIN, HttpUtil.Encoding.UTF8); + HttpUtil.setContentType(response, HttpUtil.ContentType.TEXT_PLAIN, request); response.writer().write(requestBody); } } \ No newline at end of file -- To view, visit https://asterix-gerrit.ics.uci.edu/3190 To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings Gerrit-MessageType: merged Gerrit-Change-Id: I6f2daa3ab112d8cb9210ed94db812ac1743bce58 Gerrit-PatchSet: 2 Gerrit-Project: asterixdb Gerrit-Branch: master Gerrit-Owner: Michael Blow <mb...@apache.org> Gerrit-Reviewer: Anon. E. Moose #1000171 Gerrit-Reviewer: Jenkins <jenk...@fulliautomatix.ics.uci.edu> Gerrit-Reviewer: Michael Blow <mb...@apache.org>