Skip to content

CAMEL-24961: Catalog body types for netty, netty-http, jetty, servlet, undertow, cxf, cxfrs, spring-ws and four more - #28395

Closed
davsclaus wants to merge 1 commit into
mainfrom
feature/CAMEL-24961-body-types-http-servers
Closed

davsclaus wants to merge 1 commit into
mainfrom
feature/CAMEL-24961-body-types-http-servers

Conversation

@davsclaus

@davsclaus davsclaus commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Claude Code on behalf of davsclaus

This group adds the catalog body types (CAMEL-24961) for twelve HTTP, WebSocket and web service components: netty, netty-http, jetty, servlet, undertow, vertx-websocket, atmosphere-websocket, webhook, cxf, cxfrs, spring-ws and rest-postman. Each change is an @BodyTypes annotation on the Endpoint, plus the JSON it generates and the catalog copy. Five doc pages had their body text corrected.

What the catalog says now

Component Consumer Reply of the consumer Producer input Producer output
netty a String (the default codec has no TCP framing: textline=true gives one line each); byte[] with udpByteArrayCodec; a ByteBuf with allowDefaultCodec=false a String or a ByteBuf; any body with textline; no body closes the connection a String, or a ByteBuf over TCP; any body with textline the reply as a String (sync, the default); unchanged with sync=false
netty-http the request as a stream cache that can be read again; a ByteBuf with disableStreamCache text, bytes, a stream, a file or a value; no body gives 204 text, bytes, a stream or a file the response as byte[]
jetty, servlet the request as a stream cache (the raw stream with disableStreamCache); empty for a GET; null for Content-Length 0 text, bytes, a stream or a file
undertow HTTP: byte[] for POST, PUT and PATCH, null for the other methods, a Map for a form; WebSocket: a String or byte[] HTTP: text, bytes, a stream or a file HTTP: text, bytes, a stream or a file; WebSocket: to the peers of the endpoint HTTP: the response as byte[]; WebSocket: unchanged
vertx-websocket a String for a text frame, byte[] for a binary one; the ServerWebSocket for the OPEN event a String as text, byte[] as binary, other bodies as their toString unchanged
atmosphere-websocket a String or byte[]; InOnly, no reply text or a Reader as text, bytes or an InputStream as binary unchanged
webhook unknown: what the webhook handler of the delegate makes of the request any: the delegates set the response themselves
cxf by dataFormat: POJO a MessageContentsList of the parameters; PAYLOAD a CxfPayload; RAW the stream of the envelope; CXF_MESSAGE a SOAPMessage by dataFormat: the return value; the XML of the body; the envelope; a SOAPMessage or a Source by dataFormat, as the reply by dataFormat, as the consumer
cxfrs Default binding: a MessageContentsList; SimpleConsumer: the entity as the method declares it a Response, text, bytes, a stream, a file, or a bean that a JAX-RS provider writes the entity; the parameters of the method with httpClientAPI=false a jakarta.ws.rs.core.Response; the return value of the method with httpClientAPI=false
spring-ws the payload as a Source (format xml) XML as text, bytes, a stream, a Source or a DOM the same the response as a Source, or null
rest-postman the request body, as platform-http gives it to direct:<requestId> text, bytes or a stream one request: text, bytes, a stream or a file; a folder or the whole collection ignores the body one request: the response stream; a folder or a collection: a List of PostmanRunResult

Where an HTTP server answers with a Map, a List or a POJO, the description says to marshal it first, as it does for platform-http.

Checked at runtime. The throwaway tests below are not part of the PR.

  • netty: real TCP and UDP sockets.
  • jetty, servlet (in the Undertow servlet container), undertow, atmosphere-websocket and netty-http: a java.net.http client and WebSocket.
  • vertx-websocket: as server and as client.
  • cxf: all four data formats, as consumer, reply and producer.
  • cxfrs: the Default and SimpleConsumer bindings, and the HTTP and proxy APIs.
  • spring-ws: an in-memory message sender.
  • rest-postman: WireMock behind the producer, and platform-http-vertx for the consumer.

