This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch openapi2 in repository https://gitbox.apache.org/repos/asf/camel.git
commit f3434923f8f8f293eb2a72841d638a21812ca861 Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Mon Mar 25 10:27:09 2024 +0100 CAMEL-20557: Rest DSL to use openapi spec directly --- .../vertx/PlatformHttpRestOpenApiConsumerTest.java | 56 ++++++++++++++++++++++ .../rest/openapi/RestOpenApiProcessor.java | 35 ++++++-------- 2 files changed, 71 insertions(+), 20 deletions(-) diff --git a/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/PlatformHttpRestOpenApiConsumerTest.java b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/PlatformHttpRestOpenApiConsumerTest.java index ab01d018caa..6c9865ecb59 100644 --- a/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/PlatformHttpRestOpenApiConsumerTest.java +++ b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/PlatformHttpRestOpenApiConsumerTest.java @@ -54,4 +54,60 @@ public class PlatformHttpRestOpenApiConsumerTest { } } + @Test + public void testRestOpenApiNotFound() throws Exception { + final CamelContext context = VertxPlatformHttpEngineTest.createCamelContext(); + + try { + context.addRoutes(new RouteBuilder() { + @Override + public void configure() { + from("rest-openapi:classpath:openapi-v3.json") + .log("dummy"); + + from("direct:getPetById") + .setBody().constant("{\"pet\": \"tony the tiger\"}"); + } + }); + + context.start(); + + given() + .when() + .get("/api/v3/pet/123/unknown") + .then() + .statusCode(404); + } finally { + context.stop(); + } + } + + @Test + public void testRestOpenApiNotAllowed() throws Exception { + final CamelContext context = VertxPlatformHttpEngineTest.createCamelContext(); + + try { + context.addRoutes(new RouteBuilder() { + @Override + public void configure() { + from("rest-openapi:classpath:openapi-v3.json") + .log("dummy"); + + from("direct:getPetById") + .setBody().constant("{\"pet\": \"tony the tiger\"}"); + } + }); + + context.start(); + + given() + .when() + .put("/api/v3/pet/123") + .then() + .statusCode(405); + } finally { + context.stop(); + } + } + } diff --git a/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/RestOpenApiProcessor.java b/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/RestOpenApiProcessor.java index 283327a3c6a..f0c8bb351a7 100644 --- a/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/RestOpenApiProcessor.java +++ b/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/RestOpenApiProcessor.java @@ -17,12 +17,11 @@ package org.apache.camel.component.rest.openapi; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; -import java.util.concurrent.RejectedExecutionException; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.Operation; -import io.swagger.v3.oas.models.PathItem; import org.apache.camel.AsyncCallback; import org.apache.camel.CamelContext; import org.apache.camel.CamelContextAware; @@ -34,6 +33,9 @@ import org.apache.camel.support.service.ServiceHelper; public class RestOpenApiProcessor extends DelegateAsyncProcessor implements CamelContextAware { + private static final List<String> METHODS + = Arrays.asList("GET", "HEAD", "POST", "PUT", "DELETE", "TRACE", "OPTIONS", "CONNECT", "PATCH"); + private CamelContext camelContext; private final OpenAPI openAPI; private final String basePath; @@ -68,9 +70,7 @@ public class RestOpenApiProcessor extends DelegateAsyncProcessor implements Came @Override public boolean process(Exchange exchange, AsyncCallback callback) { // TODO: check if valid operation according to OpenApi - // TODO: validate GET/POST etc // TODO: RequestValidator - // TODO: 404 and so on // TODO: binding String path = exchange.getMessage().getHeader(Exchange.HTTP_PATH, String.class); @@ -86,26 +86,21 @@ public class RestOpenApiProcessor extends DelegateAsyncProcessor implements Came return restOpenapiProcessorStrategy.process(o, path, exchange, callback); } - // no operation found so it's a 404 - exchange.setException(new RejectedExecutionException()); - exchange.getMessage().setHeader(Exchange.HTTP_RESPONSE_CODE, 404); + // okay we cannot process this requires so return either 404 or 405. + // to know if its 405 then we need to check if any other HTTP method would have a consumer for the "same" request + final String contextPath = path; + boolean hasAnyMethod + = METHODS.stream().anyMatch(v -> RestConsumerContextPathMatcher.matchBestPath(v, contextPath, paths) != null); + if (hasAnyMethod) { + exchange.getMessage().setHeader(Exchange.HTTP_RESPONSE_CODE, 405); + } else { + exchange.getMessage().setHeader(Exchange.HTTP_RESPONSE_CODE, 404); + } + exchange.setRouteStop(true); callback.done(true); return true; } - protected Operation asOperation(PathItem item, String verb) { - return switch (verb) { - case "GET" -> item.getGet(); - case "DELETE" -> item.getDelete(); - case "HEAD" -> item.getHead(); - case "PATCH" -> item.getPatch(); - case "OPTIONS" -> item.getOptions(); - case "PUT" -> item.getPut(); - case "POST" -> item.getPost(); - default -> null; - }; - } - @Override protected void doBuild() throws Exception { super.doBuild();