, ExpandedTypeDescription.MapLikeTypeDescription> typeDescriptionFactory) { }
/**
- * Type information about a map-resembling interface in which a child can have 0, 1, or more values i.e., the child is
+ * Type information about a map-resembling interface in which a child can have 0, 1, or more values (i.e., the child is
* a list).
*
* @param
parent type
@@ -165,7 +166,7 @@ record ChildMapListType
(
private static final System.Logger LOGGER = System.getLogger(CustomConstructor.class.getName());
CustomConstructor(TypeDescription td) {
- super(td);
+ super(td, new LoaderOptions());
yamlClassConstructors.put(NodeId.mapping, new ConstructMapping());
}
diff --git a/openapi/src/main/java/io/helidon/openapi/ImplTypeDescription.java b/openapi/src/main/java/io/helidon/openapi/ImplTypeDescription.java
index 6d315ad81a3..e00dbc4d563 100644
--- a/openapi/src/main/java/io/helidon/openapi/ImplTypeDescription.java
+++ b/openapi/src/main/java/io/helidon/openapi/ImplTypeDescription.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.
@@ -61,46 +61,18 @@ public Tag getTag() {
return delegate.getTag();
}
- @Override
- public void setTag(Tag tag) {
- delegate.setTag(tag);
- }
-
- @Override
- public void setTag(String tag) {
- delegate.setTag(tag);
- }
-
@Override
@Deprecated
public void putListPropertyType(String property, Class> type) {
delegate.putListPropertyType(property, type);
}
- @Override
- @Deprecated
- public Class extends Object> getListPropertyType(String property) {
- return delegate.getListPropertyType(property);
- }
-
@Override
@Deprecated
public void putMapPropertyType(String property, Class> key, Class> value) {
delegate.putMapPropertyType(property, key, value);
}
- @Override
- @Deprecated
- public Class extends Object> getMapKeyType(String property) {
- return delegate.getMapKeyType(property);
- }
-
- @Override
- @Deprecated
- public Class extends Object> getMapValueType(String property) {
- return delegate.getMapValueType(property);
- }
-
@Override
public void addPropertyParameters(String pName, Class>... classes) {
delegate.addPropertyParameters(pName, classes);
diff --git a/openapi/src/main/java/io/helidon/openapi/ParserHelper.java b/openapi/src/main/java/io/helidon/openapi/ParserHelper.java
index 3e9050fcf14..a832eb38843 100644
--- a/openapi/src/main/java/io/helidon/openapi/ParserHelper.java
+++ b/openapi/src/main/java/io/helidon/openapi/ParserHelper.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022 Oracle and/or its affiliates.
+ * Copyright (c) 2022, 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.
@@ -32,6 +32,13 @@
* Wraps generated parser and uses {@link io.helidon.openapi.ExpandedTypeDescription} as its type.
*/
public class ParserHelper {
+
+ // Temporary to suppress SnakeYAML warnings.
+ // As a static we keep a reference to the logger, thereby making sure any changes we make are persistent. (JUL holds
+ // only weak references to loggers internally.)
+ private static final java.util.logging.Logger SNAKE_YAML_INTROSPECTOR_LOGGER =
+ java.util.logging.Logger.getLogger(org.yaml.snakeyaml.introspector.PropertySubstitute.class.getPackage().getName());
+
/**
* The SnakeYAMLParserHelper is generated by a maven plug-in.
*/
@@ -39,6 +46,10 @@ public class ParserHelper {
private ParserHelper(SnakeYAMLParserHelper generatedHelper) {
this.generatedHelper = generatedHelper;
+ boolean warningsEnabled = Boolean.getBoolean("openapi.parsing.warnings.enabled");
+ if (SNAKE_YAML_INTROSPECTOR_LOGGER.isLoggable(java.util.logging.Level.WARNING) && !warningsEnabled) {
+ SNAKE_YAML_INTROSPECTOR_LOGGER.setLevel(java.util.logging.Level.SEVERE);
+ }
}
/**
diff --git a/openapi/src/main/java/io/helidon/openapi/Serializer.java b/openapi/src/main/java/io/helidon/openapi/Serializer.java
index d7c91c1193d..514c3c2891d 100644
--- a/openapi/src/main/java/io/helidon/openapi/Serializer.java
+++ b/openapi/src/main/java/io/helidon/openapi/Serializer.java
@@ -114,7 +114,6 @@ static class CustomRepresenter extends Representer {
private static final String EXTENSIONS = "extensions";
- private final DumperOptions dumperOptions;
private final DumperOptions.ScalarStyle stringStyle;
private final Map, ExpandedTypeDescription> implsToTypes;
@@ -122,8 +121,8 @@ static class CustomRepresenter extends Representer {
CustomRepresenter(Map, ExpandedTypeDescription> types,
Map, ExpandedTypeDescription> implsToTypes, DumperOptions dumperOptions,
DumperOptions.ScalarStyle stringStyle) {
+ super(dumperOptions);
this.implsToTypes = implsToTypes;
- this.dumperOptions = dumperOptions;
this.stringStyle = stringStyle;
types.values().stream()
.map(ImplTypeDescription::new)
diff --git a/openapi/src/main/java/module-info.java b/openapi/src/main/java/module-info.java
index 12e10c17097..830b6cd537b 100644
--- a/openapi/src/main/java/module-info.java
+++ b/openapi/src/main/java/module-info.java
@@ -42,6 +42,7 @@
requires transitive microprofile.openapi.api;
requires static io.helidon.config.metadata;
+ requires java.logging; // temporary to adjust SnakeYAML logger level
exports io.helidon.openapi;
exports io.helidon.openapi.internal to io.helidon.microprofile.openapi, io.helidon.reactive.openapi, io.helidon.nima.openapi;
diff --git a/tests/integration/gh-5792-nima/README.md b/tests/integration/gh-5792-nima/README.md
new file mode 100644
index 00000000000..66f0618e73f
--- /dev/null
+++ b/tests/integration/gh-5792-nima/README.md
@@ -0,0 +1,21 @@
+
+# helidon-tests-integration-yaml-parsing
+
+Sample Helidon Níma project to make sure that we can build and run using an older release of SnakeYAML in case users need to fall back.
+
+Note that the static OpenAPI document packaged into the application JAR file intentionally _does not_ describe the API for this service.
+It contains a much richer definition to exercise YAML parsing a bit more.
+
+## Build and run
+
+With JDK19+
+ ```bash
+ mvn package
+java --enable-preview -jar target/helidon-tests-integration-yaml-parsing.jar
+ ```
+
+## Try OpenAPI
+
+ ```
+ curl -s -X GET http://localhost:8080/openapi
+```
diff --git a/tests/integration/gh-5792-nima/pom.xml b/tests/integration/gh-5792-nima/pom.xml
new file mode 100644
index 00000000000..99dcffd153f
--- /dev/null
+++ b/tests/integration/gh-5792-nima/pom.xml
@@ -0,0 +1,117 @@
+
+
+
+
+ 4.0.0
+
+ io.helidon.applications
+ helidon-nima
+ 4.0.0-SNAPSHOT
+ ../../../applications/nima/pom.xml
+
+ io.helidon.tests.integration
+ helidon-tests-integration-yaml-parsing-nima
+ 4.0.0-SNAPSHOT
+
+ Helidon SnakeYAML Earlier Version Test - Nima
+
+
+ io.helidon.tests.integration.yamlparsing.Main
+ 1.32
+
+
+
+
+
+
+ org.yaml
+ snakeyaml
+ ${selectedSnakeYamlVersion}
+
+
+
+
+
+
+ io.helidon.nima.webserver
+ helidon-nima-webserver
+
+
+ io.helidon.nima.webclient
+ helidon-nima-webclient
+
+
+ io.helidon.nima.http.media
+ helidon-nima-http-media-jsonp
+
+
+ io.helidon.nima.openapi
+ helidon-nima-openapi
+
+
+ io.helidon.config
+ helidon-config-yaml
+
+
+ jakarta.json
+ jakarta.json-api
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ test
+
+
+ org.hamcrest
+ hamcrest-all
+ test
+
+
+ io.helidon.nima.testing.junit5
+ helidon-nima-testing-junit5-webserver
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ ${selectedSnakeYamlVersion}
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+
+
+ copy-libs
+
+
+
+
+
+
diff --git a/tests/integration/gh-5792-nima/src/main/java/io/helidon/tests/integration/yamlparsing/GreetClientHttp.java b/tests/integration/gh-5792-nima/src/main/java/io/helidon/tests/integration/yamlparsing/GreetClientHttp.java
new file mode 100644
index 00000000000..d175a024b7e
--- /dev/null
+++ b/tests/integration/gh-5792-nima/src/main/java/io/helidon/tests/integration/yamlparsing/GreetClientHttp.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 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.integration.yamlparsing;
+
+import io.helidon.common.http.Http;
+import io.helidon.nima.webclient.WebClient;
+import io.helidon.nima.webclient.http1.Http1Client;
+
+/**
+ * Executable class that invokes HTTP/1 requests against the server.
+ */
+public class GreetClientHttp {
+ private GreetClientHttp() {
+ }
+
+ /**
+ * Main method.
+ *
+ * @param args ignored
+ */
+ public static void main(String[] args) {
+ Http1Client client = WebClient.builder()
+ .baseUri("http://localhost:8080/greet")
+ .build();
+
+ String response = client.method(Http.Method.GET)
+ .request()
+ .as(String.class);
+
+ System.out.println(response);
+
+ response = client.get("Nima")
+ .request()
+ .as(String.class);
+
+ System.out.println(response);
+ }
+}
diff --git a/tests/integration/gh-5792-nima/src/main/java/io/helidon/tests/integration/yamlparsing/GreetService.java b/tests/integration/gh-5792-nima/src/main/java/io/helidon/tests/integration/yamlparsing/GreetService.java
new file mode 100644
index 00000000000..c697910278f
--- /dev/null
+++ b/tests/integration/gh-5792-nima/src/main/java/io/helidon/tests/integration/yamlparsing/GreetService.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 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.integration.yamlparsing;
+
+import java.util.Collections;
+import java.util.concurrent.atomic.AtomicReference;
+
+import io.helidon.common.http.Http;
+import io.helidon.nima.webserver.http.HttpRules;
+import io.helidon.nima.webserver.http.HttpService;
+import io.helidon.nima.webserver.http.ServerRequest;
+import io.helidon.nima.webserver.http.ServerResponse;
+
+import jakarta.json.Json;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.JsonObject;
+
+/**
+ * A simple service to greet you. Examples:
+ *
+ * Get default greeting message:
+ * {@code curl -X GET http://localhost:8080/greet}
+ *
+ * Get greeting message for Joe:
+ * {@code curl -X GET http://localhost:8080/greet/Joe}
+ *
+ * Change greeting
+ * {@code curl -X PUT -H "Content-Type: application/json" -d '{"greeting" : "Howdy"}' http://localhost:8080/greet/greeting}
+ *
+ * The message is returned as a JSON object
+ */
+class GreetService implements HttpService {
+
+ private static final JsonBuilderFactory JSON = Json.createBuilderFactory(Collections.emptyMap());
+
+ /**
+ * The config value for the key {@code greeting}.
+ */
+ private final AtomicReference greeting = new AtomicReference<>();
+
+ GreetService() {
+ greeting.set("Hello");
+ }
+
+ /**
+ * A service registers itself by updating the routing rules.
+ *
+ * @param rules the routing rules.
+ */
+ @Override
+ public void routing(HttpRules rules) {
+ rules
+ .get("/", this::getDefaultMessageHandler)
+ .get("/{name}", this::getMessageHandler)
+ .put("/greeting", this::updateGreetingHandler);
+ }
+
+ /**
+ * Return a worldly greeting message.
+ *
+ * @param request the server request
+ * @param response the server response
+ */
+ private void getDefaultMessageHandler(ServerRequest request,
+ ServerResponse response) {
+ sendResponse(response, "World");
+ }
+
+ /**
+ * Return a greeting message using the name that was provided.
+ *
+ * @param request the server request
+ * @param response the server response
+ */
+ private void getMessageHandler(ServerRequest request,
+ ServerResponse response) {
+ String name = request.path().pathParameters().value("name");
+ sendResponse(response, name);
+ }
+
+ private void sendResponse(ServerResponse response, String name) {
+ String msg = String.format("%s %s!", greeting.get(), name);
+
+ JsonObject returnObject = JSON.createObjectBuilder()
+ .add("message", msg)
+ .build();
+ response.send(returnObject);
+ }
+
+ private void updateGreetingFromJson(JsonObject jo, ServerResponse response) {
+
+ if (!jo.containsKey("greeting")) {
+ JsonObject jsonErrorObject = JSON.createObjectBuilder()
+ .add("error", "No greeting provided")
+ .build();
+ response.status(Http.Status.BAD_REQUEST_400)
+ .send(jsonErrorObject);
+ return;
+ }
+
+ greeting.set(jo.getString("greeting"));
+ response.status(Http.Status.NO_CONTENT_204).send();
+ }
+
+ /**
+ * Set the greeting to use in future messages.
+ *
+ * @param request the server request
+ * @param response the server response
+ */
+ private void updateGreetingHandler(ServerRequest request,
+ ServerResponse response) {
+ updateGreetingFromJson(request.content().as(JsonObject.class), response);
+ }
+
+}
diff --git a/tests/integration/gh-5792-nima/src/main/java/io/helidon/tests/integration/yamlparsing/Main.java b/tests/integration/gh-5792-nima/src/main/java/io/helidon/tests/integration/yamlparsing/Main.java
new file mode 100644
index 00000000000..022c8c6bdd1
--- /dev/null
+++ b/tests/integration/gh-5792-nima/src/main/java/io/helidon/tests/integration/yamlparsing/Main.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 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.integration.yamlparsing;
+
+import io.helidon.logging.common.LogConfig;
+import io.helidon.nima.openapi.OpenApiService;
+import io.helidon.nima.webserver.WebServer;
+import io.helidon.nima.webserver.http.HttpRouting;
+
+/**
+ * The application main class.
+ */
+public final class Main {
+
+ /**
+ * Cannot be instantiated.
+ */
+ private Main() {
+ }
+
+ /**
+ * Application main entry point.
+ * @param args command line arguments.
+ */
+ public static void main(final String[] args) {
+ // load logging configuration
+ LogConfig.configureRuntime();
+
+ WebServer server = WebServer.builder()
+ .routing(Main::routing)
+ .start();
+
+ System.out.println("WEB server is up! http://localhost:" + server.port() + "/greet");
+ }
+
+ /**
+ * Updates HTTP Routing.
+ */
+ static void routing(HttpRouting.Builder routing) {
+
+ OpenApiService openApiService = OpenApiService.builder()
+ .staticFile("target/classes/petstore.yaml")
+ .build();
+
+ GreetService greetService = new GreetService();
+
+ routing.register("/greet", greetService)
+ .register(openApiService);
+ }
+}
diff --git a/tests/integration/gh-5792-nima/src/main/java/io/helidon/tests/integration/yamlparsing/package-info.java b/tests/integration/gh-5792-nima/src/main/java/io/helidon/tests/integration/yamlparsing/package-info.java
new file mode 100644
index 00000000000..b81dd6a2525
--- /dev/null
+++ b/tests/integration/gh-5792-nima/src/main/java/io/helidon/tests/integration/yamlparsing/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 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.
+ */
+
+/**
+ * Integration test to make sure apps can use the older release of SnakeYAML if needed.
+ */
+package io.helidon.tests.integration.yamlparsing;
diff --git a/tests/integration/gh-5792-nima/src/main/resources/application.yaml b/tests/integration/gh-5792-nima/src/main/resources/application.yaml
new file mode 100644
index 00000000000..63c5f08a061
--- /dev/null
+++ b/tests/integration/gh-5792-nima/src/main/resources/application.yaml
@@ -0,0 +1,18 @@
+#
+# Copyright (c) 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.
+server:
+ port: 8080
+ host: 0.0.0.0
+
diff --git a/tests/integration/gh-5792-nima/src/main/resources/logging.properties b/tests/integration/gh-5792-nima/src/main/resources/logging.properties
new file mode 100644
index 00000000000..e70b8888d96
--- /dev/null
+++ b/tests/integration/gh-5792-nima/src/main/resources/logging.properties
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 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.
+handlers=java.util.logging.ConsoleHandler
+java.util.logging.SimpleFormatter.format=%1$tY.%1$tm.%1$td %1$tH:%1$tM:%1$tS.%1$tL %5$s%6$s%n
+# Global logging level. Can be overridden by specific loggers
+.level=INFO
+io.helidon.nima.level=INFO
diff --git a/tests/integration/gh-5792-nima/src/main/resources/petstore.yaml b/tests/integration/gh-5792-nima/src/main/resources/petstore.yaml
new file mode 100644
index 00000000000..aefd6ea97e0
--- /dev/null
+++ b/tests/integration/gh-5792-nima/src/main/resources/petstore.yaml
@@ -0,0 +1,124 @@
+#
+# Copyright (c) 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.
+#
+openapi: "3.0.0"
+info:
+ version: 1.0.0
+ title: Swagger Petstore
+ license:
+ name: MIT
+servers:
+ - url: http://petstore.swagger.io/v1
+paths:
+ /pets:
+ get:
+ summary: List all pets
+ operationId: listPets
+ tags:
+ - pets
+ parameters:
+ - name: limit
+ in: query
+ description: How many items to return at one time (max 100)
+ required: false
+ schema:
+ type: integer
+ format: int32
+ responses:
+ "200":
+ description: An paged array of pets
+ headers:
+ x-next:
+ description: A link to the next page of responses
+ schema:
+ type: string
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Pets"
+ default:
+ description: unexpected error
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+ post:
+ summary: Create a pet
+ operationId: createPets
+ tags:
+ - pets
+ responses:
+ "201":
+ description: Null response
+ default:
+ description: unexpected error
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+ /pets/{petId}:
+ get:
+ summary: Info for a specific pet
+ operationId: showPetById
+ tags:
+ - pets
+ parameters:
+ - name: petId
+ in: path
+ required: true
+ description: The id of the pet to retrieve
+ schema:
+ type: string
+ responses:
+ "200":
+ description: Expected response to a valid request
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Pets"
+ default:
+ description: unexpected error
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+components:
+ schemas:
+ Pet:
+ required:
+ - id
+ - name
+ properties:
+ id:
+ type: integer
+ format: int64
+ name:
+ type: string
+ tag:
+ type: string
+ Pets:
+ type: array
+ items:
+ $ref: "#/components/schemas/Pet"
+ Error:
+ required:
+ - code
+ - message
+ properties:
+ code:
+ type: integer
+ format: int32
+ message:
+ type: string
\ No newline at end of file
diff --git a/tests/integration/gh-5792-nima/src/test/java/io/helidon/tests/integration/yamlparsing/AbstractMainTest.java b/tests/integration/gh-5792-nima/src/test/java/io/helidon/tests/integration/yamlparsing/AbstractMainTest.java
new file mode 100644
index 00000000000..ce241888e8a
--- /dev/null
+++ b/tests/integration/gh-5792-nima/src/test/java/io/helidon/tests/integration/yamlparsing/AbstractMainTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 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.integration.yamlparsing;
+
+
+import io.helidon.common.http.Http;
+import io.helidon.nima.testing.junit5.webserver.SetUpRoute;
+import io.helidon.nima.webclient.http1.Http1Client;
+import io.helidon.nima.webclient.http1.Http1ClientResponse;
+import io.helidon.nima.webserver.http.HttpRouting;
+
+import org.junit.jupiter.api.Test;
+import jakarta.json.JsonObject;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.is;
+
+abstract class AbstractMainTest {
+ private final Http1Client client;
+
+ protected AbstractMainTest(Http1Client client) {
+ this.client = client;
+ }
+
+ @SetUpRoute
+ static void routing(HttpRouting.Builder builder) {
+ Main.routing(builder);
+ }
+
+
+ @Test
+ void testRootRoute() {
+ try (Http1ClientResponse response = client.get("/greet")
+ .request()) {
+
+ assertThat(response.status(), is(Http.Status.OK_200));
+ JsonObject json = response.as(JsonObject.class);
+ assertThat(json.getString("message"), is("Hello World!"));
+ }
+ }
+
+ @Test
+ void testOpenApi() {
+ try (Http1ClientResponse response = client.get("/openapi").request()) {
+ assertThat("/openapi status", response.status(), is(Http.Status.OK_200));
+ assertThat("/openapi content", response.as(String.class), containsString("title: Swagger Petstore"));
+ }
+ }
+
+}
diff --git a/tests/integration/gh-5792-nima/src/test/java/io/helidon/tests/integration/yamlparsing/MainIT.java b/tests/integration/gh-5792-nima/src/test/java/io/helidon/tests/integration/yamlparsing/MainIT.java
new file mode 100644
index 00000000000..2fc907f441f
--- /dev/null
+++ b/tests/integration/gh-5792-nima/src/test/java/io/helidon/tests/integration/yamlparsing/MainIT.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 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.integration.yamlparsing;
+
+import io.helidon.nima.testing.junit5.webserver.ServerTest;
+import io.helidon.nima.webclient.http1.Http1Client;
+
+@ServerTest
+class MainIT extends AbstractMainTest {
+ MainIT(Http1Client client) {
+ super(client);
+ }
+}
\ No newline at end of file
diff --git a/tests/integration/gh-5792-nima/src/test/java/io/helidon/tests/integration/yamlparsing/MainTest.java b/tests/integration/gh-5792-nima/src/test/java/io/helidon/tests/integration/yamlparsing/MainTest.java
new file mode 100644
index 00000000000..5c7a5e3a8ac
--- /dev/null
+++ b/tests/integration/gh-5792-nima/src/test/java/io/helidon/tests/integration/yamlparsing/MainTest.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 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.integration.yamlparsing;
+
+import io.helidon.nima.testing.junit5.webserver.DirectClient;
+import io.helidon.nima.testing.junit5.webserver.RoutingTest;
+
+@RoutingTest
+class MainTest extends AbstractMainTest {
+ MainTest(DirectClient client) {
+ super(client);
+ }
+}
\ No newline at end of file
diff --git a/tests/integration/gh-5792-nima/src/test/resources/application.yaml b/tests/integration/gh-5792-nima/src/test/resources/application.yaml
new file mode 100644
index 00000000000..850e85592c4
--- /dev/null
+++ b/tests/integration/gh-5792-nima/src/test/resources/application.yaml
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 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.
+server:
+ port: 0
+ host: 0.0.0.0
+
+app:
+ greeting: "Hello"
\ No newline at end of file
diff --git a/tests/integration/gh-5792/README.md b/tests/integration/gh-5792/README.md
new file mode 100644
index 00000000000..fc289363cc6
--- /dev/null
+++ b/tests/integration/gh-5792/README.md
@@ -0,0 +1,126 @@
+# helidon-tests-integration-yaml-parsing
+
+Sample Helidon SE project that includes multiple REST operations.
+
+## Build and run
+
+
+With JDK19+
+```bash
+mvn package
+java --enable-preview -jar target/helidon-tests-integration-yaml-parsing.jar
+```
+
+## Exercise the application
+```
+curl -X GET http://localhost:8080/simple-greet
+{"message":"Hello World!"}
+```
+```
+curl -X GET http://localhost:8080/greet
+{"message":"Hello World!"}
+
+curl -X GET http://localhost:8080/greet/Joe
+{"message":"Hello Joe!"}
+
+curl -X PUT -H "Content-Type: application/json" -d '{"greeting" : "Hola"}' http://localhost:8080/greet/greeting
+
+curl -X GET http://localhost:8080/greet/Jose
+{"message":"Hola Jose!"}
+```
+
+
+## Try metrics
+
+```
+# Prometheus Format
+curl -s -X GET http://localhost:8080/metrics
+# TYPE base:gc_g1_young_generation_count gauge
+. . .
+
+# JSON Format
+curl -H 'Accept: application/json' -X GET http://localhost:8080/metrics
+{"base":...
+. . .
+```
+
+
+## Try health
+
+```
+curl -s -X GET http://localhost:8080/health
+{"outcome":"UP",...
+
+```
+
+
+## Building a Native Image
+
+Make sure you have GraalVM locally installed:
+
+```
+$GRAALVM_HOME/bin/native-image --version
+```
+
+Build the native image using the native image profile:
+
+```
+mvn package -Pnative-image
+```
+
+This uses the helidon-maven-plugin to perform the native compilation using your installed copy of GraalVM. It might take a while to complete.
+Once it completes start the application using the native executable (no JVM!):
+
+```
+./target/helidon-tests-integration-yaml-parsing
+```
+
+Yep, it starts fast. You can exercise the application’s endpoints as before.
+## Building the Docker Image
+
+```
+docker build -t helidon-tests-integration-yaml-parsing .
+```
+
+## Running the Docker Image
+
+```
+docker run --rm -p 8080:8080 helidon-tests-integration-yaml-parsing:latest
+```
+
+Exercise the application as described above.
+
+## Building a Custom Runtime Image
+
+Build the custom runtime image using the jlink image profile:
+
+```
+mvn package -Pjlink-image
+```
+
+This uses the helidon-maven-plugin to perform the custom image generation.
+After the build completes it will report some statistics about the build including the reduction in image size.
+
+The target/helidon-tests-integration-yaml-parsing-jri directory is a self contained custom image of your application. It contains your application,
+its runtime dependencies and the JDK modules it depends on. You can start your application using the provide start script:
+
+```
+./target/helidon-tests-integration-yaml-parsing-jri/bin/start
+```
+
+Class Data Sharing (CDS) Archive
+Also included in the custom image is a Class Data Sharing (CDS) archive that improves your application’s startup
+performance and in-memory footprint. You can learn more about Class Data Sharing in the JDK documentation.
+
+The CDS archive increases your image size to get these performance optimizations. It can be of significant size (tens of MB).
+The size of the CDS archive is reported at the end of the build output.
+
+If you’d rather have a smaller image size (with a slightly increased startup time) you can skip the creation of the CDS
+archive by executing your build like this:
+
+```
+mvn package -Pjlink-image -Djlink.image.addClassDataSharingArchive=false
+```
+
+For more information on available configuration options see the helidon-maven-plugin documentation.
+
\ No newline at end of file
diff --git a/tests/integration/gh-5792/pom.xml b/tests/integration/gh-5792/pom.xml
new file mode 100644
index 00000000000..2b90aa88269
--- /dev/null
+++ b/tests/integration/gh-5792/pom.xml
@@ -0,0 +1,113 @@
+
+
+
+
+ 4.0.0
+
+ io.helidon.applications
+ helidon-se
+ 4.0.0-SNAPSHOT
+ ../../../applications/se/pom.xml
+
+ io.helidon.tests.integration
+ helidon-tests-integration-yaml-parsing
+ 4.0.0-SNAPSHOT
+
+ Helidon SnakeYAML Earlier Version Test - Reactive
+
+ io.helidon.tests.integration.yamlparsing.Main
+ 1.32
+
+
+
+
+
+
+ org.yaml
+ snakeyaml
+ ${selectedSnakeYamlVersion}
+
+
+
+
+
+
+ io.helidon.reactive.webserver
+ helidon-reactive-webserver
+
+
+ io.helidon.reactive.media
+ helidon-reactive-media-jsonp
+
+
+ io.helidon.reactive.openapi
+ helidon-reactive-openapi
+
+
+ io.helidon.config
+ helidon-config-yaml
+
+
+ io.helidon.reactive.webclient
+ helidon-reactive-webclient
+ test
+
+
+ io.helidon.common
+ helidon-common-media-type
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ test
+
+
+ org.hamcrest
+ hamcrest-all
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+
+
+ copy-libs
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ ${selectedSnakeYamlVersion}
+
+
+
+
+
+
diff --git a/tests/integration/gh-5792/src/main/java/io/helidon/tests/integration/yamlparsing/GreetService.java b/tests/integration/gh-5792/src/main/java/io/helidon/tests/integration/yamlparsing/GreetService.java
new file mode 100644
index 00000000000..5389690545b
--- /dev/null
+++ b/tests/integration/gh-5792/src/main/java/io/helidon/tests/integration/yamlparsing/GreetService.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 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.integration.yamlparsing;
+
+import java.util.Collections;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import jakarta.json.Json;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.JsonException;
+import jakarta.json.JsonObject;
+
+import io.helidon.common.http.Http;
+import io.helidon.config.Config;
+import io.helidon.reactive.webserver.Routing;
+import io.helidon.reactive.webserver.ServerRequest;
+import io.helidon.reactive.webserver.ServerResponse;
+import io.helidon.reactive.webserver.Service;
+
+/**
+ * A simple service to greet you. Examples:
+ *
+ * Get default greeting message:
+ * curl -X GET http://localhost:8080/greet
+ *
+ * Get greeting message for Joe:
+ * curl -X GET http://localhost:8080/greet/Joe
+ *
+ * Change greeting
+ * curl -X PUT -H "Content-Type: application/json" -d '{"greeting" : "Howdy"}' http://localhost:8080/greet/greeting
+ *
+ * The message is returned as a JSON object
+ */
+
+public class GreetService implements Service {
+
+ /**
+ * The config value for the key {@code greeting}.
+ */
+ private final AtomicReference greeting = new AtomicReference<>();
+
+ private static final JsonBuilderFactory JSON = Json.createBuilderFactory(Collections.emptyMap());
+
+ private static final Logger LOGGER = Logger.getLogger(GreetService.class.getName());
+
+ GreetService(Config config) {
+ greeting.set(config.get("app.greeting").asString().orElse("Ciao"));
+ }
+
+ /**
+ * A service registers itself by updating the routing rules.
+ * @param rules the routing rules.
+ */
+ @Override
+ public void update(Routing.Rules rules) {
+ rules
+ .get("/", this::getDefaultMessageHandler)
+ .get("/{name}", this::getMessageHandler)
+ .put("/greeting", this::updateGreetingHandler);
+ }
+
+ /**
+ * Return a worldly greeting message.
+ * @param request the server request
+ * @param response the server response
+ */
+ private void getDefaultMessageHandler(ServerRequest request, ServerResponse response) {
+ sendResponse(response, "World");
+ }
+
+ /**
+ * Return a greeting message using the name that was provided.
+ * @param request the server request
+ * @param response the server response
+ */
+ private void getMessageHandler(ServerRequest request, ServerResponse response) {
+ String name = request.path().param("name");
+ sendResponse(response, name);
+ }
+
+ private void sendResponse(ServerResponse response, String name) {
+ String msg = String.format("%s %s!", greeting.get(), name);
+
+ JsonObject returnObject = JSON.createObjectBuilder()
+ .add("message", msg)
+ .build();
+ response.send(returnObject);
+ }
+
+ private static T processErrors(Throwable ex, ServerRequest request, ServerResponse response) {
+
+ if (ex.getCause() instanceof JsonException){
+
+ LOGGER.log(Level.FINE, "Invalid JSON", ex);
+ JsonObject jsonErrorObject = JSON.createObjectBuilder()
+ .add("error", "Invalid JSON")
+ .build();
+ response.status(Http.Status.BAD_REQUEST_400).send(jsonErrorObject);
+ } else {
+
+ LOGGER.log(Level.FINE, "Internal error", ex);
+ JsonObject jsonErrorObject = JSON.createObjectBuilder()
+ .add("error", "Internal error")
+ .build();
+ response.status(Http.Status.INTERNAL_SERVER_ERROR_500).send(jsonErrorObject);
+ }
+
+ return null;
+ }
+
+ private void updateGreetingFromJson(JsonObject jo, ServerResponse response) {
+ if (!jo.containsKey("greeting")) {
+ JsonObject jsonErrorObject = JSON.createObjectBuilder()
+ .add("error", "No greeting provided")
+ .build();
+ response.status(Http.Status.BAD_REQUEST_400)
+ .send(jsonErrorObject);
+ return;
+ }
+
+ greeting.set(jo.getString("greeting"));
+ response.status(Http.Status.NO_CONTENT_204).send();
+ }
+
+ /**
+ * Set the greeting to use in future messages.
+ * @param request the server request
+ * @param response the server response
+ */
+ private void updateGreetingHandler(ServerRequest request,
+ ServerResponse response) {
+ request.content().as(JsonObject.class)
+ .thenAccept(jo -> updateGreetingFromJson(jo, response))
+ .exceptionally(ex -> processErrors(ex, request, response));
+ }
+}
diff --git a/tests/integration/gh-5792/src/main/java/io/helidon/tests/integration/yamlparsing/Main.java b/tests/integration/gh-5792/src/main/java/io/helidon/tests/integration/yamlparsing/Main.java
new file mode 100644
index 00000000000..b85da78e8c8
--- /dev/null
+++ b/tests/integration/gh-5792/src/main/java/io/helidon/tests/integration/yamlparsing/Main.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 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.integration.yamlparsing;
+
+
+import io.helidon.reactive.media.jsonp.JsonpSupport;
+import io.helidon.logging.common.LogConfig;
+import io.helidon.common.reactive.Single;
+import io.helidon.config.Config;
+import io.helidon.reactive.openapi.OpenAPISupport;
+import io.helidon.reactive.webserver.Routing;
+import io.helidon.reactive.webserver.WebServer;
+
+/**
+ * The application main class.
+ */
+public final class Main {
+
+ /**
+ * 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 Single startServer() {
+
+ // load logging configuration
+ LogConfig.configureRuntime();
+
+ // By default this will pick up application.yaml from the classpath
+ Config config = Config.create();
+
+ WebServer server = WebServer.builder(createRouting(config))
+ .config(config.get("server"))
+ .addMediaSupport(JsonpSupport.create()) .build();
+
+ Single webserver = server.start();
+
+ // Try to start the server. If successful, print some info and arrange to
+ // print a message at shutdown. If unsuccessful, print the exception.
+ webserver.thenAccept(ws -> {
+ System.out.println("WEB server is up! http://localhost:" + ws.port() + "/greet");
+ ws.whenShutdown().thenRun(() -> System.out.println("WEB server is DOWN. Good bye!"));
+ })
+ .exceptionallyAccept(t -> {
+ System.err.println("Startup failed: " + t.getMessage());
+ t.printStackTrace(System.err);
+ });
+
+ return webserver;
+ }
+
+ /**
+ * Creates new {@link io.helidon.reactive.webserver.Routing}.
+ *
+ * @return routing configured with JSON support, a health check, and a service
+ * @param config configuration of this server
+ */
+ private static Routing createRouting(Config config) {
+ SimpleGreetService simpleGreetService = new SimpleGreetService(config);
+ GreetService greetService = new GreetService(config);
+ OpenAPISupport openApiSupport = OpenAPISupport.builder()
+ .staticFile("target/classes/petstore.yaml")
+ .build();
+ Routing.Builder builder = Routing.builder()
+ .register(openApiSupport)
+ .register("/simple-greet", simpleGreetService)
+ .register("/greet", greetService);
+
+
+ return builder.build();
+ }
+}
diff --git a/tests/integration/gh-5792/src/main/java/io/helidon/tests/integration/yamlparsing/SimpleGreetService.java b/tests/integration/gh-5792/src/main/java/io/helidon/tests/integration/yamlparsing/SimpleGreetService.java
new file mode 100644
index 00000000000..0c9f98a0278
--- /dev/null
+++ b/tests/integration/gh-5792/src/main/java/io/helidon/tests/integration/yamlparsing/SimpleGreetService.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 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.integration.yamlparsing;
+
+import java.util.Collections;
+import java.util.logging.Logger;
+
+import jakarta.json.Json;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.JsonObject;
+
+import io.helidon.config.Config;
+import io.helidon.reactive.webserver.Routing;
+import io.helidon.reactive.webserver.ServerRequest;
+import io.helidon.reactive.webserver.ServerResponse;
+import io.helidon.reactive.webserver.Service;
+
+/**
+ * A simple service to greet you. Examples:
+ *
+ * Get default greeting message:
+ * curl -X GET http://localhost:8080/simple-greet
+ *
+ * The message is returned as a JSON object
+ */
+public class SimpleGreetService implements Service {
+
+ private static final Logger LOGGER = Logger.getLogger(SimpleGreetService.class.getName());
+ private static final JsonBuilderFactory JSON = Json.createBuilderFactory(Collections.emptyMap());
+
+ private final String greeting;
+
+ SimpleGreetService(Config config) {
+ greeting = config.get("app.greeting").asString().orElse("Ciao");
+ }
+
+
+ /**
+ * A service registers itself by updating the routing rules.
+ *
+ * @param rules the routing rules.
+ */
+ @Override
+ public void update(Routing.Rules rules) {
+ rules.get("/", this::getDefaultMessageHandler);
+ rules.get("/greet-count", this::countAccess, this::getDefaultMessageHandler);
+ }
+
+ /**
+ * Return a worldly greeting message.
+ *
+ * @param request the server request
+ * @param response the server response
+ */
+ private void getDefaultMessageHandler(ServerRequest request, ServerResponse response) {
+ String msg = String.format("%s %s!", greeting, "World");
+ LOGGER.info("Greeting message is " + msg);
+ JsonObject returnObject = JSON.createObjectBuilder()
+ .add("message", msg)
+ .build();
+ response.send(returnObject);
+ }
+
+
+ private void countAccess(ServerRequest request, ServerResponse response) {
+ request.next();
+ }
+}
diff --git a/tests/integration/gh-5792/src/main/java/io/helidon/tests/integration/yamlparsing/package-info.java b/tests/integration/gh-5792/src/main/java/io/helidon/tests/integration/yamlparsing/package-info.java
new file mode 100644
index 00000000000..d754dcafe1b
--- /dev/null
+++ b/tests/integration/gh-5792/src/main/java/io/helidon/tests/integration/yamlparsing/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 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.
+ */
+
+/**
+ * Tests of YAML parsing with an older SnakeYAML release.
+ */
+package io.helidon.tests.integration.yamlparsing;
diff --git a/tests/integration/gh-5792/src/main/resources/application.yaml b/tests/integration/gh-5792/src/main/resources/application.yaml
new file mode 100644
index 00000000000..a62827b24ef
--- /dev/null
+++ b/tests/integration/gh-5792/src/main/resources/application.yaml
@@ -0,0 +1,21 @@
+#
+# Copyright (c) 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.
+
+server:
+ port: 8080
+ host: 0.0.0.0
+
+app:
+ greeting: "Hello"
diff --git a/tests/integration/gh-5792/src/main/resources/logging.properties b/tests/integration/gh-5792/src/main/resources/logging.properties
new file mode 100644
index 00000000000..b0b8dcf9994
--- /dev/null
+++ b/tests/integration/gh-5792/src/main/resources/logging.properties
@@ -0,0 +1,33 @@
+#
+# Copyright (c) 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/integration/gh-5792/src/main/resources/petstore.yaml b/tests/integration/gh-5792/src/main/resources/petstore.yaml
new file mode 100644
index 00000000000..b15eb29dac1
--- /dev/null
+++ b/tests/integration/gh-5792/src/main/resources/petstore.yaml
@@ -0,0 +1,124 @@
+#
+# Copyright (c) 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.
+#
+openapi: "3.0.0"
+info:
+ version: 1.0.0
+ title: Swagger Petstore
+ license:
+ name: MIT
+servers:
+ - url: http://petstore.swagger.io/v1
+paths:
+ /pets:
+ get:
+ summary: List all pets
+ operationId: listPets
+ tags:
+ - pets
+ parameters:
+ - name: limit
+ in: query
+ description: How many items to return at one time (max 100)
+ required: false
+ schema:
+ type: integer
+ format: int32
+ responses:
+ "200":
+ description: An paged array of pets
+ headers:
+ x-next:
+ description: A link to the next page of responses
+ schema:
+ type: string
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Pets"
+ default:
+ description: unexpected error
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+ post:
+ summary: Create a pet
+ operationId: createPets
+ tags:
+ - pets
+ responses:
+ "201":
+ description: Null response
+ default:
+ description: unexpected error
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+ /pets/{petId}:
+ get:
+ summary: Info for a specific pet
+ operationId: showPetById
+ tags:
+ - pets
+ parameters:
+ - name: petId
+ in: path
+ required: true
+ description: The id of the pet to retrieve
+ schema:
+ type: string
+ responses:
+ "200":
+ description: Expected response to a valid request
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Pets"
+ default:
+ description: unexpected error
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+components:
+ schemas:
+ Pet:
+ required:
+ - id
+ - name
+ properties:
+ id:
+ type: integer
+ format: int64
+ name:
+ type: string
+ tag:
+ type: string
+ Pets:
+ type: array
+ items:
+ $ref: "#/components/schemas/Pet"
+ Error:
+ required:
+ - code
+ - message
+ properties:
+ code:
+ type: integer
+ format: int32
+ message:
+ type: string
diff --git a/tests/integration/gh-5792/src/test/java/io/helidon/tests/integration/yamlparsing/MainTest.java b/tests/integration/gh-5792/src/test/java/io/helidon/tests/integration/yamlparsing/MainTest.java
new file mode 100644
index 00000000000..82a6a6188f7
--- /dev/null
+++ b/tests/integration/gh-5792/src/test/java/io/helidon/tests/integration/yamlparsing/MainTest.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 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.integration.yamlparsing;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.TimeUnit;
+import java.util.Collections;
+import jakarta.json.Json;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.JsonObject;
+
+import io.helidon.common.media.type.MediaTypes;
+import io.helidon.reactive.media.jsonp.JsonpSupport;
+import io.helidon.reactive.webclient.WebClient;
+import io.helidon.reactive.webclient.WebClientResponse;
+import io.helidon.reactive.webserver.WebServer;
+
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+
+class MainTest {
+
+ private static final JsonBuilderFactory JSON_BUILDER = Json.createBuilderFactory(Collections.emptyMap());
+ private static final JsonObject TEST_JSON_OBJECT = JSON_BUILDER.createObjectBuilder()
+ .add("greeting", "Hola")
+ .build();
+ private static WebServer webServer;
+ private static WebClient webClient;
+
+ @BeforeAll
+ static void startTheServer() {
+ webServer = Main.startServer().await();
+
+ webClient = WebClient.builder()
+ .baseUri("http://localhost:" + webServer.port())
+ .addMediaSupport(JsonpSupport.create())
+ .build();
+ }
+
+ @AfterAll
+ static void stopServer() throws ExecutionException, InterruptedException, TimeoutException {
+ if (webServer != null) {
+ webServer.shutdown()
+ .toCompletableFuture()
+ .get(10, TimeUnit.SECONDS);
+ }
+ }
+
+ @Test
+ void testOpenApi() {
+ String get = webClient.get()
+ .path("/openapi")
+ .accept(MediaTypes.APPLICATION_OPENAPI_YAML)
+ .request(String.class)
+ .await();
+
+ assertThat(get, containsString("title: Swagger Petstore"));
+ }
+
+ @Test
+ void testSimpleGreet() {
+ JsonObject jsonObject = webClient.get()
+ .path("/simple-greet")
+ .request(JsonObject.class)
+ .await();
+ assertThat(jsonObject.getString("message"), is("Hello World!"));
+ }
+
+ @Test
+ void testGreetings() {
+ JsonObject jsonObject;
+ WebClientResponse response;
+
+ jsonObject = webClient.get()
+ .path("/greet/Joe")
+ .request(JsonObject.class)
+ .await();
+ assertThat(jsonObject.getString("message"), is("Hello Joe!"));
+
+ response = webClient.put()
+ .path("/greet/greeting")
+ .submit(TEST_JSON_OBJECT)
+ .await();
+ assertThat(response.status().code(), is(204));
+
+ jsonObject = webClient.get()
+ .path("/greet/Joe")
+ .request(JsonObject.class)
+ .await();
+ assertThat(jsonObject.getString("message"), is("Hola Joe!"));
+ }
+
+ @Test
+ void verifySnakeYamlVersion() {
+ String selectedSnakeYamlVersion = System.getProperty("selected-snakeyaml-version");
+ assertThat("Spec of selected SnakeYAML version", selectedSnakeYamlVersion, is(notNullValue()));
+
+ String classpath = System.getProperty("java.class.path");
+ assertThat("SnakeYAML version in classpath",
+ classpath,
+ containsString("snakeyaml-" + selectedSnakeYamlVersion));
+ }
+}
diff --git a/tests/integration/gh-5792/src/test/resources/application.yaml b/tests/integration/gh-5792/src/test/resources/application.yaml
new file mode 100644
index 00000000000..e7a165b42dd
--- /dev/null
+++ b/tests/integration/gh-5792/src/test/resources/application.yaml
@@ -0,0 +1,23 @@
+#
+# Copyright (c) 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.
+server:
+ port: 0
+ host: 0.0.0.0
+
+app:
+ greeting: "Hello"
+
+security:
+ enabled: false
diff --git a/tests/integration/pom.xml b/tests/integration/pom.xml
index f3faa7ded5c..2fba593105b 100644
--- a/tests/integration/pom.xml
+++ b/tests/integration/pom.xml
@@ -71,6 +71,8 @@
native-image
vault
oidc
+ gh-5792
+ gh-5792-nima