The tests sent text, bytes, a stream, a file, a Map, a List, a POJO, a number and no body, and logged the class of the body after each step.

Not run:

  • the transferException deserialization and custom bindings or codecs;
  • chunked netty-http messages and protocol=proxy;
  • performInvocation and the Custom binding of cxfrs;
  • one-way SOAP operations;
  • atmosphere events;
  • a real webhook delegate (read from the Telegram, ClickUp and WhatsApp handlers).

Choices

  • undertow has HTTP and WebSocket under one scheme, picked by the URI. So each side describes both, and the producer output mixes bytes and unchanged, as sql and jdbc do.
  • cxf repeats the RAW entries for MESSAGE, which is an alias of RAW.
  • The consumer of webhook is unknown, as the delegate component decides its body.

Doc fixes

  • jetty, servlet, netty-http: the "Stream" note said that the body can be read only once. By default the consumer gives a stream cache, which can be read again; only disableStreamCache gives the raw stream. The netty-http producer gives a byte[].
  • cxf: the class is org.apache.camel.component.cxf.common.CxfPayload.
  • cxfrs: jakarta.ws.rs.core.Response, not javax.

Open PRs that change these modules (#21800, #22358, #28337, #28352, #28357, #28366, #28369, #28377) do not touch the Endpoint classes or the generated files of this PR.

Bugs found, not fixed here. Filed one JIRA per component: CAMEL-26136 (camel-netty), CAMEL-26137 (camel-netty-http), CAMEL-26138 (camel-http-common), CAMEL-26139 (camel-servlet), CAMEL-26140 (camel-undertow), CAMEL-26141 (camel-atmosphere-websocket), CAMEL-26142 (camel-spring-ws), CAMEL-26143 (camel-cxf), CAMEL-26144 (camel-cxfrs).

  • netty:
    • With the default codec, a failed exchange gets no reply (the exception cannot be encoded), and the client times out. With textline the client gets the error.
    • A reply that is not a String (bytes, a stream, a file, a Map or a POJO) is dropped with a WARN, and the client waits, without end when there is no requestTimeout.
    • useByteBuf=true skips a File, a Map or a POJO with no error ("No payload to send").
    • A producer with sync=false still sets the reply of the server on the exchange after the producer has completed.
  • netty-http:
    • A List reply sends no response and keeps the connection open.
    • With disableStreamCache=true, a route that ends with the request ByteBuf fails with IllegalReferenceCountException, and the client gets no response.
    • sync=false still puts the response on the exchange.
  • jetty, servlet (DefaultHttpBinding of camel-http-common):
    • With chunked=true, the default, a reply of a Map, a List, a POJO or a number gives 200 with an empty body and no error.
    • mapHttpMessageBody=false still maps the body.
    • With disableStreamCache=true, the body of a form POST has already been read by the mapping of the form fields: servlet answers 500 "Stream is closed", jetty gives an empty body.
  • servlet: attachmentMultipartBinding=true fails every request that is not multipart, with 500 "Cannot populate attachments".
  • undertow:
    • A reply of a Map, a List or a POJO gives an empty 200, with only a WARN.
    • An Integer reply or producer body is sent as 4 binary bytes, not as "42".
    • The producer sends a Map, a List or a POJO as an empty POST, with no error.
    • The consumer drops the body of a DELETE and of the other methods that are not POST, PUT or PATCH.
    • The producer gives an empty byte[], not null, for a 204.
  • atmosphere-websocket:
    • WebsocketConsumer.getQueryMap uses nameval[1], so a query parameter without = fails with an ArrayIndexOutOfBoundsException. This was read from the code.
    • useStreaming is documented for sending, but only the consumer uses it.
  • cxf:
    • A POJO reply (and a CXF_MESSAGE reply) of a byte[] gives the SOAP fault "class [B cannot be cast to class [Ljava.lang.Object;". DefaultCxfBinding.populateOutBody checks isArray() and then casts to Object[].
    • The POJO producer splits a body that is not a List: "Hello,World" becomes 2 parameters, and a byte[] one per byte.
    • A CXF_MESSAGE producer sends an empty envelope for a String, byte[], stream or DOM Document body, with no error; a reply of text, a stream or a Document does the same.
    • A Map or null reply gives an empty soap:Body in PAYLOAD, and an empty response in RAW, instead of a fault.
  • cxfrs:
    • With the Default binding, a route that leaves the request body gives 500 "No message body writer has been found for class MessageContentsList".
    • The producer of the HTTP API sends only the first element of a List body.
  • spring-ws:
    • A route that ends with a null body sends the request payload back as the response.
    • A reply that does not convert to a Source (a Map, a raw stream) gives an empty SOAP body without a fault.
    • The producer rejects a File, and a raw InputStream without stream caching.

Local checks

  • The changed modules build, with no change to the generated files after the build.
  • The catalog copies equal their modules.
  • camel-catalog, camel-yaml-dsl-validator and camel-jbang-core tests pass.
  • The Endpoint and Component DSLs regenerate with no change.

🤖 Generated with Claude Code

…, undertow, vertx-websocket, atmosphere-websocket, webhook, cxf, cxfrs, spring-ws and rest-postman

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: Claus Ibsen <claus.ibsen@gmail.com>
@davsclaus davsclaus added this to the 4.24.0 milestone Oct 24, 2026
@davsclaus davsclaus added the enhancement New feature or request label Oct 24, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🌟 Thank you for your contribution to the Apache Camel project! 🌟
🤖 CI automation will test this PR automatically.

🐫 Apache Camel Committers, please review the following items:

  • First-time contributors require MANUAL approval for the GitHub Actions to run
  • You can use the command /component-test (camel-)component-name1 (camel-)component-name2.. to request a test from the test bot although they are normally detected and executed by CI.
  • You can label PRs using skip-tests and test-dependents to fine-tune the checks executed by this PR.
  • Build and test logs are available in the summary page. Only Apache Camel committers have access to the summary.

⚠️ Be careful when sharing logs. Review their contents before sharing them publicly.

@github-actions

Copy link
Copy Markdown
Contributor

🧪 CI tested the following changed modules:

  • catalog/camel-catalog
  • components/camel-atmosphere-websocket
  • components/camel-cxf/camel-cxf-rest
  • components/camel-cxf/camel-cxf-soap
  • components/camel-jetty
  • components/camel-netty-http
  • components/camel-netty
  • components/camel-rest-postman
  • components/camel-servlet
  • components/camel-spring-parent/camel-spring-ws
  • components/camel-undertow
  • components/camel-vertx/camel-vertx-websocket
  • components/camel-webhook

ℹ️ Dependent modules were not tested because the total number of affected modules exceeded the threshold (50). Use the test-dependents label to force testing all dependents.


🔬 Scalpel shadow comparison — Scalpel: 76 of 707 tested, 26 compile-only — current: 76 all tested

Maveniverse Scalpel detected 76 affected modules (current approach: 76).

Skip-tests mode would test 76 modules (13 direct + 64 downstream), skip tests for 26 (generated code, meta-modules)

Modules Scalpel would test (76)
  • camel-a2a ← downstream of org.apache.camel:camel-platform-http-vertx
  • camel-ai-observability ← downstream of org.apache.camel:camel-telemetry
  • camel-as2 ← downstream of org.apache.camel:camel-jetty
  • camel-atmosphere-websocket ← components/camel-atmosphere-websocket/src/generated/resources/META-INF/org/apache/camel/component/atmosphere/websocket/atmosphere-websocket.json, components/camel-atmosphere-websocket/src/main/java/org/apache/camel/component/atmosphere/websocket/WebsocketEndpoint.java
  • camel-clickup ← downstream of org.apache.camel:camel-netty-http
  • camel-consul ← downstream of org.apache.camel:camel-jetty
  • camel-cxf-rest ← components/camel-cxf/camel-cxf-rest/src/generated/resources/META-INF/org/apache/camel/component/cxf/jaxrs/cxfrs.json, components/camel-cxf/camel-cxf-rest/src/main/docs/cxfrs-component.adoc, components/camel-cxf/camel-cxf-rest/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsEndpoint.java
  • camel-cxf-soap ← components/camel-cxf/camel-cxf-soap/src/generated/resources/META-INF/org/apache/camel/component/cxf/jaxws/cxf.json, components/camel-cxf/camel-cxf-soap/src/main/docs/cxf-component.adoc, components/camel-cxf/camel-cxf-soap/src/main/java/org/apache/camel/component/cxf/jaxws/CxfEndpoint.java
  • camel-cxf-spring-rest ← downstream of org.apache.camel:camel-cxf-rest
  • camel-cxf-spring-soap ← downstream of org.apache.camel:camel-cxf-soap
  • camel-cxf-spring-transport ← downstream of org.apache.camel:camel-cxf-transport
  • camel-cxf-transport ← downstream of org.apache.camel:camel-undertow
  • camel-fhir ← downstream of org.apache.camel:camel-hl7
  • camel-hl7 ← downstream of org.apache.camel:camel-netty
  • camel-ibm-watsonx-ai ← downstream of org.apache.camel:camel-vertx-websocket
  • camel-java-joor-dsl ← downstream of org.apache.camel:camel-telegram
  • camel-jbang-mcp ← downstream of org.apache.camel:camel-catalog
  • camel-jbang-plugin-mcp ← downstream of org.apache.camel:camel-jbang-core
  • camel-jbang-plugin-tui ← downstream of org.apache.camel:camel-catalog
  • camel-jbang-plugin-validate ← downstream of org.apache.camel:camel-yaml-dsl-validator
  • camel-jetty ← components/camel-jetty/src/generated/resources/META-INF/org/apache/camel/component/jetty12/jetty.json, components/camel-jetty/src/main/docs/jetty-component.adoc, components/camel-jetty/src/main/java/org/apache/camel/component/jetty12/JettyHttpEndpoint12.java
  • camel-jsonpath ← downstream of org.apache.camel:camel-platform-http-vertx
  • camel-knative-http ← downstream of org.apache.camel:camel-platform-http-vertx
  • camel-langchain4j-agent ← downstream of org.apache.camel:camel-telemetry
  • camel-langchain4j-chat ← downstream of org.apache.camel:camel-telemetry
  • camel-langchain4j-embeddings ← downstream of org.apache.camel:camel-telemetry
  • camel-langchain4j-embeddingstore ← downstream of org.apache.camel:camel-langchain4j-embeddings
  • camel-launcher-container ← downstream of org.apache.camel:camel-launcher
  • camel-lra ← downstream of org.apache.camel:camel-undertow
  • camel-mcp-server ← downstream of org.apache.camel:camel-platform-http-vertx
  • camel-micrometer-observability ← downstream of org.apache.camel:camel-cxf-rest
  • camel-micrometer-prometheus ← downstream of org.apache.camel:camel-platform-http-main
  • camel-netty ← components/camel-netty/src/generated/resources/META-INF/org/apache/camel/component/netty/netty.json, components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyEndpoint.java
  • camel-netty-http ← components/camel-netty-http/src/generated/resources/META-INF/org/apache/camel/component/netty/http/netty-http.json, components/camel-netty-http/src/main/docs/netty-http-component.adoc, components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpEndpoint.java
  • camel-oauth ← downstream of org.apache.camel:camel-netty-http
  • camel-observability-services ← downstream of org.apache.camel:camel-opentelemetry2
  • camel-openai ← downstream of org.apache.camel:camel-telemetry
  • camel-openapi-validator ← downstream of org.apache.camel:camel-rest-openapi
  • camel-opentelemetry ← downstream of org.apache.camel:camel-cxf-rest
  • camel-opentelemetry2 ← downstream of org.apache.camel:camel-cxf-rest
  • camel-platform-http-main ← downstream of org.apache.camel:camel-platform-http-vertx
  • camel-platform-http-vertx ← downstream of org.apache.camel:camel-rest-postman
  • camel-quickfix ← downstream of org.apache.camel:camel-jetty
  • camel-rest-openapi ← downstream of org.apache.camel:camel-netty-http
  • camel-rest-postman ← components/camel-rest-postman/src/generated/resources/META-INF/org/apache/camel/component/rest/postman/rest-postman.json, components/camel-rest-postman/src/main/java/org/apache/camel/component/rest/postman/RestPostmanEndpoint.java
  • camel-restdsl-openapi-plugin ← downstream of org.apache.camel:camel-jetty
  • camel-semantic ← downstream of org.apache.camel:camel-xml-io-dsl
  • camel-semantic-openai ← downstream of org.apache.camel:camel-openai
  • camel-semantic-typesafe-ai ← downstream of org.apache.camel:camel-xml-io-dsl
  • camel-semantic-wolf-defender ← downstream of org.apache.camel:camel-semantic
  • camel-servlet ← components/camel-servlet/src/generated/resources/META-INF/org/apache/camel/component/servlet/servlet.json, components/camel-servlet/src/main/docs/servlet-component.adoc, components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletEndpoint.java
  • camel-slack ← downstream of org.apache.camel:camel-undertow
  • camel-soap ← downstream of org.apache.camel:camel-cxf-soap
  • camel-spring-ai-chat ← downstream of org.apache.camel:camel-telemetry
  • camel-spring-ws ← components/camel-spring-parent/camel-spring-ws/src/generated/resources/META-INF/org/apache/camel/component/spring/ws/spring-ws.json, components/camel-spring-parent/camel-spring-ws/src/main/java/org/apache/camel/component/spring/ws/SpringWebserviceEndpoint.java
  • camel-state-store ← downstream of org.apache.camel:camel-test-main-junit5
  • camel-syslog ← downstream of org.apache.camel:camel-netty
  • camel-telegram ← downstream of org.apache.camel:camel-netty-http
  • camel-telemetry ← downstream of org.apache.camel:camel-cxf-rest
  • camel-telemetry-dev ← downstream of org.apache.camel:camel-cxf-rest
  • camel-test-main-junit5 ← downstream of org.apache.camel:camel-xml-io-dsl
  • camel-test-main-junit6 ← downstream of org.apache.camel:camel-xml-io-dsl
  • camel-typesafe-ai ← downstream of org.apache.camel:camel-xml-io-dsl
  • camel-undertow ← components/camel-undertow/src/generated/resources/META-INF/org/apache/camel/component/undertow/undertow.json, components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowEndpoint.java
  • camel-undertow-spring-security ← downstream of org.apache.camel:camel-undertow
  • camel-vertx-http ← downstream of org.apache.camel:camel-undertow
  • camel-vertx-websocket ← components/camel-vertx/camel-vertx-websocket/src/generated/resources/META-INF/org/apache/camel/component/vertx/websocket/vertx-websocket.json, components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketEndpoint.java
  • camel-webhook ← components/camel-webhook/src/generated/resources/META-INF/org/apache/camel/component/webhook/webhook.json, components/camel-webhook/src/main/java/org/apache/camel/component/webhook/WebhookEndpoint.java
  • camel-whatsapp ← downstream of org.apache.camel:camel-netty-http
  • camel-xml-io-dsl ← downstream of org.apache.camel:camel-telegram
  • camel-xml-jaxb-dsl ← downstream of org.apache.camel:camel-telegram
  • camel-xml-jaxb-dsl-test-definition ← downstream of org.apache.camel:camel-telegram
  • camel-xml-jaxb-dsl-test-spring ← downstream of org.apache.camel:camel-telegram
  • camel-yaml-dsl-validator ← downstream of org.apache.camel:camel-catalog
  • camel-yaml-dsl-validator-maven-plugin ← downstream of org.apache.camel:camel-yaml-dsl-validator
  • camel-zookeeper ← downstream of org.apache.camel:camel-jetty
Modules with tests skipped (26)
  • apache-camel
  • camel-allcomponents
  • camel-catalog-console
  • camel-catalog-maven
  • camel-catalog-suggest
  • camel-componentdsl
  • camel-endpointdsl
  • camel-endpointdsl-support
  • camel-itest
  • camel-jbang-core
  • camel-jbang-it
  • camel-jbang-main
  • camel-jbang-plugin-edit
  • camel-jbang-plugin-generate
  • camel-jbang-plugin-kubernetes
  • camel-jbang-plugin-test
  • camel-kamelet-main
  • camel-launcher
  • camel-report-maven-plugin
  • camel-route-parser
  • camel-yaml-dsl
  • camel-yaml-dsl-deserializers
  • camel-yaml-dsl-maven-plugin
  • coverage
  • docs
  • dummy-component

ℹ️ Shadow mode — Scalpel observes but does not affect test execution. Learn more

⚠️ Some tests are disabled on GitHub Actions (@DisabledIfSystemProperty(named = "ci.env.name")) and require manual verification:

  • components/camel-jetty: 1 test(s) disabled on GitHub Actions
  • components/camel-netty: 1 test(s) disabled on GitHub Actions
Build reactor — dependencies compiled but only changed modules were tested (13 modules, 3m 2s total)

Total reactor time: 3m 2s

Module Duration Status
Camel :: Jetty 39.8s SUCCESS
Camel :: CXF :: SOAP 32.4s SUCCESS
Camel :: Undertow 24.5s SUCCESS
Camel :: Spring Web Services 16.8s SUCCESS
Camel :: Servlet 13.9s SUCCESS
Camel :: Catalog :: Camel Catalog 12.9s SUCCESS
Camel :: REST Postman 11.7s SUCCESS
Camel :: Atmosphere WebSocket Servlet 11.5s SUCCESS
Camel :: CXF :: REST 11.3s SUCCESS
Camel :: Webhook 7.0s SUCCESS
Camel :: Netty n/a
Camel :: Netty HTTP n/a
Camel :: Vert.x :: WebSocket n/a

Top 20 slowest modules:

  • Camel :: Jetty (39.8s)
  • Camel :: CXF :: SOAP (32.4s)
  • Camel :: Undertow (24.5s)
  • Camel :: Spring Web Services (16.8s)
  • Camel :: Servlet (13.9s)
  • Camel :: Catalog :: Camel Catalog (12.9s)
  • Camel :: REST Postman (11.7s)
  • Camel :: Atmosphere WebSocket Servlet (11.5s)
  • Camel :: CXF :: REST (11.3s)
  • Camel :: Webhook (7.0s)

⚙️ View full build and test results

davsclaus added a commit that referenced this pull request Oct 24, 2026
…, undertow, cxf, cxfrs, spring-ws and four more (#28395)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: Claus Ibsen <claus.ibsen@gmail.com>
@davsclaus

Copy link
Copy Markdown
Contributor Author

Merged to main as e485925 (squashed with the other CAMEL-24961 body type groups, tested together locally).

Claude Code on behalf of davsclaus

@davsclaus davsclaus closed this Oct 24, 2026
@davsclaus
davsclaus deleted the feature/CAMEL-24961-body-types-http-servers branch October 24, 2026 18:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant