From 6245cec12073b0561399444722d8e0b897bd6ae4 Mon Sep 17 00:00:00 2001 From: Claus Ibsen Date: Sat, 11 Jul 2026 14:26:38 +0200 Subject: [PATCH] CAMEL-24004: Generated REST DSL always emits type on param definitions The XML model writer skips attributes matching their default value, so type="path" (the default for ParamDefinition) was omitted from the generated XML. The YAML and XML generators now ensure the type attribute is always present in the output. Co-Authored-By: Claude Opus 4.6 Signed-off-by: Claus Ibsen --- .../generator/openapi/RestDslXmlGenerator.java | 10 ++++++++++ .../openapi/RestDslYamlGenerator.java | 13 ++++++++----- .../src/test/resources/GreetingsYaml.txt | 3 +++ .../test/resources/OpenApiV302PetstoreYaml.txt | 9 +++++++++ .../OpenApiV3PetstoreWithModelYaml.txt | 9 +++++++++ .../OpenApiV3PetstoreWithRestComponentXml.txt | 18 +++++++++--------- .../OpenApiV3PetstoreWithRestComponentYaml.txt | 9 +++++++++ .../test/resources/OpenApiV3PetstoreXml.txt | 18 +++++++++--------- .../test/resources/OpenApiV3PetstoreYaml.txt | 9 +++++++++ 9 files changed, 75 insertions(+), 23 deletions(-) diff --git a/tooling/openapi-rest-dsl-generator/src/main/java/org/apache/camel/generator/openapi/RestDslXmlGenerator.java b/tooling/openapi-rest-dsl-generator/src/main/java/org/apache/camel/generator/openapi/RestDslXmlGenerator.java index 29279ab33c0e9..d9fde58ce0d75 100644 --- a/tooling/openapi-rest-dsl-generator/src/main/java/org/apache/camel/generator/openapi/RestDslXmlGenerator.java +++ b/tooling/openapi-rest-dsl-generator/src/main/java/org/apache/camel/generator/openapi/RestDslXmlGenerator.java @@ -80,6 +80,16 @@ public String generate(final CamelContext context) throws Exception { element.removeAttribute("customId"); } + // ensure param elements always have the type attribute + // (the XML writer omits it when the value is the default "path") + final NodeList params = document.getElementsByTagName("param"); + for (int i = 0; i < params.getLength(); i++) { + final Element param = (Element) params.item(i); + if (!param.hasAttribute("type")) { + param.setAttribute("type", "path"); + } + } + boolean restConfig = restComponent != null || restContextPath != null || clientRequestValidation; if (restConfig) { final Element configuration = document.createElement("restConfiguration"); diff --git a/tooling/openapi-rest-dsl-generator/src/main/java/org/apache/camel/generator/openapi/RestDslYamlGenerator.java b/tooling/openapi-rest-dsl-generator/src/main/java/org/apache/camel/generator/openapi/RestDslYamlGenerator.java index 55d1bc9084c8d..439c09bb16cf2 100644 --- a/tooling/openapi-rest-dsl-generator/src/main/java/org/apache/camel/generator/openapi/RestDslYamlGenerator.java +++ b/tooling/openapi-rest-dsl-generator/src/main/java/org/apache/camel/generator/openapi/RestDslYamlGenerator.java @@ -260,24 +260,27 @@ private static void fixParamNodes(XmlMapper xmlMapper, JsonNode node, String ver on.set("param", arr); p = arr; } - // fix required to be boolean type if (p != null) { for (JsonNode pc : p) { - JsonNode r = pc.get("required"); + ObjectNode on = (ObjectNode) pc; + // ensure type is always present (XML writer omits the default "path") + if (on.get("type") == null) { + on.put("type", "path"); + } + // fix required to be boolean type + JsonNode r = on.get("required"); if (r != null) { String t = r.textValue(); boolean b = Boolean.parseBoolean(t); - ObjectNode on = (ObjectNode) pc; BooleanNode bn = xmlMapper.createObjectNode().booleanNode(b); on.set("required", bn); } String k = "allowableValues"; - r = pc.get(k); + r = on.get(k); if (r != null) { // remove value node JsonNode v = r.get("value"); if (v.isArray()) { - ObjectNode on = (ObjectNode) pc; on.set(k, v); on.remove("value"); } diff --git a/tooling/openapi-rest-dsl-generator/src/test/resources/GreetingsYaml.txt b/tooling/openapi-rest-dsl-generator/src/test/resources/GreetingsYaml.txt index 99350e4c2789a..d4745b36e2c29 100644 --- a/tooling/openapi-rest-dsl-generator/src/test/resources/GreetingsYaml.txt +++ b/tooling/openapi-rest-dsl-generator/src/test/resources/GreetingsYaml.txt @@ -6,6 +6,7 @@ produces: "*/*" param: - name: "name" + type: "path" to: "direct:greeting-api" post: - id: "post-greeting-api" @@ -13,10 +14,12 @@ produces: "*/*" param: - name: "name" + type: "path" to: "direct:post-greeting-api" - id: "bye-api" path: "/bye/{name}" produces: "*/*" param: - name: "name" + type: "path" to: "direct:bye-api" diff --git a/tooling/openapi-rest-dsl-generator/src/test/resources/OpenApiV302PetstoreYaml.txt b/tooling/openapi-rest-dsl-generator/src/test/resources/OpenApiV302PetstoreYaml.txt index c1d70abd4ca23..1c8dbae7b8505 100644 --- a/tooling/openapi-rest-dsl-generator/src/test/resources/OpenApiV302PetstoreYaml.txt +++ b/tooling/openapi-rest-dsl-generator/src/test/resources/OpenApiV302PetstoreYaml.txt @@ -18,6 +18,7 @@ param: - description: "name that need to be deleted" name: "username" + type: "path" - description: "Update an existent user in the store" name: "body" type: "body" @@ -39,6 +40,7 @@ - dataType: "integer" description: "ID of pet that needs to be updated" name: "petId" + type: "path" - collectionFormat: "multi" description: "Name of pet that needs to be updated" name: "name" @@ -58,6 +60,7 @@ - dataType: "integer" description: "ID of pet to update" name: "petId" + type: "path" - collectionFormat: "multi" description: "Additional Metadata" name: "additionalMetadata" @@ -132,6 +135,7 @@ - dataType: "integer" description: "ID of pet to return" name: "petId" + type: "path" to: "direct:getPetById" - id: "getInventory" path: "/store/inventory" @@ -147,6 +151,7 @@ - dataType: "integer" description: "ID of order that needs to be fetched" name: "orderId" + type: "path" to: "direct:getOrderById" - id: "loginUser" path: "/user/login" @@ -172,6 +177,7 @@ param: - description: "The name that needs to be fetched. Use user1 for testing. " name: "username" + type: "path" to: "direct:getUserByName" delete: - id: "deletePet" @@ -183,6 +189,7 @@ - dataType: "integer" description: "Pet id to delete" name: "petId" + type: "path" to: "direct:deletePet" - id: "deleteOrder" path: "/store/order/{orderId}" @@ -192,6 +199,7 @@ - dataType: "integer" description: "ID of the order that needs to be deleted" name: "orderId" + type: "path" to: "direct:deleteOrder" - id: "deleteUser" path: "/user/{username}" @@ -199,4 +207,5 @@ param: - description: "The name that needs to be deleted" name: "username" + type: "path" to: "direct:deleteUser" diff --git a/tooling/openapi-rest-dsl-generator/src/test/resources/OpenApiV3PetstoreWithModelYaml.txt b/tooling/openapi-rest-dsl-generator/src/test/resources/OpenApiV3PetstoreWithModelYaml.txt index bab2cdea7e4ab..cae6eb13d715d 100644 --- a/tooling/openapi-rest-dsl-generator/src/test/resources/OpenApiV3PetstoreWithModelYaml.txt +++ b/tooling/openapi-rest-dsl-generator/src/test/resources/OpenApiV3PetstoreWithModelYaml.txt @@ -18,6 +18,7 @@ param: - description: "name that need to be updated" name: "username" + type: "path" - description: "Updated user object" name: "body" type: "body" @@ -46,6 +47,7 @@ - dataType: "integer" description: "ID of pet that needs to be updated" name: "petId" + type: "path" - description: "Updated name of the pet" name: "name" type: "formData" @@ -62,6 +64,7 @@ - dataType: "integer" description: "ID of pet to update" name: "petId" + type: "path" - description: "Additional data to pass to server" name: "additionalMetadata" type: "formData" @@ -143,6 +146,7 @@ - dataType: "integer" description: "ID of pet to return" name: "petId" + type: "path" to: "direct:getPetById" - id: "getInventory" path: "/store/inventory" @@ -159,6 +163,7 @@ - dataType: "integer" description: "ID of pet that needs to be fetched" name: "orderId" + type: "path" to: "direct:getOrderById" - id: "loginUser" path: "/user/login" @@ -183,6 +188,7 @@ param: - description: "The name that needs to be fetched. Use user1 for testing. " name: "username" + type: "path" to: "direct:getUserByName" delete: - id: "deletePet" @@ -194,6 +200,7 @@ - dataType: "integer" description: "Pet id to delete" name: "petId" + type: "path" to: "direct:deletePet" - id: "deleteOrder" path: "/store/order/{orderId}" @@ -203,6 +210,7 @@ - dataType: "integer" description: "ID of the order that needs to be deleted" name: "orderId" + type: "path" to: "direct:deleteOrder" - id: "deleteUser" path: "/user/{username}" @@ -210,4 +218,5 @@ param: - description: "The name that needs to be deleted" name: "username" + type: "path" to: "direct:deleteUser" diff --git a/tooling/openapi-rest-dsl-generator/src/test/resources/OpenApiV3PetstoreWithRestComponentXml.txt b/tooling/openapi-rest-dsl-generator/src/test/resources/OpenApiV3PetstoreWithRestComponentXml.txt index 851e3e705f429..2032366ce4edd 100644 --- a/tooling/openapi-rest-dsl-generator/src/test/resources/OpenApiV3PetstoreWithRestComponentXml.txt +++ b/tooling/openapi-rest-dsl-generator/src/test/resources/OpenApiV3PetstoreWithRestComponentXml.txt @@ -20,22 +20,22 @@ - + - + - + - + @@ -48,11 +48,11 @@ - + - + @@ -76,16 +76,16 @@ - + - + - + diff --git a/tooling/openapi-rest-dsl-generator/src/test/resources/OpenApiV3PetstoreWithRestComponentYaml.txt b/tooling/openapi-rest-dsl-generator/src/test/resources/OpenApiV3PetstoreWithRestComponentYaml.txt index 0b8312dd09bc0..bc69dd21ea6c8 100644 --- a/tooling/openapi-rest-dsl-generator/src/test/resources/OpenApiV3PetstoreWithRestComponentYaml.txt +++ b/tooling/openapi-rest-dsl-generator/src/test/resources/OpenApiV3PetstoreWithRestComponentYaml.txt @@ -19,6 +19,7 @@ param: - description: "name that need to be updated" name: "username" + type: "path" - description: "Updated user object" name: "body" type: "body" @@ -46,6 +47,7 @@ - dataType: "integer" description: "ID of pet that needs to be updated" name: "petId" + type: "path" - description: "Updated name of the pet" name: "name" type: "formData" @@ -61,6 +63,7 @@ - dataType: "integer" description: "ID of pet to update" name: "petId" + type: "path" - description: "Additional data to pass to server" name: "additionalMetadata" type: "formData" @@ -134,6 +137,7 @@ - dataType: "integer" description: "ID of pet to return" name: "petId" + type: "path" to: "direct:getPetById" - id: "getInventory" path: "/store/inventory" @@ -149,6 +153,7 @@ - dataType: "integer" description: "ID of pet that needs to be fetched" name: "orderId" + type: "path" to: "direct:getOrderById" - id: "loginUser" path: "/user/login" @@ -172,6 +177,7 @@ param: - description: "The name that needs to be fetched. Use user1 for testing. " name: "username" + type: "path" to: "direct:getUserByName" delete: - id: "deletePet" @@ -183,6 +189,7 @@ - dataType: "integer" description: "Pet id to delete" name: "petId" + type: "path" to: "direct:deletePet" - id: "deleteOrder" path: "/store/order/{orderId}" @@ -192,6 +199,7 @@ - dataType: "integer" description: "ID of the order that needs to be deleted" name: "orderId" + type: "path" to: "direct:deleteOrder" - id: "deleteUser" path: "/user/{username}" @@ -199,4 +207,5 @@ param: - description: "The name that needs to be deleted" name: "username" + type: "path" to: "direct:deleteUser" diff --git a/tooling/openapi-rest-dsl-generator/src/test/resources/OpenApiV3PetstoreXml.txt b/tooling/openapi-rest-dsl-generator/src/test/resources/OpenApiV3PetstoreXml.txt index 2a44a015a9921..e0691a03aaaff 100644 --- a/tooling/openapi-rest-dsl-generator/src/test/resources/OpenApiV3PetstoreXml.txt +++ b/tooling/openapi-rest-dsl-generator/src/test/resources/OpenApiV3PetstoreXml.txt @@ -18,22 +18,22 @@ - + - + - + - + @@ -46,11 +46,11 @@ - + - + @@ -74,16 +74,16 @@ - + - + - + diff --git a/tooling/openapi-rest-dsl-generator/src/test/resources/OpenApiV3PetstoreYaml.txt b/tooling/openapi-rest-dsl-generator/src/test/resources/OpenApiV3PetstoreYaml.txt index 04387681f199a..8de4ef21f3493 100644 --- a/tooling/openapi-rest-dsl-generator/src/test/resources/OpenApiV3PetstoreYaml.txt +++ b/tooling/openapi-rest-dsl-generator/src/test/resources/OpenApiV3PetstoreYaml.txt @@ -16,6 +16,7 @@ param: - description: "name that need to be updated" name: "username" + type: "path" - description: "Updated user object" name: "body" type: "body" @@ -43,6 +44,7 @@ - dataType: "integer" description: "ID of pet that needs to be updated" name: "petId" + type: "path" - description: "Updated name of the pet" name: "name" type: "formData" @@ -58,6 +60,7 @@ - dataType: "integer" description: "ID of pet to update" name: "petId" + type: "path" - description: "Additional data to pass to server" name: "additionalMetadata" type: "formData" @@ -131,6 +134,7 @@ - dataType: "integer" description: "ID of pet to return" name: "petId" + type: "path" to: "direct:getPetById" - id: "getInventory" path: "/store/inventory" @@ -146,6 +150,7 @@ - dataType: "integer" description: "ID of pet that needs to be fetched" name: "orderId" + type: "path" to: "direct:getOrderById" - id: "loginUser" path: "/user/login" @@ -169,6 +174,7 @@ param: - description: "The name that needs to be fetched. Use user1 for testing. " name: "username" + type: "path" to: "direct:getUserByName" delete: - id: "deletePet" @@ -180,6 +186,7 @@ - dataType: "integer" description: "Pet id to delete" name: "petId" + type: "path" to: "direct:deletePet" - id: "deleteOrder" path: "/store/order/{orderId}" @@ -189,6 +196,7 @@ - dataType: "integer" description: "ID of the order that needs to be deleted" name: "orderId" + type: "path" to: "direct:deleteOrder" - id: "deleteUser" path: "/user/{username}" @@ -196,4 +204,5 @@ param: - description: "The name that needs to be deleted" name: "username" + type: "path" to: "direct:deleteUser"