wy471x opened a new pull request, #7173: URL: https://github.com/apache/shenyu/pull/7173
<!-- Fixes #6670 --> Make sure that: - [X] You have read the [contribution guidelines](https://shenyu.apache.org/community/contributor-guide). - [X] You submit test cases (unit or integration tests) that back your changes. - [X] Your local test passed `./mvnw clean install -Dmaven.javadoc.skip=true`. ## Summary `AiResponseTransformerPlugin` built a brand new `ObjectMapper` on every decorated AI response — one inside `AiResponseParser#extractBodyFromAiResponse` and one inside `AiResponseTransformerDecorator#writeWith`'s `flatMap`. A fresh `ObjectMapper` builds its own `TypeFactory`/`SerializerProvider`/cache per instance, so this adds needless CPU and young-gen pressure on a hot path (the decorator runs for every AI-transformed response). The sibling `AiTokenLimiterPlugin` already hoists a static `MAPPER`, so this aligns the two. ### Changes: 1. `AiResponseTransformerPlugin` (`shenyu-plugin-ai/shenyu-plugin-ai-response-transformer/.../AiResponseTransformerPlugin.java:75`) — added a single `private static final ObjectMapper MAPPER = new ObjectMapper();` to the plugin class, following the `AiTokenLimiterPlugin.AiStatisticServerHttpResponse` pattern. 2. `AiResponseParser#extractBodyFromAiResponse` (`:225`) — `new ObjectMapper().readTree(body)` replaced with `MAPPER.readTree(body)` (validation-only call, behaviour unchanged). 3. `AiResponseTransformerDecorator#writeWith` (`:338`, `:345`) — the per-response local `ObjectMapper objectMapper = new ObjectMapper();` removed; `readTree(message)` / `writeValueAsString(messageNode)` now use the shared `MAPPER`. Both nested classes are static, so the single outer-class constant is shared. `ObjectMapper` is thread-safe for read/write operations, so a shared instance is safe here. ### Test Cases: 1. `AiResponseTransformerPluginTest#testExtractBodyFromAiResponseReusesObjectMapper` (new, `.../response/AiResponseTransformerPluginTest.java`) — uses `mockConstruction(ObjectMapper.class)` around an `extractBodyFromAiResponse` call after forcing class initialization, asserting `0` `ObjectMapper` instances are constructed and that the JSON body is still returned correctly. Verified the test fails against the un-fixed code (`expected: <0> but was: <1>`), so it locks the fix in. 2. All 21 pre-existing `AiResponseTransformerPluginTest` cases still pass, covering the decorator JSON-merge path (`testOriginalHeadersRemainWhenTransformedBodyIsInvalid`) and the body/header extraction paths that now use the shared mapper. ## Verification - `mvn -pl shenyu-plugin/shenyu-plugin-ai/shenyu-plugin-ai-response-transformer -am test -Dtest=AiResponseTransformerPluginTest` (JDK 21): `Tests run: 22, Failures: 0, Errors: 0, Skipped: 0`. - `mvn clean install -Dmaven.javadoc.skip=true` (JDK 21): BUILD SUCCESS over the whole reactor (checkstyle + RAT included). Note: the first run hit `HttpShenyuSdkClientTest#testShenyuHttpClient` timing out after 2s against `https://shenyu.apache.org` — an unrelated, network-dependent test in `shenyu-sdk-httpclient`; re-running from that module (`-rf :shenyu-sdk-httpclient`) passed and the remaining 15 modules built green. Fixes #6670 -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
