books = BOOK_STORE.getAll();
+ switch (jsonLibrary) {
+ case JSONP:
+ response.send(BookMapper.encodeJsonp(books));
+ break;
+ case JSONB:
+ case JACKSON:
+ response.send(books);
+ break;
+ default:
+ throw new RuntimeException("Unknown JSON library " + jsonLibrary);
+ }
+ }
+
+ private void postBook(ServerRequest request, ServerResponse response) {
+ switch (jsonLibrary) {
+ case JSONP:
+ JsonObject jo = request.content().as(JsonObject.class);
+ addBook(BookMapper.decodeJsonp(jo), response);
+ break;
+ case JSONB:
+ case JACKSON:
+ Book book = request.content().as(Book.class);
+ addBook(book, response);
+ break;
+ default:
+ throw new RuntimeException("Unknown JSON library " + jsonLibrary);
+ }
+ }
+
+ private void addBook(Book book, ServerResponse response) {
+ if (BOOK_STORE.contains(book.getIsbn())) {
+ response.status(Http.Status.CONFLICT_409).send();
+ } else {
+ BOOK_STORE.store(book);
+ response.status(Http.Status.OK_200).send();
+ }
+ }
+
+ private void getBook(ServerRequest request, ServerResponse response) {
+ String isbn = request.path().pathParameters().value(ISBN_PARAM);
+ Book book = BOOK_STORE.find(isbn);
+
+ if (book == null) {
+ response.status(Http.Status.NOT_FOUND_404).send();
+ return;
+ }
+
+ switch (jsonLibrary) {
+ case JSONP:
+ response.send(BookMapper.encodeJsonp(book));
+ break;
+ case JSONB:
+ case JACKSON:
+ response.send(book);
+ break;
+ default:
+ throw new RuntimeException("Unknown JSON library " + jsonLibrary);
+ }
+ }
+
+ private void putBook(ServerRequest request, ServerResponse response) {
+ switch (jsonLibrary) {
+ case JSONP:
+ JsonObject jo = request.content().as(JsonObject.class);
+ updateBook(BookMapper.decodeJsonp(jo), response);
+ break;
+ case JSONB:
+ case JACKSON:
+ Book book = request.content().as(Book.class);
+ updateBook(book, response);
+ break;
+ default:
+ throw new RuntimeException("Unknown JSON library " + jsonLibrary);
+ }
+ }
+
+ private void updateBook(Book book, ServerResponse response) {
+ if (BOOK_STORE.contains(book.getIsbn())) {
+ BOOK_STORE.store(book);
+ response.status(Http.Status.OK_200).send();
+ } else {
+ response.status(Http.Status.NOT_FOUND_404).send();
+ }
+ }
+
+ private void deleteBook(ServerRequest request, ServerResponse response) {
+ String isbn = request.path().pathParameters().value(ISBN_PARAM);
+ if (BOOK_STORE.contains(isbn)) {
+ BOOK_STORE.remove(isbn);
+ response.send();
+ } else {
+ response.status(Http.Status.NOT_FOUND_404).send();
+ }
+ }
+}
diff --git a/tests/apps/bookstore/bookstore-nima/src/main/java/io/helidon/tests/apps/bookstore/nima/Main.java b/tests/apps/bookstore/bookstore-nima/src/main/java/io/helidon/tests/apps/bookstore/nima/Main.java
new file mode 100644
index 00000000000..d7075a2f4c1
--- /dev/null
+++ b/tests/apps/bookstore/bookstore-nima/src/main/java/io/helidon/tests/apps/bookstore/nima/Main.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2019, 2023 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.tests.apps.bookstore.nima;
+
+import io.helidon.common.configurable.Resource;
+import io.helidon.common.pki.KeyConfig;
+import io.helidon.config.Config;
+import io.helidon.health.checks.DeadlockHealthCheck;
+import io.helidon.health.checks.DiskSpaceHealthCheck;
+import io.helidon.health.checks.HeapMemoryHealthCheck;
+import io.helidon.logging.common.LogConfig;
+import io.helidon.nima.common.tls.Tls;
+import io.helidon.nima.observe.health.HealthFeature;
+import io.helidon.nima.observe.metrics.MetricsFeature;
+import io.helidon.nima.webserver.Routing;
+import io.helidon.nima.webserver.WebServer;
+import io.helidon.nima.webserver.http.HttpRouting;
+
+/**
+ * Simple Hello World rest application.
+ */
+public final class Main {
+
+ private static final String SERVICE_PATH = "/books";
+
+ enum JsonLibrary {
+ JSONP,
+ JSONB,
+ JACKSON
+ }
+
+ /**
+ * Cannot be instantiated.
+ */
+ private Main() {
+ }
+
+ /**
+ * Application main entry point.
+ *
+ * @param args command line arguments.
+ */
+ public static void main(final String[] args) {
+ startServer();
+ }
+
+ /**
+ * Start the server.
+ *
+ * @return the created {@link WebServer} instance
+ */
+ static WebServer startServer() {
+ return startServer(false, false, false);
+ }
+
+ /**
+ * Start the server.
+ *
+ * @param ssl Enable ssl support.
+ * @param http2 Enable http2 support.
+ * @return the created {@link WebServer} instance
+ */
+ static WebServer startServer(boolean ssl, boolean http2, boolean compression) {
+ // load logging configuration
+ LogConfig.configureRuntime();
+
+ // By default this will pick up application.yaml from the classpath
+ Config config = Config.create();
+
+
+ // Build server config based on params
+ WebServer.Builder serverBuilder = WebServer.builder()
+ .addRouting(createRouting(config))
+ .config(config.get("server"))
+ .update(it -> configureJsonSupport(it, config))
+ .update(it -> configureSsl(it, ssl));
+ // .enableCompression(compression);
+
+ configureJsonSupport(serverBuilder, config);
+
+ WebServer server = serverBuilder.build();
+ server.start();
+ String url = (ssl ? "https" : "http") + "://localhost:" + server.port() + SERVICE_PATH;
+ System.out.println("WEB server is up! " + url + " [ssl=" + ssl + ", http2=" + http2
+ + ", compression=" + compression + "]");
+
+ return server;
+ }
+
+ private static void configureJsonSupport(WebServer.Builder wsBuilder, Config config) {
+ JsonLibrary jsonLibrary = getJsonLibrary(config);
+
+ /* Nima WebServer.Builder does not currently support programmatic way to set media support */
+ /* See issue https://github.com/helidon-io/helidon/issues/6278 */
+ switch (jsonLibrary) {
+ case JSONP:
+ //wsBuilder.addMediaSupport(JsonpSupport.create());
+ break;
+ case JSONB:
+ throw new RuntimeException(jsonLibrary + " is not a supported JSON Library. Only JSONP is supported at this time");
+ //wsBuilder.addMediaSupport(JsonbSupport.create());
+ case JACKSON:
+ throw new RuntimeException(jsonLibrary + " is not a supported JSON Library. Only JSONP is supported at this time");
+ //wsBuilder.addMediaSupport(JacksonSupport.create());
+ default:
+ throw new RuntimeException("Unknown JSON library " + jsonLibrary);
+ }
+ }
+
+ private static void configureSsl(WebServer.Builder wsBuilder, boolean useSsl) {
+ if (!useSsl) {
+ return;
+ }
+
+ KeyConfig privateKeyConfig = privateKey();
+ Tls tls = Tls.builder()
+ .privateKey(privateKeyConfig.privateKey().get())
+ .privateKeyCertChain(privateKeyConfig.certChain())
+ .build();
+
+ wsBuilder.tls(tls);
+ }
+
+ private static KeyConfig privateKey() {
+ String password = "helidon";
+
+ return KeyConfig.keystoreBuilder()
+ .keystore(Resource.create("certificate.p12"))
+ .keystorePassphrase(password)
+ .build();
+ }
+
+ /**
+ * Creates new {@link Routing}.
+ *
+ * @param config configuration of this server
+ * @return routing configured with JSON support, a health check, and a service
+ */
+ private static Routing createRouting(Config config) {
+
+ HealthFeature health = HealthFeature.builder()
+ .useSystemServices(false)
+ .addCheck(HeapMemoryHealthCheck.create())
+ .addCheck(DiskSpaceHealthCheck.create())
+ .addCheck(DeadlockHealthCheck.create())
+ .details(true)
+ .build();
+
+ HttpRouting.Builder builder = HttpRouting.builder()
+ .addFeature(health) // Health at "/health"
+ .addFeature(MetricsFeature.builder().build()) // Metrics at "/metrics"
+ .register(SERVICE_PATH, new BookService(config));
+
+ return builder.build();
+ }
+
+ static JsonLibrary getJsonLibrary(Config config) {
+ return config.get("app.json-library")
+ .asString()
+ .map(String::toUpperCase)
+ .map(JsonLibrary::valueOf)
+ .orElse(JsonLibrary.JSONP);
+ }
+}
diff --git a/tests/apps/bookstore/bookstore-nima/src/main/java/io/helidon/tests/apps/bookstore/nima/package-info.java b/tests/apps/bookstore/bookstore-nima/src/main/java/io/helidon/tests/apps/bookstore/nima/package-info.java
new file mode 100644
index 00000000000..19169318ea1
--- /dev/null
+++ b/tests/apps/bookstore/bookstore-nima/src/main/java/io/helidon/tests/apps/bookstore/nima/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2019, 2023 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.
+ */
+
+/**
+ * Quickstart demo application
+ *
+ * Start with {@link io.helidon.tests.apps.bookstore.nima.Main} class.
+ *
+ * @see io.helidon.tests.apps.bookstore.nima.Main
+ */
+package io.helidon.tests.apps.bookstore.nima;
diff --git a/tests/apps/bookstore/bookstore-nima/src/main/java/module-info.java b/tests/apps/bookstore/bookstore-nima/src/main/java/module-info.java
new file mode 100644
index 00000000000..c24b0da8bf6
--- /dev/null
+++ b/tests/apps/bookstore/bookstore-nima/src/main/java/module-info.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2020, 2023 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.
+ */
+
+/**
+ * Helidon Nima Bookstore test application
+ */
+module io.helidon.tests.apps.bookstore.nima {
+ requires java.logging;
+ requires jakarta.json;
+
+ requires io.helidon.nima.webserver;
+ requires io.helidon.config.yaml;
+ requires io.helidon.config;
+ requires io.helidon.health;
+ requires io.helidon.health.checks;
+ requires io.helidon.nima.observe.metrics;
+ requires io.helidon.nima.observe.health;
+ requires io.helidon.nima.http.media.jsonp;
+ //requires io.helidon.nima.media.jackson;
+ requires io.helidon.tests.apps.bookstore.common;
+ requires io.helidon.logging.common;
+ requires io.helidon.logging.jul;
+ requires io.helidon.common.pki;
+
+ exports io.helidon.tests.apps.bookstore.nima;
+}
diff --git a/tests/apps/bookstore/bookstore-nima/src/main/resources/application.yaml b/tests/apps/bookstore/bookstore-nima/src/main/resources/application.yaml
new file mode 100644
index 00000000000..d4e18a543ea
--- /dev/null
+++ b/tests/apps/bookstore/bookstore-nima/src/main/resources/application.yaml
@@ -0,0 +1,30 @@
+#
+# Copyright (c) 2019, 2023 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.
+#
+
+app:
+ json-library: jsonp
+
+server:
+ port: 8080
+ host: 0.0.0.0
+# ssl:
+# private-key:
+# keystore-resource-path: "certificate.p12"
+# keystore-passphrase: "helidon"
+# experimental:
+# http2:
+# enable: true
+# max-content-length: 16384
diff --git a/tests/apps/bookstore/bookstore-nima/src/main/resources/certificate.p12 b/tests/apps/bookstore/bookstore-nima/src/main/resources/certificate.p12
new file mode 100644
index 00000000000..b2cb83427d1
Binary files /dev/null and b/tests/apps/bookstore/bookstore-nima/src/main/resources/certificate.p12 differ
diff --git a/tests/apps/bookstore/bookstore-nima/src/main/resources/logging.properties b/tests/apps/bookstore/bookstore-nima/src/main/resources/logging.properties
new file mode 100644
index 00000000000..da72a9a8201
--- /dev/null
+++ b/tests/apps/bookstore/bookstore-nima/src/main/resources/logging.properties
@@ -0,0 +1,34 @@
+#
+# Copyright (c) 2019, 2023 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.
+#
+
+# Example Logging Configuration File
+# For more information see $JAVA_HOME/jre/lib/logging.properties
+
+# Send messages to the console
+handlers=io.helidon.logging.jul.HelidonConsoleHandler
+
+# HelidonConsoleHandler uses a SimpleFormatter subclass that replaces "!thread!" with the current thread
+java.util.logging.SimpleFormatter.format=%1$tY.%1$tm.%1$td %1$tH:%1$tM:%1$tS %4$s %3$s !thread!: %5$s%6$s%n
+
+# Global logging level. Can be overridden by specific loggers
+.level=INFO
+
+# Component specific log levels
+#io.helidon.reactive.webserver.level=INFO
+#io.helidon.config.level=INFO
+#io.helidon.security.level=INFO
+#io.helidon.common.level=INFO
+#io.netty.level=INFO
diff --git a/tests/apps/bookstore/bookstore-nima/src/test/java/io/helidon/tests/apps/bookstore/nima/Http2SslTest.java b/tests/apps/bookstore/bookstore-nima/src/test/java/io/helidon/tests/apps/bookstore/nima/Http2SslTest.java
new file mode 100644
index 00000000000..02f99705fdf
--- /dev/null
+++ b/tests/apps/bookstore/bookstore-nima/src/test/java/io/helidon/tests/apps/bookstore/nima/Http2SslTest.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2019, 2023 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.tests.apps.bookstore.nima;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import io.helidon.common.configurable.ThreadPoolSupplier;
+
+import io.helidon.nima.webserver.WebServer;
+import okhttp3.OkHttpClient;
+import okhttp3.Protocol;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import okhttp3.Response;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import static io.helidon.tests.apps.bookstore.nima.TestServer.APPLICATION_JSON;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.fail;
+
+/**
+ * Tests SSL/TLS with HTTP 2 upgrades and compression.
+ */
+public class Http2SslTest {
+
+ private static WebServer webServer;
+ private static OkHttpClient client;
+
+ @BeforeAll
+ public static void startServer() throws Exception {
+ webServer = TestServer.start(true, true, true);
+ client = TestServer.newOkHttpClient(true);
+ }
+
+ @AfterAll
+ public static void stopServer() throws Exception {
+ TestServer.stop(webServer);
+ }
+
+ @Test
+ public void testHelloWorldHttp2Ssl() throws Exception {
+ testHelloWorld(false);
+ }
+
+ @Test
+ public void testHelloWorldHttp2SslCompression() throws Exception {
+ testHelloWorld(true);
+ }
+
+ @Test
+ public void testHelloWorldHttp2SslPostFirst() throws Exception {
+ Request.Builder builder = TestServer.newRequestBuilder(webServer, "/books", true);
+ Request postBook = builder.post(
+ RequestBody.create(APPLICATION_JSON, TestServer.getBookAsJson())).build();
+ try (Response postBookRes = client.newCall(postBook).execute()) {
+ assertThat(postBookRes.code(), is(200));
+ assertThat(postBookRes.protocol(), is(Protocol.HTTP_2));
+ }
+
+ builder = TestServer.newRequestBuilder(webServer, "/books/123456", true);
+ Request deleteBook = builder.delete().build();
+ try (Response deleteBookRes = client.newCall(deleteBook).execute()) {
+ assertThat(deleteBookRes.code(), is(200));
+ assertThat(deleteBookRes.protocol(), is(Protocol.HTTP_2));
+ }
+ }
+
+ @Test
+ public void testHelloWorldHttp2SslConcurrent() throws Exception {
+ ExecutorService executor = ThreadPoolSupplier.create("test-thread-pool").get();
+ Request.Builder builder = TestServer.newRequestBuilder(webServer, "/books", true);
+ Request getBooks = builder.build();
+
+ List> tasks = Collections.nCopies(10, () -> client.newCall(getBooks).execute());
+ executor.invokeAll(tasks).forEach(f -> {
+ try {
+ Response r = f.get(1, TimeUnit.SECONDS);
+ assertThat(r.code(), is(200));
+ assertThat(r.protocol(), is(Protocol.HTTP_2));
+ } catch (Exception e) {
+ fail(e);
+ }
+ });
+ }
+
+ private void testHelloWorld(boolean compression) throws Exception {
+ Request.Builder builder = TestServer.newRequestBuilder(webServer, "/books", true, compression);
+
+ Request getBooks = builder.build();
+ try (Response getBooksRes = client.newCall(getBooks).execute()) {
+ assertThat(getBooksRes.code(), is(200));
+ assertThat(getBooksRes.protocol(), is(Protocol.HTTP_2));
+ }
+
+ Request postBook = builder.post(
+ RequestBody.create(APPLICATION_JSON, TestServer.getBookAsJson())).build();
+ try (Response postBookRes = client.newCall(postBook).execute()) {
+ assertThat(postBookRes.code(), is(200));
+ assertThat(postBookRes.protocol(), is(Protocol.HTTP_2));
+ }
+
+ builder = TestServer.newRequestBuilder(webServer, "/books/123456", true, compression);
+ Request getBook = builder.build();
+ try (Response getBookRes = client.newCall(getBook).execute()) {
+ assertThat(getBookRes.code(), is(200));
+ assertThat(getBookRes.protocol(), is(Protocol.HTTP_2));
+ }
+
+ Request deleteBook = builder.delete().build();
+ try (Response deleteBookRes = client.newCall(deleteBook).execute()) {
+ assertThat(deleteBookRes.code(), is(200));
+ assertThat(deleteBookRes.protocol(), is(Protocol.HTTP_2));
+
+ }
+
+ Request getNoBook = builder.build();
+ try (Response getNoBookRes = client.newCall(getNoBook).execute()) {
+ assertThat(getNoBookRes.code(), is(404));
+ assertThat(getNoBookRes.protocol(), is(Protocol.HTTP_2));
+ }
+ }
+}
diff --git a/tests/apps/bookstore/bookstore-nima/src/test/java/io/helidon/tests/apps/bookstore/nima/MainTest.java b/tests/apps/bookstore/bookstore-nima/src/test/java/io/helidon/tests/apps/bookstore/nima/MainTest.java
new file mode 100644
index 00000000000..7b4c521f1a6
--- /dev/null
+++ b/tests/apps/bookstore/bookstore-nima/src/test/java/io/helidon/tests/apps/bookstore/nima/MainTest.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2018, 2023 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.tests.apps.bookstore.nima;
+
+
+import io.helidon.nima.webserver.WebServer;
+import jakarta.json.Json;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonReader;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import okhttp3.Response;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import static io.helidon.tests.apps.bookstore.nima.TestServer.APPLICATION_JSON;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+public class MainTest {
+
+ private static WebServer webServer;
+ private static OkHttpClient client;
+
+ @BeforeAll
+ public static void startServer() throws Exception {
+ webServer = TestServer.start(false, false, false);
+ client = TestServer.newOkHttpClient(false);
+ }
+
+ @AfterAll
+ public static void stopServer() throws Exception {
+ TestServer.stop(webServer);
+ }
+
+ @Test
+ public void testHelloWorld() throws Exception {
+ Request.Builder builder = TestServer.newRequestBuilder(webServer, "/books", false);
+
+ Request getBooks = builder.build();
+ try (Response getBooksRes = client.newCall(getBooks).execute()) {
+ assertThat(getBooksRes.code(), is(200));
+ assertThat(getBooksRes.header("content-length"), notNullValue());
+ String body = getBooksRes.body().string();
+ assertThat(body, is("[]"));
+ }
+
+ Request postBook = builder.post(
+ RequestBody.create(APPLICATION_JSON, TestServer.getBookAsJson())).build();
+ try (Response postBookRes = client.newCall(postBook).execute()) {
+ assertThat(postBookRes.code(), is(200));
+ }
+
+ builder = TestServer.newRequestBuilder(webServer, "/books/123456", false);
+ Request getBook = builder.build();
+ try (Response getBookRes = client.newCall(getBook).execute()) {
+ assertThat(getBookRes.code(), is(200));
+ assertThat(getBookRes.header("content-length"), notNullValue());
+ JsonReader jsonReader = Json.createReader(getBookRes.body().byteStream());
+ JsonObject jsonObject = jsonReader.readObject();
+ assertThat("Checking if correct ISBN", jsonObject.getString("isbn"),
+ is("123456"));
+ }
+
+ Request deleteBook = builder.delete().build();
+ try (Response deleteBookRes = client.newCall(deleteBook).execute()) {
+ assertThat(deleteBookRes.code(), is(200));
+ }
+
+ Request getNoBook = builder.build();
+ try (Response getNoBookRes = client.newCall(getNoBook).execute()) {
+ assertThat(getNoBookRes.code(), is(404));
+ }
+ }
+}
diff --git a/tests/apps/bookstore/bookstore-nima/src/test/java/io/helidon/tests/apps/bookstore/nima/SslTest.java b/tests/apps/bookstore/bookstore-nima/src/test/java/io/helidon/tests/apps/bookstore/nima/SslTest.java
new file mode 100644
index 00000000000..73e740c4318
--- /dev/null
+++ b/tests/apps/bookstore/bookstore-nima/src/test/java/io/helidon/tests/apps/bookstore/nima/SslTest.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2019, 2023 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.tests.apps.bookstore.nima;
+
+import io.helidon.nima.webserver.WebServer;
+
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import okhttp3.Response;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import static io.helidon.tests.apps.bookstore.nima.TestServer.APPLICATION_JSON;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+/**
+ * Tests SSL/TLS with HTTP 1.1.
+ */
+public class SslTest {
+
+ private static WebServer webServer;
+ private static OkHttpClient client;
+
+ @BeforeAll
+ public static void startServer() throws Exception {
+ webServer = TestServer.start(true, false, false);
+ client = TestServer.newOkHttpClient(true);
+ }
+
+ @AfterAll
+ public static void stopServer() throws Exception {
+ TestServer.stop(webServer);
+ }
+
+ @Test
+ public void testHelloWorldSsl() throws Exception {
+ Request.Builder builder = TestServer.newRequestBuilder(webServer, "/books", true);
+
+ Request getBooks = builder.build();
+ try (Response getBooksRes = client.newCall(getBooks).execute()) {
+ assertThat(getBooksRes.code(), is(200));
+ }
+
+ Request postBook = builder.post(
+ RequestBody.create(APPLICATION_JSON, TestServer.getBookAsJson())).build();
+ try (Response postBookRes = client.newCall(postBook).execute()) {
+ assertThat(postBookRes.code(), is(200));
+ }
+
+ builder = TestServer.newRequestBuilder(webServer, "/books/123456", true);
+ Request getBook = builder.build();
+ try (Response getBookRes = client.newCall(getBook).execute()) {
+ assertThat(getBookRes.code(), is(200));
+ }
+
+ Request deleteBook = builder.delete().build();
+ try (Response deleteBookRes = client.newCall(deleteBook).execute()) {
+ assertThat(deleteBookRes.code(), is(200));
+ }
+
+ Request getNoBook = builder.build();
+ try (Response getNoBookRes = client.newCall(getNoBook).execute()) {
+ assertThat(getNoBookRes.code(), is(404));
+ }
+ }
+}
diff --git a/tests/apps/bookstore/bookstore-nima/src/test/java/io/helidon/tests/apps/bookstore/nima/TestServer.java b/tests/apps/bookstore/bookstore-nima/src/test/java/io/helidon/tests/apps/bookstore/nima/TestServer.java
new file mode 100644
index 00000000000..0ac06443662
--- /dev/null
+++ b/tests/apps/bookstore/bookstore-nima/src/test/java/io/helidon/tests/apps/bookstore/nima/TestServer.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2019, 2023 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.tests.apps.bookstore.nima;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.security.SecureRandom;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+import io.helidon.nima.webserver.WebServer;
+
+import okhttp3.Interceptor;
+import okhttp3.MediaType;
+import okhttp3.OkHttpClient;
+import okhttp3.Protocol;
+import okhttp3.Request;
+import okhttp3.Response;
+import org.junit.jupiter.api.Assertions;
+
+/**
+ * Utility class to start the Helidon server with options.
+ */
+class TestServer {
+
+ static final MediaType APPLICATION_JSON = MediaType.parse("application/json");
+
+ private static X509TrustManager TRUST_MANAGER = new X509TrustManager() {
+ public X509Certificate[] getAcceptedIssuers() {
+ return new X509Certificate[0];
+ }
+
+ public void checkClientTrusted(X509Certificate[] certs, String authType) {
+ }
+
+ public void checkServerTrusted(X509Certificate[] certs, String authType) {
+ }
+ };
+
+ static WebServer start(boolean ssl, boolean http2, boolean compression) throws Exception {
+ WebServer webServer = Main.startServer(ssl, http2, compression);
+
+ long timeout = 2000; // 2 seconds should be enough to start the server
+ long now = System.currentTimeMillis();
+
+ while (!webServer.isRunning()) {
+ Thread.sleep(100);
+ if ((System.currentTimeMillis() - now) > timeout) {
+ Assertions.fail("Failed to start webserver");
+ }
+ }
+
+ return webServer;
+ }
+
+ static void stop(WebServer webServer) throws Exception {
+ if (webServer != null) {
+ webServer.stop();
+ }
+ }
+
+ static String getBookAsJson() throws Exception {
+ try (InputStream is = TestServer.class.getClassLoader().getResourceAsStream("book.json")) {
+ if (is != null) {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+ return reader.lines().collect(Collectors.joining(System.lineSeparator()));
+ }
+ throw new RuntimeException("Unable to find resource book.json");
+ }
+ }
+
+ static SSLContext setupSSLTrust() throws Exception {
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(null, new TrustManager[] { TRUST_MANAGER }, new SecureRandom());
+ return sslContext;
+ }
+
+ static Request.Builder newRequestBuilder(WebServer webServer, String path, boolean ssl) throws Exception {
+ return newRequestBuilder(webServer, path, ssl, false);
+ }
+
+ static Request.Builder newRequestBuilder(WebServer webServer, String path, boolean ssl, boolean compression)
+ throws Exception {
+ URL url = new URL((ssl ? "https" : "http") + "://localhost:" + webServer.port() + path);
+ Request.Builder builder = new Request.Builder().url(url);
+ builder.addHeader("Accept-Encoding", compression ? "gzip" : "none");
+ return builder;
+ }
+
+ static class LoggingInterceptor implements Interceptor {
+ @Override
+ public Response intercept(Interceptor.Chain chain) throws IOException {
+ Request request = chain.request();
+
+ long t1 = System.nanoTime();
+ System.out.println(String.format("Sending request %s on %s%n%s",
+ request.url(), chain.connection(), request.headers()));
+
+ Response response = chain.proceed(request);
+
+ long t2 = System.nanoTime();
+ System.out.println(String.format("Received response for %s in %.1fms%nProtocol is %s%n%s",
+ response.request().url(), (t2 - t1) / 1e6d, response.protocol(), response.headers()));
+
+ return response;
+ }
+ }
+
+ static OkHttpClient newOkHttpClient(boolean ssl) throws Exception {
+ OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder()
+ .addNetworkInterceptor(new LoggingInterceptor())
+ .protocols(Arrays.asList(Protocol.HTTP_2, Protocol.HTTP_1_1));
+ if (ssl) {
+ SSLContext sslContext = setupSSLTrust();
+ clientBuilder.sslSocketFactory(sslContext.getSocketFactory(), TRUST_MANAGER);
+ clientBuilder.hostnameVerifier((host, session) -> host.equals("localhost"));
+ }
+ return clientBuilder.build();
+ }
+}
diff --git a/tests/apps/bookstore/bookstore-nima/src/test/resources/book.json b/tests/apps/bookstore/bookstore-nima/src/test/resources/book.json
new file mode 100644
index 00000000000..7afa99f43dd
--- /dev/null
+++ b/tests/apps/bookstore/bookstore-nima/src/test/resources/book.json
@@ -0,0 +1,17 @@
+{
+ "isbn": "123456",
+ "title": "The hunt for Red October",
+ "description": "387 p., hardback",
+ "summary": "The Soviets' new ballistic-missile submarine is attempting to defect to the United States, but the Soviet Atlantic fleet has been ordered to find and destroy her at all costs. Can Red October reach the U.S. safely?",
+ "genre": "spy stories",
+ "category": "fiction",
+ "publisher": "Naval Institute Press",
+ "copyright": "c1984",
+ "authors": [
+ {
+ "first": "Tom",
+ "last": "Clancy"
+ }
+ ]
+}
+
diff --git a/tests/apps/bookstore/bookstore-se/pom.xml b/tests/apps/bookstore/bookstore-se/pom.xml
index b53b62fe140..2e136690cc5 100644
--- a/tests/apps/bookstore/bookstore-se/pom.xml
+++ b/tests/apps/bookstore/bookstore-se/pom.xml
@@ -58,6 +58,10 @@
io.helidon.reactive.metrics
helidon-reactive-metrics
+
+ io.helidon.metrics
+ helidon-metrics
+
io.helidon.reactive.media
helidon-reactive-media-jsonp
diff --git a/tests/apps/bookstore/bookstore-se/src/main/java/io/helidon/tests/apps/bookstore/se/BookService.java b/tests/apps/bookstore/bookstore-se/src/main/java/io/helidon/tests/apps/bookstore/se/BookService.java
index 76f77698c23..a9e9ff6ed93 100644
--- a/tests/apps/bookstore/bookstore-se/src/main/java/io/helidon/tests/apps/bookstore/se/BookService.java
+++ b/tests/apps/bookstore/bookstore-se/src/main/java/io/helidon/tests/apps/bookstore/se/BookService.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, 2022 Oracle and/or its affiliates.
+ * Copyright (c) 2018, 2023 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.
@@ -25,6 +25,7 @@
import io.helidon.reactive.webserver.ServerResponse;
import io.helidon.reactive.webserver.Service;
import io.helidon.tests.apps.bookstore.common.Book;
+import io.helidon.tests.apps.bookstore.common.BookMapper;
import io.helidon.tests.apps.bookstore.common.BookStore;
import jakarta.json.JsonObject;
diff --git a/tests/apps/bookstore/common/pom.xml b/tests/apps/bookstore/common/pom.xml
index 5fc549c535f..549e4c7018a 100644
--- a/tests/apps/bookstore/common/pom.xml
+++ b/tests/apps/bookstore/common/pom.xml
@@ -35,6 +35,10 @@
jakarta.enterprise
jakarta.enterprise.cdi-api
+
+ io.helidon.reactive.media
+ helidon-reactive-media-jsonp
+
org.junit.jupiter
junit-jupiter-api
diff --git a/tests/apps/bookstore/bookstore-se/src/main/java/io/helidon/tests/apps/bookstore/se/AuthorMapper.java b/tests/apps/bookstore/common/src/main/java/io/helidon/tests/apps/bookstore/common/AuthorMapper.java
similarity index 96%
rename from tests/apps/bookstore/bookstore-se/src/main/java/io/helidon/tests/apps/bookstore/se/AuthorMapper.java
rename to tests/apps/bookstore/common/src/main/java/io/helidon/tests/apps/bookstore/common/AuthorMapper.java
index 7abf2458835..0a429e5cd21 100644
--- a/tests/apps/bookstore/bookstore-se/src/main/java/io/helidon/tests/apps/bookstore/se/AuthorMapper.java
+++ b/tests/apps/bookstore/common/src/main/java/io/helidon/tests/apps/bookstore/common/AuthorMapper.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, 2021 Oracle and/or its affiliates.
+ * Copyright (c) 2019, 2023 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package io.helidon.tests.apps.bookstore.se;
+package io.helidon.tests.apps.bookstore.common;
import java.util.ArrayList;
import java.util.List;
diff --git a/tests/apps/bookstore/bookstore-se/src/main/java/io/helidon/tests/apps/bookstore/se/BookMapper.java b/tests/apps/bookstore/common/src/main/java/io/helidon/tests/apps/bookstore/common/BookMapper.java
similarity index 90%
rename from tests/apps/bookstore/bookstore-se/src/main/java/io/helidon/tests/apps/bookstore/se/BookMapper.java
rename to tests/apps/bookstore/common/src/main/java/io/helidon/tests/apps/bookstore/common/BookMapper.java
index e9e72131645..4757f6d8cf7 100644
--- a/tests/apps/bookstore/bookstore-se/src/main/java/io/helidon/tests/apps/bookstore/se/BookMapper.java
+++ b/tests/apps/bookstore/common/src/main/java/io/helidon/tests/apps/bookstore/common/BookMapper.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, 2021 Oracle and/or its affiliates.
+ * Copyright (c) 2019, 2023 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.
@@ -14,10 +14,11 @@
* limitations under the License.
*/
-package io.helidon.tests.apps.bookstore.se;
+package io.helidon.tests.apps.bookstore.common;
import java.util.Collection;
+import io.helidon.tests.apps.bookstore.common.AuthorMapper;
import io.helidon.tests.apps.bookstore.common.Book;
import jakarta.json.Json;
@@ -26,7 +27,7 @@
import jakarta.json.JsonBuilderFactory;
import jakarta.json.JsonObject;
-class BookMapper {
+public class BookMapper {
private static final String ISBN = "isbn";
private static final String TITLE = "title";
@@ -52,7 +53,7 @@ private BookMapper() {
* @param book Book to convert to JSON
* @return new JsonObject representing book
*/
- static JsonObject encodeJsonp(Book book) {
+ public static JsonObject encodeJsonp(Book book) {
JsonObject jo = JSON_FACTORY.createObjectBuilder()
.add(ISBN, book.getIsbn())
.add(TITLE, book.getTitle())
@@ -67,7 +68,7 @@ static JsonObject encodeJsonp(Book book) {
return jo;
}
- static JsonArray encodeJsonp(Collection books) {
+ public static JsonArray encodeJsonp(Collection books) {
JsonArrayBuilder builder = JSON_FACTORY.createArrayBuilder();
for (Book b : books) {
builder.add(encodeJsonp(b));
@@ -79,7 +80,7 @@ static JsonArray encodeJsonp(Collection books) {
* @param jo JsonObject representation to convert to Book pojo
* @return New Book pojo
*/
- static Book decodeJsonp(JsonObject jo) {
+ public static Book decodeJsonp(JsonObject jo) {
return updateBook(new Book(), jo);
}
diff --git a/tests/apps/bookstore/common/src/main/java/module-info.java b/tests/apps/bookstore/common/src/main/java/module-info.java
index c5743840603..8ba441ee9e0 100644
--- a/tests/apps/bookstore/common/src/main/java/module-info.java
+++ b/tests/apps/bookstore/common/src/main/java/module-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, 2021 Oracle and/or its affiliates.
+ * Copyright (c) 2020, 2023 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.
@@ -20,6 +20,7 @@
module io.helidon.tests.apps.bookstore.common {
requires jakarta.cdi;
+ requires jakarta.json;
opens io.helidon.tests.apps.bookstore.common to weld.core.impl, io.helidon.microprofile.cdi;
diff --git a/tests/apps/bookstore/pom.xml b/tests/apps/bookstore/pom.xml
index 42aad487fae..ed0f1304499 100644
--- a/tests/apps/bookstore/pom.xml
+++ b/tests/apps/bookstore/pom.xml
@@ -35,6 +35,7 @@
common
+ bookstore-nima
bookstore-se
bookstore-mp
diff --git a/tests/functional/bookstore/pom.xml b/tests/functional/bookstore/pom.xml
index 763f6f390d6..c052419cf52 100644
--- a/tests/functional/bookstore/pom.xml
+++ b/tests/functional/bookstore/pom.xml
@@ -32,6 +32,7 @@
${project.basedir}/../../apps/bookstore/bookstore-se/target/bookstore-se.jar
${project.basedir}/../../apps/bookstore/bookstore-mp/target/bookstore-mp.jar
+ ${project.basedir}/../../apps/bookstore/bookstore-nima/target/bookstore-nima.jar
@@ -44,6 +45,7 @@
${appJarPathSE}
${appJarPathMP}
+ ${appJarPathNima}
diff --git a/tests/functional/bookstore/src/test/java/io/helidon/tests/bookstore/MainTest.java b/tests/functional/bookstore/src/test/java/io/helidon/tests/bookstore/MainTest.java
index f49c4bd0c76..9c8fee2ddb6 100644
--- a/tests/functional/bookstore/src/test/java/io/helidon/tests/bookstore/MainTest.java
+++ b/tests/functional/bookstore/src/test/java/io/helidon/tests/bookstore/MainTest.java
@@ -56,15 +56,16 @@
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.greaterThan;
-@Disabled
class MainTest {
private static String appJarPathSE = System.getProperty("app.jar.path.se", "please-set-app.jar.path.se");
private static String appJarPathMP = System.getProperty("app.jar.path.mp", "please-set-app.jar.path.mp");
+ private static String appJarPathNima = System.getProperty("app.jar.path.nima", "please-set-app.jar.path.nima");
private static final LocalPlatform localPlatform = LocalPlatform.get();
private static final String MODULE_NAME_MP = "io.helidon.tests.apps.bookstore.mp";
private static final String MODULE_NAME_SE = "io.helidon.tests.apps.bookstore.se";
+ private static final String MODULE_NAME_NIMA = "io.helidon.tests.apps.bookstore.nima";
private static final System.Logger LOGGER = System.getLogger(MainTest.class.getName());
/**
@@ -111,6 +112,7 @@ void waitForApplicationUp() throws Exception {
private void waitForApplication(boolean toBeUp) throws Exception {
long timeout = 15 * 1000; // 15 seconds should be enough to start/stop the server
long now = System.currentTimeMillis();
+ int count = 0;
String operation = (toBeUp ? "start" : "stop");
URL url = getHealthUrl();
LOGGER.log(Level.INFO, "Waiting for application to " + operation);
@@ -120,11 +122,12 @@ private void waitForApplication(boolean toBeUp) throws Exception {
do {
Thread.sleep(500);
if ((System.currentTimeMillis() - now) > timeout) {
- Assertions.fail("Application failed to " + operation);
+ Assertions.fail("Application failed to " + operation + ": count=" + count);
}
try {
+ count++;
conn = (HttpURLConnection) url.openConnection();
- conn.setConnectTimeout(500);
+ conn.setConnectTimeout(1000);
responseCode = conn.getResponseCode();
if (toBeUp && responseCode != 200) {
LOGGER.log(Level.INFO, "Waiting for application to " + operation + ": Bad health response "
@@ -149,6 +152,7 @@ private void waitForApplication(boolean toBeUp) throws Exception {
static void setup() {
appJarPathSE = Paths.get(appJarPathSE).normalize().toString();
appJarPathMP = Paths.get(appJarPathMP).normalize().toString();
+ appJarPathNima = Paths.get(appJarPathNima).normalize().toString();
}
/**
@@ -217,9 +221,11 @@ private void runExitOnStartedTest(String edition) throws Exception {
application.close();
}
- @Test
- void basicTestJsonP() throws Exception {
- runJsonFunctionalTest("se", "jsonp");
+
+ @ParameterizedTest
+ @ValueSource(strings = {"se", "mp", "nima"})
+ void basicTestJson(String edition) throws Exception {
+ runJsonFunctionalTest(edition, "");
}
@Test
@@ -232,19 +238,10 @@ void basicTestJackson() throws Exception {
runJsonFunctionalTest("se", "jackson");
}
- @Test
- void basicTestJsonMP() throws Exception {
- runJsonFunctionalTest("mp", "");
- }
-
- @Test
- void basicTestMetricsHealthSE() throws Exception {
- runMetricsAndHealthTest("se", "jsonp", false);
- }
-
- @Test
- void basicTestMetricsHealthMP() throws Exception {
- runMetricsAndHealthTest("mp", "", false);
+ @ParameterizedTest
+ @ValueSource(strings = {"se", "mp", "nima"})
+ void basicTestMetricsHealth(String edition) throws Exception {
+ runMetricsAndHealthTest(edition, "", false);
}
@Test
@@ -257,16 +254,10 @@ void basicTestMetricsHealthJackson() throws Exception {
runMetricsAndHealthTest("se", "jackson", false);
}
- @Test
- @Disabled("3.0.0-JAKARTA")
- void basicTestMetricsHealthSEModules() throws Exception {
- runMetricsAndHealthTest("se", "jsonp", true);
- }
-
- @Test
- @Disabled("3.0.0-JAKARTA")
- void basicTestMetricsHealthMPModules() throws Exception {
- runMetricsAndHealthTest("mp", "", true);
+ @ParameterizedTest
+ @ValueSource(strings = {"se", "mp", "nima"})
+ void basicTestMetricsHealthModules(String edition) throws Exception {
+ runMetricsAndHealthTest(edition, "", true);
}
/**
@@ -428,7 +419,7 @@ private void runMetricsAndHealthTest(String edition, String jsonLibrary, boolean
}
@ParameterizedTest
- @ValueSource(strings = {"se", "mp"})
+ @ValueSource(strings = {"se", "mp", "nima"})
void routing(String edition) throws Exception {
HelidonApplication application = startTheApplication(editionToJarPath(edition), Collections.emptyList());
@@ -443,7 +434,7 @@ void routing(String edition) throws Exception {
.path("/boo%6bs")
.request()
.thenAccept(it -> {
- if ("se".equals(edition)) {
+ if ("se".equals(edition) || "nima".equals(edition)) {
assertThat("Checking encode URL response SE", it.status(), is(Http.Status.OK_200));
} else {
// JAXRS does not decode URLs before matching
@@ -497,8 +488,10 @@ private static String editionToJarPath(String edition) {
return appJarPathSE;
} else if ("mp".equals(edition)) {
return appJarPathMP;
+ } else if ("nima".equals(edition)) {
+ return appJarPathNima;
} else {
- throw new IllegalArgumentException("Invalid edition '" + edition + "'. Must be 'se' or 'mp'");
+ throw new IllegalArgumentException("Invalid edition '" + edition + "'. Must be 'se' or 'mp' or 'nima'");
}
}
@@ -507,8 +500,10 @@ private static String editionToModuleName(String edition) {
return MODULE_NAME_SE;
} else if ("mp".equals(edition)) {
return MODULE_NAME_MP;
+ } else if ("nima".equals(edition)) {
+ return MODULE_NAME_NIMA;
} else {
- throw new IllegalArgumentException("Invalid edition '" + edition + "'. Must be 'se' or 'mp'");
+ throw new IllegalArgumentException("Invalid edition '" + edition + "'. Must be 'se' or 'mp' or 'nima'");
}
}
}