You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2024/03/28 14:40:48 UTC

(camel) 34/38: CAMEL-20557: Rest DSL to use openapi spec directly

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 e5b688c502a41564ed8a2308d902aab456b3baf8
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed Mar 27 14:45:06 2024 +0100

    CAMEL-20557: Rest DSL to use openapi spec directly
---
 ...PlatformHttpRestOpenApiConsumerRestDslTest.java |  3 +-
 .../rest/openapi/RestOpenApiEndpoint.java          |  4 +-
 .../org/apache/camel/model/rest/openApi.json       |  5 +-
 .../apache/camel/model/rest/OpenApiDefinition.java | 67 +++++++++++++++++-----
 .../apache/camel/model/rest/RestDefinition.java    | 20 +++----
 .../java/org/apache/camel/xml/in/ModelParser.java  |  1 +
 .../java/org/apache/camel/xml/out/ModelWriter.java |  1 +
 .../org/apache/camel/yaml/out/ModelWriter.java     |  1 +
 8 files changed, 69 insertions(+), 33 deletions(-)

diff --git a/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/PlatformHttpRestOpenApiConsumerRestDslTest.java b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/PlatformHttpRestOpenApiConsumerRestDslTest.java
index b836248ab33..c659090e47a 100644
--- a/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/PlatformHttpRestOpenApiConsumerRestDslTest.java
+++ b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/PlatformHttpRestOpenApiConsumerRestDslTest.java
@@ -213,8 +213,7 @@ public class PlatformHttpRestOpenApiConsumerRestDslTest {
             context.addRoutes(new RouteBuilder() {
                 @Override
                 public void configure() {
-                    rest().clientRequestValidation(true)
-                            .openApi().specification("openapi-v3.json").missingOperation("ignore");
+                    rest().openApi().specification("openapi-v3.json").missingOperation("ignore").requestValidationEnabled();
 
                     from("direct:updatePet")
                             .setBody().constant("{\"pet\": \"tony the tiger\"}");
diff --git a/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/RestOpenApiEndpoint.java b/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/RestOpenApiEndpoint.java
index 0a29a7c18b5..da2620cb248 100644
--- a/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/RestOpenApiEndpoint.java
+++ b/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/RestOpenApiEndpoint.java
@@ -36,7 +36,6 @@ import java.util.stream.Stream;
 import com.atlassian.oai.validator.OpenApiInteractionValidator;
 import com.atlassian.oai.validator.report.LevelResolver;
 import com.atlassian.oai.validator.report.ValidationReport;
-import io.swagger.parser.OpenAPIParser;
 import io.swagger.v3.oas.models.OpenAPI;
 import io.swagger.v3.oas.models.Operation;
 import io.swagger.v3.oas.models.PathItem;
@@ -48,6 +47,7 @@ import io.swagger.v3.oas.models.security.SecurityRequirement;
 import io.swagger.v3.oas.models.security.SecurityScheme;
 import io.swagger.v3.oas.models.security.SecurityScheme.In;
 import io.swagger.v3.oas.models.servers.Server;
+import io.swagger.v3.parser.OpenAPIV3Parser;
 import io.swagger.v3.parser.core.models.ParseOptions;
 import io.swagger.v3.parser.core.models.SwaggerParseResult;
 import org.apache.camel.CamelContext;
@@ -902,7 +902,7 @@ public final class RestOpenApiEndpoint extends DefaultEndpoint {
      * @return              the specification
      */
     static OpenAPI loadSpecificationFrom(final CamelContext camelContext, final String uri) {
-        final OpenAPIParser openApiParser = new OpenAPIParser();
+        final OpenAPIV3Parser openApiParser = new OpenAPIV3Parser();
         final ParseOptions options = new ParseOptions();
         options.setResolveFully(true);
 
diff --git a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/rest/openApi.json b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/rest/openApi.json
index f1292c7c300..2d064458544 100644
--- a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/rest/openApi.json
+++ b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/rest/openApi.json
@@ -17,7 +17,8 @@
     "disabled": { "index": 2, "kind": "attribute", "displayName": "Disabled", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to disable all the REST services from the OpenAPI contract from the route during build time. Once an REST service has been disabled then it cannot be enabled later at runtime." },
     "specification": { "index": 3, "kind": "attribute", "displayName": "Specification", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Path to the OpenApi specification file." },
     "routeId": { "index": 4, "kind": "attribute", "displayName": "Route Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the id of the route" },
-    "missingOperation": { "index": 5, "kind": "attribute", "displayName": "Missing Operation", "required": false, "type": "enum", "javaType": "java.lang.String", "enum": [ "fail", "ignore", "mock" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "fail", "description": "Whether to fail, ignore or return a mock response for OpenAPI operations that are not mapped to a corresponding route." },
-    "mockIncludePattern": { "index": 6, "kind": "attribute", "displayName": "Mock Include Pattern", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "classpath:camel-mock\/**", "description": "Used for inclusive filtering of mock data from directories. The pattern is using Ant-path style pattern. Multiple patterns can be specified separated by comma." }
+    "requestValidationEnabled": { "index": 5, "kind": "attribute", "displayName": "Request Validation Enabled", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to enable validation of the client request to check that the request contains valid and expected data." },
+    "missingOperation": { "index": 6, "kind": "attribute", "displayName": "Missing Operation", "required": false, "type": "enum", "javaType": "java.lang.String", "enum": [ "fail", "ignore", "mock" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "fail", "description": "Whether to fail, ignore or return a mock response for OpenAPI operations that are not mapped to a corresponding route." },
+    "mockIncludePattern": { "index": 7, "kind": "attribute", "displayName": "Mock Include Pattern", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "classpath:camel-mock\/**", "description": "Used for inclusive filtering of mock data from directories. The pattern is using Ant-path style pattern. Multiple patterns can be specified separated by comma." }
   }
 }
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/rest/OpenApiDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/rest/OpenApiDefinition.java
index 91183e54fee..6579c6837e1 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/model/rest/OpenApiDefinition.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/rest/OpenApiDefinition.java
@@ -46,6 +46,9 @@ public class OpenApiDefinition extends OptionalIdentifiedDefinition<OpenApiDefin
     @Metadata(label = "advanced", javaType = "java.lang.Boolean")
     private String disabled;
     @XmlAttribute
+    @Metadata(javaType = "java.lang.Boolean")
+    private String requestValidationEnabled;
+    @XmlAttribute
     @Metadata(enums = "fail,ignore,mock", defaultValue = "fail")
     private String missingOperation;
     @XmlAttribute
@@ -94,12 +97,24 @@ public class OpenApiDefinition extends OptionalIdentifiedDefinition<OpenApiDefin
         this.disabled = disabled;
     }
 
+    public String getRequestValidationEnabled() {
+        return requestValidationEnabled;
+    }
+
+    /**
+     * Whether to enable validation of the client request to check that the request contains valid and expected data.
+     */
+    public void setRequestValidationEnabled(String requestValidationEnabled) {
+        this.requestValidationEnabled = requestValidationEnabled;
+    }
+
     public String getMissingOperation() {
         return missingOperation;
     }
 
     /**
-     * Whether to fail, ignore or return a mock response for OpenAPI operations that are not mapped to a corresponding route.
+     * Whether to fail, ignore or return a mock response for OpenAPI operations that are not mapped to a corresponding
+     * route.
      */
     public void setMissingOperation(String missingOperation) {
         this.missingOperation = missingOperation;
@@ -110,8 +125,8 @@ public class OpenApiDefinition extends OptionalIdentifiedDefinition<OpenApiDefin
     }
 
     /**
-     * Used for inclusive filtering of mock data from directories. The pattern is using Ant-path style pattern.
-     * Multiple patterns can be specified separated by comma.
+     * Used for inclusive filtering of mock data from directories. The pattern is using Ant-path style pattern. Multiple
+     * patterns can be specified separated by comma.
      */
     public void setMockIncludePattern(String mockIncludePattern) {
         this.mockIncludePattern = mockIncludePattern;
@@ -140,8 +155,8 @@ public class OpenApiDefinition extends OptionalIdentifiedDefinition<OpenApiDefin
     }
 
     /**
-     * Whether to enable api-doc that exposes the OpenAPI specification file as a REST endpoint.
-     * This allows clients to obtain the specification from the running Camel application.
+     * Whether to enable api-doc that exposes the OpenAPI specification file as a REST endpoint. This allows clients to
+     * obtain the specification from the running Camel application.
      */
     public OpenApiDefinition apiContextPath(String apiDoc) {
         this.apiContextPath = apiDoc;
@@ -149,8 +164,31 @@ public class OpenApiDefinition extends OptionalIdentifiedDefinition<OpenApiDefin
     }
 
     /**
-     * Whether to disable the OpenAPI entirely. Once the OpenAPI has been disabled then it cannot be
-     * enabled later at runtime.
+     * Whether to enable validation of the client request to check that the request contains valid and expected data.
+     */
+    public OpenApiDefinition requestValidationEnabled(String requestValidationEnabled) {
+        this.requestValidationEnabled = requestValidationEnabled;
+        return this;
+    }
+
+    /**
+     * Whether to enable validation of the client request to check that the request contains valid and expected data.
+     */
+    public OpenApiDefinition requestValidationEnabled(boolean requestValidationEnabled) {
+        this.requestValidationEnabled = requestValidationEnabled ? "true" : "false";
+        return this;
+    }
+
+    /**
+     * Whether to enable validation of the client request to check that the request contains valid and expected data.
+     */
+    public OpenApiDefinition requestValidationEnabled() {
+        return requestValidationEnabled(true);
+    }
+
+    /**
+     * Whether to disable the OpenAPI entirely. Once the OpenAPI has been disabled then it cannot be enabled later at
+     * runtime.
      */
     public OpenApiDefinition disabled(String disabled) {
         this.disabled = disabled;
@@ -158,8 +196,8 @@ public class OpenApiDefinition extends OptionalIdentifiedDefinition<OpenApiDefin
     }
 
     /**
-     * Whether to disable the OpenAPI entirely. Once the OpenAPI has been disabled then it cannot be
-     * enabled later at runtime.
+     * Whether to disable the OpenAPI entirely. Once the OpenAPI has been disabled then it cannot be enabled later at
+     * runtime.
      */
     public OpenApiDefinition disabled(boolean disabled) {
         this.disabled = disabled ? "true" : "false";
@@ -167,15 +205,16 @@ public class OpenApiDefinition extends OptionalIdentifiedDefinition<OpenApiDefin
     }
 
     /**
-     * Whether to disable the OpenAPI entirely. Once the OpenAPI has been disabled then it cannot be
-     * enabled later at runtime.
+     * Whether to disable the OpenAPI entirely. Once the OpenAPI has been disabled then it cannot be enabled later at
+     * runtime.
      */
     public OpenApiDefinition disabled() {
         return disabled(true);
     }
 
     /**
-     * Whether to fail, ignore or return a mock response for OpenAPI operations that are not mapped to a corresponding route.
+     * Whether to fail, ignore or return a mock response for OpenAPI operations that are not mapped to a corresponding
+     * route.
      */
     public OpenApiDefinition missingOperation(String missingOperation) {
         this.missingOperation = missingOperation;
@@ -183,8 +222,8 @@ public class OpenApiDefinition extends OptionalIdentifiedDefinition<OpenApiDefin
     }
 
     /**
-     * Used for inclusive filtering of mock data from directories. The pattern is using Ant-path style pattern.
-     * Multiple patterns can be specified separated by comma.
+     * Used for inclusive filtering of mock data from directories. The pattern is using Ant-path style pattern. Multiple
+     * patterns can be specified separated by comma.
      */
     public OpenApiDefinition mockIncludePattern(String mockIncludePattern) {
         this.mockIncludePattern = mockIncludePattern;
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestDefinition.java
index f5d30621789..326e207d299 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestDefinition.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestDefinition.java
@@ -761,8 +761,8 @@ public class RestDefinition extends OptionalIdentifiedDefinition<RestDefinition>
      * The Camel endpoint this REST service will call, such as a direct endpoint to link to an existing route that
      * handles this REST call.
      *
-     * @param uri the uri of the endpoint
-     * @return this builder
+     * @param  uri the uri of the endpoint
+     * @return     this builder
      */
     public RestDefinition to(String uri) {
         // add to last verb
@@ -868,7 +868,8 @@ public class RestDefinition extends OptionalIdentifiedDefinition<RestDefinition>
             addRouteDefinition(camelContext, filter, answer, config.getComponent(), config.getProducerComponent());
         }
         if (openApi != null) {
-            addRouteDefinition(camelContext, openApi, answer, config.getComponent(), config.getProducerComponent(), config.getApiContextPath());
+            addRouteDefinition(camelContext, openApi, answer, config.getComponent(), config.getProducerComponent(),
+                    config.getApiContextPath());
         }
 
         return answer;
@@ -1007,15 +1008,8 @@ public class RestDefinition extends OptionalIdentifiedDefinition<RestDefinition>
         if (binding.getProduces() != null) {
             options.put("produces", binding.getProduces());
         }
-        if (component != null && !component.isEmpty()) {
-            options.put("consumerComponentName", component);
-        }
-        if (producerComponent != null && !producerComponent.isEmpty()) {
-            options.put("producerComponentName", producerComponent);
-        }
-        Boolean validate = parseBoolean(camelContext, getClientRequestValidation()); // TODO: move this to open-api so its all the same place
-        if (validate != null && validate) {
-            options.put("requestValidationEnabled", "true");
+        if (openApi.getRequestValidationEnabled() != null) {
+            options.put("requestValidationEnabled", openApi.getRequestValidationEnabled());
         }
         if (openApi.getMissingOperation() != null) {
             options.put("missingOperation", openApi.getMissingOperation());
@@ -1141,7 +1135,7 @@ public class RestDefinition extends OptionalIdentifiedDefinition<RestDefinition>
                 // register all the default values for the query and header parameters
                 RestParamType type = param.getType();
                 if ((RestParamType.query == type || RestParamType.header == type)
-                    && ObjectHelper.isNotEmpty(param.getDefaultValue())) {
+                        && ObjectHelper.isNotEmpty(param.getDefaultValue())) {
                     binding.addDefaultValue(param.getName(), parseText(camelContext, param.getDefaultValue()));
                 }
                 // register which parameters are required
diff --git a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
index aaefc3d2747..8482f81acde 100644
--- a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
+++ b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
@@ -3305,6 +3305,7 @@ public class ModelParser extends BaseParser {
                 case "disabled": def.setDisabled(val); break;
                 case "missingOperation": def.setMissingOperation(val); break;
                 case "mockIncludePattern": def.setMockIncludePattern(val); break;
+                case "requestValidationEnabled": def.setRequestValidationEnabled(val); break;
                 case "routeId": def.setRouteId(val); break;
                 case "specification": def.setSpecification(val); break;
                 default: return optionalIdentifiedDefinitionAttributeHandler().accept(def, key, val);
diff --git a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java
index b2d94894bf5..3c7bc4cce1b 100644
--- a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java
+++ b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java
@@ -4424,6 +4424,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("routeId", def.getRouteId());
         doWriteAttribute("specification", def.getSpecification());
         doWriteAttribute("disabled", def.getDisabled());
+        doWriteAttribute("requestValidationEnabled", def.getRequestValidationEnabled());
         doWriteElement("apiContextPath", def.getApiContextPath(), this::doWriteString);
         endElement(name);
     }
diff --git a/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java b/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java
index eecb2246f2d..2228cd84047 100644
--- a/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java
+++ b/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java
@@ -4424,6 +4424,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("routeId", def.getRouteId());
         doWriteAttribute("specification", def.getSpecification());
         doWriteAttribute("disabled", def.getDisabled());
+        doWriteAttribute("requestValidationEnabled", def.getRequestValidationEnabled());
         doWriteElement("apiContextPath", def.getApiContextPath(), this::doWriteString);
         endElement(name);
     }