CAMEL-22549: Replace deprecated Exchange getOut/hasOut/setOut with getMessage#22358
CAMEL-22549: Replace deprecated Exchange getOut/hasOut/setOut with getMessage#22358gnodet wants to merge 5 commits intoapache:mainfrom
Conversation
…tMessage Replace usage of deprecated Exchange.getOut(), Exchange.hasOut(), and Exchange.setOut() with Exchange.getMessage() across 32 component files. The getOut/hasOut/setOut API has been deprecated since Camel 3.0 in favor of the unified getMessage() API which returns the current message regardless of direction (in/out). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
🌟 Thank you for your contribution to the Apache Camel project! 🌟 🐫 Apache Camel Committers, please review the following items:
|
gnodet
left a comment
There was a problem hiding this comment.
Claude Code on behalf of Guillaume Nodet
Self-review: inline comments explaining why each change pattern is valid.
| String response = this.endpoint.getBot().sendChat(inputMessage); | ||
| inputMessage.setReply(response); | ||
| exchange.getOut().setBody(inputMessage); | ||
| exchange.getMessage().setBody(inputMessage); |
There was a problem hiding this comment.
Pattern: simple getOut().setBody() → getMessage().setBody()
getOut() lazily creates a new OUT message (copying headers from IN). getMessage() returns the current message (OUT if one exists, otherwise IN). Since no OUT was previously created here, getOut() was creating an OUT just to set a body on it — getMessage() achieves the same result without the unnecessary OUT message creation.
Same pattern applies to: BeanIODataFormat, BindyFixedLengthDataFormat, PGPKeyAccessDataFormat, HL7DataFormat, JcrProducer, Soap11/12DataFormatAdapter, SoapDataFormat, RocketMQReplyManagerSupport, SinkConverter.
| Message out = exchange.getOut(); | ||
| out.copyFrom(in); | ||
| out.setHeader(config.getSignatureHeaderName(), new Base64().encode(signature)); | ||
| exchange.getMessage().setHeader(config.getSignatureHeaderName(), new Base64().encode(signature)); |
There was a problem hiding this comment.
Pattern: removed redundant getOut() + copyFrom(in) + header set
The old code did:
Message out = exchange.getOut(); // creates OUT, copies headers from IN
out.copyFrom(in); // copies body+headers from IN to OUT again
out.setHeader(..., signature); // sets the signature headergetMessage() returns IN directly (since no OUT exists yet), which already has all the headers and body. We just need to set the signature header. The copyFrom was redundant because getOut() already copies headers, and then copyFrom copies everything again.
| // propagate headers | ||
| exchange.getOut().setHeaders(headers); | ||
| exchange.getMessage().setBody(out); | ||
| exchange.getMessage().setHeaders(headers); |
There was a problem hiding this comment.
Pattern: removed redundant header propagation
The old code saved exchange.getIn().getHeaders() into a local var, then did exchange.getOut().setHeaders(headers) to propagate them. Since getMessage() returns the IN message (which already has those headers), the explicit header propagation is unnecessary. We just set the new body and restore headers (which were captured earlier before the body was consumed).
| exchange.getOut().setBody(result.getStdout()); | ||
| exchange.getOut().setHeader(SshConstants.EXIT_VALUE, result.getExitValue()); | ||
| exchange.getOut().setHeader(SshConstants.STDERR, result.getStderr()); | ||
| exchange.getMessage().setBody(result.getStdout()); |
There was a problem hiding this comment.
Pattern: removed explicit getOut().getHeaders().putAll(in.getHeaders())
The old code created an OUT message via getOut() (which already copies headers from IN), then redundantly copied headers again with putAll. With getMessage(), headers are already present on the IN message. Same pattern in SqlStoredProducer.
|
|
||
| Message target = exchange.getPattern().isOutCapable() ? exchange.getOut() : exchange.getIn(); | ||
| target.setBody(result); | ||
| exchange.getMessage().setBody(result); |
There was a problem hiding this comment.
Pattern: isOutCapable ? getOut() : getIn() → getMessage()
getMessage() is the direct replacement for this conditional pattern — it returns the OUT message if one exists, otherwise the IN message. This is exactly what the old conditional was doing manually.
Same pattern in: StAXProcessor, SpringWebserviceProducer.
| exchange.getOut().setHeader(getEndpoint().getOutputHeader(), result); | ||
| } else { | ||
| exchange.getOut().setBody(result); | ||
| if (!getEndpoint().isNoop()) { |
There was a problem hiding this comment.
Refactored logic with redundant header copy removed
The old code: (1) copied IN headers to OUT (getOut().getHeaders().putAll(getIn().getHeaders())), (2) for noop, set body from IN to OUT, (3) for outputHeader, set body from IN + set header, (4) otherwise set result as body. Since getMessage() returns IN (which already has all headers and body), for noop=true we now do nothing (body stays as-is), and for outputHeader we just set the header without re-setting the body.
| if (answer == null && localPart.equals("body")) { | ||
| answer = out.getBody(); | ||
| } | ||
| Message out = exchange.get().getMessage(); |
There was a problem hiding this comment.
Pattern: removed hasOut() guard
The old code checked exchange.hasOut() and only read from OUT if it existed. With getMessage(), we get the current message (OUT if it exists, IN otherwise) — so the guard is unnecessary. The behavior is equivalent: if OUT exists, we read from it; if not, we read from IN.
| public Object evaluate(List list) throws XPathFunctionException { | ||
| if (exchange.get() != null && exchange.get().hasOut()) { | ||
| return exchange.get().getOut().getBody(); | ||
| if (exchange.get() != null) { |
There was a problem hiding this comment.
Same hasOut() guard removal pattern. The old code returned null when no OUT existed; now getMessage() returns IN, and getBody() on IN is valid. The XPath function $out:body now returns the current message body rather than null — which is the correct modern behavior since the in/out distinction is deprecated.
| @Deprecated | ||
| public Message getResponse() { | ||
| return exchange.getOut(); | ||
| return exchange.getMessage(); |
There was a problem hiding this comment.
Pattern: deprecated getResponse() method
The getResponse() method is itself @Deprecated. Using getMessage() instead of getOut() is appropriate since both the method and the underlying API are deprecated. Same change in ognl/RootObject and spel/RootObject.
| @Override | ||
| public Object evaluate(Exchange exchange) { | ||
| return function.apply(exchange.getOut()); | ||
| return function.apply(exchange.getMessage()); |
There was a problem hiding this comment.
These methods (outMessage(), outBody(), outBodyAs()) use getOut() to access the response message. getMessage() is the correct replacement — it returns the response (OUT) if one exists, otherwise the request (IN). All 5 getOut() calls in this file follow this same pattern.
…igration The testResponseCreatesOutMessage tests expected that response.body returns null (because getOut() lazily created an empty OUT message). With getMessage(), response now returns the current message (IN), so response.body correctly returns the IN body. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…d compat The deprecated RootObject.getResponse() method should preserve its original behavior (delegating to getOut()) to maintain backward compatibility. Added @SuppressWarnings("deprecation") since a deprecated method calling another deprecated method is expected. Restored the original tests that verify this deprecated behavior. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…etIn After the exchange has been processed, the response body may be on the OUT message. MinaPayloadHelper.getOut() correctly uses getMessage().getBody() to read the result, while getIn().getBody() would return the original input. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- getIn() → getRequestPayload() (reads exchange.getIn() — the original request) - getOut() → getResponsePayload() (reads exchange.getMessage() — the result) - setIn()/setOut() → setPayload() (unified, uses getMessage()) - Removed unused setOut() method Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
Replace deprecated
Exchange.getOut(),Exchange.hasOut(), andExchange.setOut()calls with the modernExchange.getMessage()API across 29 component files. This is part of the ongoing effort to clean up internal deprecation usage warnings (CAMEL-22549).Changes by pattern:
exchange.getOut().setBody(x)→exchange.getMessage().setBody(x)): Most files follow this patternexchange.getOut().getHeaders().putAll(exchange.getIn().getHeaders())). SincegetMessage()returns IN when no OUT exists, these copies are redundant and were removedexchange.getPattern().isOutCapable() ? exchange.getOut() : exchange.getIn()simplified toexchange.getMessage()UnwrapStreamProcessorkeeps the deprecated API with@SuppressWarnings("deprecation")because it copies full exchange state (in/out/properties) which inherently requires the in/out distinctionDeprecated behavior preserved:
RootObject.getResponse()in camel-ognl, camel-mvel, and camel-spring keeps usinggetOut()with@SuppressWarnings("deprecation")— the method is itself deprecated and should maintain its original contract (lazily creating an OUT message) for backward compatibility until it is removedIntentionally not changed:
getOut()on non-Exchange objects (e.g.,MethodInfo.getOut())Affected components:
camel-beanio, camel-bindy, camel-chatscript, camel-crypto, camel-crypto-pgp, camel-fop, camel-hl7, camel-influxdb, camel-influxdb2, camel-jcr, camel-jooq, camel-mina, camel-mock, camel-mvel, camel-ognl, camel-reactive-streams, camel-rocketmq, camel-smooks, camel-soap, camel-spring, camel-spring-ws, camel-sql, camel-ssh, camel-stax, camel-xmlsecurity, camel-xpath
Claude Code on behalf of Guillaume Nodet