forked from helidon-io/helidon
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Minimalistic SE OpenAPI support with SPI to implement the MicroProfile support and OpenAPI UI - Make openapi a multi-module with two sub-modules: openapi and openapi-ui - Add openapi/tests and move helidon-iogh-5792 from tests/integration - Re-enabled test, make it strictly a test (not an app) and use version.lib.snakeyaml to override the SnakeYAML version - Created OpenApiFormat to formalize what was before OpenApiFeature.OpenAPIMediaType - Microprofile OpenAPI refactorings: - MPOpenAPIBuilder into FilteredIndexViewsBuilder as a utility to create List<FilteredIndexView> - MpOpenApiManager implements OpenApiManager using SmallRye OpenAPI (what was before in MpOpenApiFeature - Prefix utility classes with OpenApi: - ParserHelper -> OpenApiParser - Serializer -> OpenApiSerializer - Renamed HelidonAnnotationScannerExtension to JsonpAnnotationScannerExtension to remove 'Helidon' from the class name - Renamed tests to use Test as a suffix instead of prefix - Updated examples/openapi to remove the in-memory model related features (i.e. reader, filter) - Renamed examples/microprofile/openapi-basic to examples/microprofile/openapi (to be symetrical with SE) - Updated tests to use new testing patterns (i.e. helidon-microprofile-testing-junit5 for MP and helidon-webserver-testing-junit5 for SE) - Generated config docs for openapi/openapi, openapi/openapi-ui, microprofile/openapi (Removed old files) Fixes helidon-io#7247 (SE OpenAPI static file support) Fixes helidon-io#7240 (Fix helidon-iogh-5792 integration test) Fixes helidon-io#6130 (Port OpenAPI UI integration to 4.x) Fixes helidon-io#7643 (OpenAPI parsing fails to handle default in some cases) Fixes helidon-io#7668 (Routing path with optional sequence not supported)
- Loading branch information
1 parent
480446f
commit 4d02968
Showing
131 changed files
with
5,988 additions
and
5,815 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
141 changes: 141 additions & 0 deletions
141
common/testing/junit5/src/main/java/io/helidon/common/testing/junit5/MapMatcher.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
/* | ||
* 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.common.testing.junit5; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Iterator; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
import org.hamcrest.Description; | ||
import org.hamcrest.Matcher; | ||
import org.hamcrest.TypeSafeMatcher; | ||
|
||
/** | ||
* Hamcrest matchers for {@link java.util.Map}. | ||
*/ | ||
public final class MapMatcher { | ||
private MapMatcher() { | ||
} | ||
|
||
/** | ||
* A matcher for an {@link java.util.Map} that performs a deep equality. | ||
* <p> | ||
* Usage example: | ||
* <pre> | ||
* assertThat(actualMap, isMapEqualTo(expectedMap)); | ||
* </pre> | ||
* | ||
* This method targets trees implemented using {@link java.util.Map} where values of type {@link java.util.Map} | ||
* are considered tree nodes, and values with other types are considered leaf nodes. | ||
* <p> | ||
* The deep-equality is performed by diffing a flat string representation of each map. If the diff yields no differences, | ||
* the maps are considered deeply equal. | ||
* <p> | ||
* The entries are compared using strings, both keys and leaf nodes must implement {@link Object#toString()}. | ||
* | ||
* @param expected expected map | ||
* @param <K> type of the map keys | ||
* @param <V> type of the map values | ||
* @return matcher validating the {@link java.util.Map} is deeply equal | ||
*/ | ||
public static <K, V> Matcher<Map<K, V>> mapEqualTo(Map<K, V> expected) { | ||
return new DiffMatcher<>(expected); | ||
} | ||
|
||
private static final class DiffMatcher<K, V> extends TypeSafeMatcher<Map<K, V>> { | ||
|
||
private final Map<K, V> expected; | ||
private volatile Map<K, V> actual; | ||
private volatile List<Diff> diffs; | ||
|
||
private DiffMatcher(Map<K, V> expected) { | ||
this.expected = expected; | ||
} | ||
|
||
@Override | ||
protected boolean matchesSafely(Map<K, V> actual) { | ||
this.actual = actual; | ||
this.diffs = diffs(expected, actual); | ||
return diffs.isEmpty(); | ||
} | ||
|
||
@Override | ||
public void describeTo(Description description) { | ||
description.appendText("deep map equality"); | ||
} | ||
|
||
@Override | ||
protected void describeMismatchSafely(Map<K, V> item, Description mismatchDescription) { | ||
List<Diff> diffs = actual == item ? this.diffs : diffs(expected, item); | ||
mismatchDescription.appendText("found differences" + System.lineSeparator()) | ||
.appendText(String.join(System.lineSeparator(), diffs.stream().map(Diff::toString).toList())); | ||
} | ||
|
||
private static List<Diff> diffs(Map<?, ?> left, Map<?, ?> right) { | ||
List<Diff> diffs = new ArrayList<>(); | ||
Iterator<Map.Entry<String, String>> leftEntries = flattenEntries(left, "").iterator(); | ||
Iterator<Map.Entry<String, String>> rightEntries = flattenEntries(right, "").iterator(); | ||
while (true) { | ||
boolean hasLeft = leftEntries.hasNext(); | ||
boolean hasRight = rightEntries.hasNext(); | ||
if (hasLeft && hasRight) { | ||
Map.Entry<String, String> leftEntry = leftEntries.next(); | ||
Map.Entry<String, String> rightEntry = rightEntries.next(); | ||
if (!leftEntry.equals(rightEntry)) { | ||
diffs.add(new Diff(leftEntry, rightEntry)); | ||
} | ||
} else if (hasLeft) { | ||
diffs.add(new Diff(leftEntries.next(), null)); | ||
} else if (hasRight) { | ||
diffs.add(new Diff(null, rightEntries.next())); | ||
} else { | ||
return diffs; | ||
} | ||
} | ||
} | ||
|
||
private static List<Map.Entry<String, String>> flattenEntries(Map<?, ?> map, String prefix) { | ||
List<Map.Entry<String, String>> result = new ArrayList<>(); | ||
for (Map.Entry<?, ?> entry : map.entrySet()) { | ||
if (entry.getValue() instanceof Map<?, ?> node) { | ||
result.addAll(flattenEntries(node, prefix + entry.getKey() + ".")); | ||
} else { | ||
result.add(Map.entry(prefix + entry.getKey(), entry.getValue().toString())); | ||
} | ||
} | ||
result.sort(Map.Entry.comparingByKey()); | ||
return result; | ||
} | ||
|
||
private record Diff(Map.Entry<String, String> left, Map.Entry<String, String> right) { | ||
|
||
@Override | ||
public String toString() { | ||
if (left == null && right != null) { | ||
return "ADDED >> " + right; | ||
} | ||
if (left != null && right == null) { | ||
return "REMOVED << " + left; | ||
} | ||
if (left != null) { | ||
return "ADDED >> " + left + System.lineSeparator() + "REMOVED << " + right; | ||
} | ||
return "?"; | ||
} | ||
} | ||
} | ||
} |
43 changes: 43 additions & 0 deletions
43
common/testing/junit5/src/test/java/io/helidon/common/testing/MapMatcherTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/* | ||
* 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.common.testing; | ||
|
||
import java.util.Map; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
import static io.helidon.common.testing.junit5.MapMatcher.mapEqualTo; | ||
import static org.hamcrest.Matchers.is; | ||
import static org.hamcrest.MatcherAssert.assertThat; | ||
import static org.hamcrest.Matchers.not; | ||
|
||
class MapMatcherTest { | ||
|
||
@Test | ||
void testIsMapEqual() { | ||
assertThat(Map.of("foo", "bar"), is(mapEqualTo(Map.of("foo", "bar")))); | ||
assertThat(Map.of("bar", "foo"), is(not(mapEqualTo(Map.of("foo", "bar"))))); | ||
|
||
assertThat(Map.of("foo", Map.of("bar", Map.of("bob", "alice"))), | ||
is(mapEqualTo(Map.of("foo", Map.of("bar", Map.of("bob", "alice")))))); | ||
|
||
assertThat(Map.of("foo", Map.of("bar", Map.of("bob", "alice"))), | ||
is(not(mapEqualTo(Map.of("foo", Map.of("bar", Map.of("bob", "not-alice"))))))); | ||
|
||
assertThat(Map.of("foo", "bar", "bob", "alice"), is(mapEqualTo(Map.of("bob", "alice", "foo", "bar")))); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 52 additions & 0 deletions
52
docs/config/io_helidon_microprofile_openapi_MpOpenApiManagerConfig.adoc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/////////////////////////////////////////////////////////////////////////////// | ||
|
||
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. | ||
|
||
/////////////////////////////////////////////////////////////////////////////// | ||
ifndef::rootdir[:rootdir: {docdir}/..] | ||
:description: Configuration of io.helidon.microprofile.openapi.MpOpenApiManagerConfig | ||
:keywords: helidon, config, io.helidon.microprofile.openapi.MpOpenApiManagerConfig | ||
:basic-table-intro: The table below lists the configuration keys that configure io.helidon.microprofile.openapi.MpOpenApiManagerConfig | ||
include::{rootdir}/includes/attributes.adoc[] | ||
= MpOpenApiManagerConfig (microprofile.openapi) Configuration | ||
// tag::config[] | ||
Type: link:{javadoc-base-url}/io.helidon.microprofile.openapi/io/helidon/microprofile/openapi/MpOpenApiManagerConfig.html[io.helidon.microprofile.openapi.MpOpenApiManagerConfig] | ||
== Configuration options | ||
.Optional configuration options | ||
[cols="3,3a,2,5a"] | ||
|=== | ||
|key |type |default value |description | ||
|`mp.openapi.extensions.helidon.use-jaxrs-semantics` |boolean |{nbsp} |If `true` and the `jakarta.ws.rs.core.Application` class returns a non-empty set, endpoints defined by | ||
other resources are not included in the OpenAPI document. | ||
@return `true` if enabled, `false` otherwise | ||
|=== | ||
// end::config[] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/////////////////////////////////////////////////////////////////////////////// | ||
|
||
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. | ||
|
||
/////////////////////////////////////////////////////////////////////////////// | ||
ifndef::rootdir[:rootdir: {docdir}/..] | ||
:description: Configuration of io.helidon.openapi.OpenApiFeature | ||
:keywords: helidon, config, io.helidon.openapi.OpenApiFeature | ||
:basic-table-intro: The table below lists the configuration keys that configure io.helidon.openapi.OpenApiFeature | ||
include::{rootdir}/includes/attributes.adoc[] | ||
= OpenApiFeature (openapi) Configuration | ||
// tag::config[] | ||
Type: link:{javadoc-base-url}/io.helidon.openapi/io/helidon/openapi/OpenApiFeature.html[io.helidon.openapi.OpenApiFeature] | ||
This is a standalone configuration type, prefix from configuration root: `openapi` | ||
== Configuration options | ||
.Optional configuration options | ||
[cols="3,3a,2,5a"] | ||
|=== | ||
|key |type |default value |description | ||
|`cors` |xref:{rootdir}/config/io_helidon_cors_CrossOriginConfig.adoc[CrossOriginConfig] |{nbsp} |CORS config. | ||
@return CORS config | ||
|`enabled` |boolean |`true` |Sets whether the feature should be enabled. | ||
@return `true` if enabled, `false` otherwise | ||
|`manager` |io.helidon.openapi.OpenApiManager (service provider interface) |{nbsp} |OpenAPI manager. | ||
@return the OpenAPI manager | ||
|`services` |io.helidon.openapi.OpenApiService[] (service provider interface) |{nbsp} |OpenAPI services. | ||
@return the OpenAPI services | ||
|`static-file` |string |{nbsp} |Path of the static OpenAPI document file. Default types are `json`, `yaml`, and `yml`. | ||
@return location of the static OpenAPI document file | ||
|`web-context` |string |`/openapi` |Web context path for the OpenAPI endpoint. | ||
@return webContext to use | ||
|=== | ||
// end::config[] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.