diff --git a/examples/webserver/streaming/pom.xml b/examples/webserver/streaming/pom.xml
index e955bae4391..d352915039c 100644
--- a/examples/webserver/streaming/pom.xml
+++ b/examples/webserver/streaming/pom.xml
@@ -55,6 +55,16 @@
junit-jupiter-api
test
+
+ io.helidon.webserver.testing.junit5
+ helidon-webserver-testing-junit5
+ test
+
+
+ io.helidon.webclient
+ helidon-webclient
+ test
+
org.hamcrest
hamcrest-all
diff --git a/examples/webserver/streaming/src/main/java/io/helidon/examples/webserver/streaming/Main.java b/examples/webserver/streaming/src/main/java/io/helidon/examples/webserver/streaming/Main.java
index 6f4771b8e18..dc587a7e638 100644
--- a/examples/webserver/streaming/src/main/java/io/helidon/examples/webserver/streaming/Main.java
+++ b/examples/webserver/streaming/src/main/java/io/helidon/examples/webserver/streaming/Main.java
@@ -25,8 +25,6 @@
*/
public class Main {
- static final String LARGE_FILE_PATH = "target/classes/large-file.bin";
-
private Main() {
}
diff --git a/examples/webserver/streaming/src/main/java/io/helidon/examples/webserver/streaming/StreamingService.java b/examples/webserver/streaming/src/main/java/io/helidon/examples/webserver/streaming/StreamingService.java
index c5d256effe9..13899883cfe 100644
--- a/examples/webserver/streaming/src/main/java/io/helidon/examples/webserver/streaming/StreamingService.java
+++ b/examples/webserver/streaming/src/main/java/io/helidon/examples/webserver/streaming/StreamingService.java
@@ -16,12 +16,10 @@
package io.helidon.examples.webserver.streaming;
-import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.logging.Logger;
@@ -40,11 +38,9 @@ public class StreamingService implements HttpService {
// Last file uploaded (or default). Since we don't do any locking
// when operating on the file this example is not safe for concurrent requests.
- private volatile File file;
+ private volatile Path filePath;
StreamingService() {
- // Default download file;
- file = Paths.get(Main.LARGE_FILE_PATH).toFile();
}
@Override
@@ -58,28 +54,27 @@ private void upload(ServerRequest request, ServerResponse response) {
try {
Path tempFilePath = Files.createTempFile("large-file", ".tmp");
Files.copy(request.content().inputStream(), tempFilePath, StandardCopyOption.REPLACE_EXISTING);
- file = tempFilePath.toFile();
+ filePath = tempFilePath;
response.send("File was stored as " + tempFilePath);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
- LOGGER.info("Exiting upload after uploading " + file.length() + " bytes...");
+ LOGGER.info("Exiting upload after uploading " + filePath.toFile().length() + " bytes...");
}
private void download(ServerRequest request, ServerResponse response) {
LOGGER.info("Entering download ..." + Thread.currentThread());
- if (!file.canRead()) {
- LOGGER.warning("Can't read file " + file.getAbsolutePath());
- response.status(Status.INTERNAL_SERVER_ERROR_500).send();
+ if (filePath == null) {
+ response.status(Status.BAD_REQUEST_400).send("No file to download. Please upload file first.");
return;
}
- long length = file.length();
+ long length = filePath.toFile().length();
response.headers().contentLength(length);
try {
- Files.copy(file.toPath(), response.outputStream());
+ Files.copy(filePath, response.outputStream());
} catch (IOException e) {
throw new UncheckedIOException(e);
}
LOGGER.info("Exiting download after serving " + length + " bytes...");
}
-}
+}
\ No newline at end of file
diff --git a/examples/webserver/streaming/src/test/java/io/helidon/examples/webserver/streaming/MainTest.java b/examples/webserver/streaming/src/test/java/io/helidon/examples/webserver/streaming/MainTest.java
new file mode 100644
index 00000000000..50ada67ebe6
--- /dev/null
+++ b/examples/webserver/streaming/src/test/java/io/helidon/examples/webserver/streaming/MainTest.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License 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 io.helidon.examples.webserver.streaming;
+
+import io.helidon.http.Status;
+import io.helidon.webclient.http1.Http1Client;
+import io.helidon.webclient.http1.Http1ClientResponse;
+import io.helidon.webserver.http.HttpRouting;
+import io.helidon.webserver.testing.junit5.ServerTest;
+import io.helidon.webserver.testing.junit5.SetUpRoute;
+
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Order;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+@ServerTest
+@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
+class MainTest {
+
+ private final Http1Client client;
+
+ private final String TEST_DATA_1 = "Test Data 1";
+ private final String TEST_DATA_2 = "Test Data 2";
+
+ protected MainTest(Http1Client client) {
+ this.client = client;
+ }
+
+ @SetUpRoute
+ static void routing(HttpRouting.Builder builder) {
+ Main.routing(builder);
+ }
+
+ @Test
+ @Order(0)
+ void testBadRequest() {
+ try (Http1ClientResponse response = client.get("/download").request()) {
+ assertThat(response.status(), is(Status.BAD_REQUEST_400));
+ }
+ }
+
+ @Test
+ @Order(1)
+ void testUpload1() {
+ try (Http1ClientResponse response = client.post("/upload").submit(TEST_DATA_1)) {
+ assertThat(response.status(), is(Status.OK_200));
+ }
+ }
+
+ @Test
+ @Order(2)
+ void testDownload1() {
+ try (Http1ClientResponse response = client.get("/download").request()) {
+ assertThat(response.status(), is(Status.OK_200));
+ assertThat(response.as(String.class), is(TEST_DATA_1));
+ }
+ }
+
+ @Test
+ @Order(3)
+ void testUpload2() {
+ try (Http1ClientResponse response = client.post("/upload").submit(TEST_DATA_2)) {
+ assertThat(response.status(), is(Status.OK_200));
+ }
+ }
+
+ @Test
+ @Order(4)
+ void testDownload2() {
+ try (Http1ClientResponse response = client.get("/download").request()) {
+ assertThat(response.status(), is(Status.OK_200));
+ assertThat(response.as(String.class), is(TEST_DATA_2));
+ }
+ }
+}