Skip to content

CAMEL-24117: camel-rest-openapi - Create per-endpoint strategy instance#24783

Merged
davsclaus merged 1 commit into
mainfrom
fix/CAMEL-24117
Jul 16, 2026
Merged

CAMEL-24117: camel-rest-openapi - Create per-endpoint strategy instance#24783
davsclaus merged 1 commit into
mainfrom
fix/CAMEL-24117

Conversation

@davsclaus

Copy link
Copy Markdown
Contributor

Summary

  • Fix shared DefaultRestOpenapiProcessorStrategy instance causing cross-talk between multiple rest().openApi() consumers
  • Each endpoint now gets its own strategy instance (unless the user explicitly supplies a custom one at the component level)
  • Fixes missingOperation/mockIncludePattern overwrite, silent fail-fast loss, and uris list mixing across consumers

Root cause

RestOpenApiComponent.doInit() created ONE DefaultRestOpenapiProcessorStrategy and createEndpoint() shared it across all endpoints. Each consumer's afterPropertiesConfigured() then called setMissingOperation() / setMockIncludePattern() on the shared object — last writer wins. Combined with ServiceHelper.initService idempotency, the second consumer's null missingOperation was never resolved, causing validateOpenApi() to silently skip all fail/ignore/mock branches.

Changes

  • RestOpenApiComponent.createEndpoint(): Create a fresh DefaultRestOpenapiProcessorStrategy per endpoint when no user-supplied custom strategy exists. Share only an explicitly user-supplied strategy.
  • RestOpenApiComponent.doInit(): Remove auto-creation of shared default strategy (no longer needed).

Claude Code on behalf of davsclaus

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

…ce to fix shared state cross-talk

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Claus Ibsen <claus.ibsen@gmail.com>
@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.

@gnodet gnodet left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — correct fix for shared strategy cross-talk.

Verification:

  • DefaultRestOpenapiProcessorStrategy has per-consumer mutable state: uris list (line 77, accumulates HTTP endpoint registrations), missingOperation (line 414), and mockIncludePattern (line 424). Sharing one instance across multiple rest().openApi() consumers causes last-writer-wins on configuration and URI mixing.
  • The fix correctly distinguishes user-supplied (restOpenapiProcessorStrategy != null — field access, not getter) from auto-created strategies. User-supplied strategies are shared as intended; default strategies are created per-endpoint.
  • Removing the auto-creation from doInit() is safe — the field stays null unless explicitly set by the user, and each endpoint gets its own fresh instance in createEndpoint().
  • Compatible with #24782 (lifecycle fix): the component's doStop() handles null via ServiceHelper.stopService(), and per-endpoint strategies are stopped by each endpoint's own doStop().

Reviewed with Claude Code on behalf of @gnodet. This review was generated by an AI agent and may contain inaccuracies; please verify all suggestions before applying.

@github-actions

Copy link
Copy Markdown
Contributor

🧪 CI tested the following changed modules:

  • components/camel-rest-openapi

🔬 Scalpel shadow comparison — Scalpel: 18 tested, 29 compile-only — current: 18 all tested

Maveniverse Scalpel detected 47 affected modules (current approach: 18).

⚠️ Modules only in Scalpel (29)
  • apache-camel
  • camel-allcomponents
  • camel-catalog
  • camel-catalog-console
  • camel-catalog-lucene
  • camel-catalog-maven
  • camel-catalog-suggest
  • camel-componentdsl
  • camel-csimple-maven-plugin
  • 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

Skip-tests mode would test 18 modules (1 direct + 17 downstream), skip tests for 29 (generated code, meta-modules)

Modules Scalpel would test (18)
  • camel-a2a
  • camel-jbang-mcp
  • camel-jbang-plugin-mcp
  • camel-jbang-plugin-route-parser
  • camel-jbang-plugin-tui
  • camel-jbang-plugin-validate
  • camel-jsonpath
  • camel-knative-http
  • camel-launcher-container
  • camel-micrometer-prometheus
  • camel-oauth
  • camel-observability-services
  • camel-openapi-validator
  • camel-platform-http-main
  • camel-platform-http-vertx
  • camel-rest-openapi
  • camel-yaml-dsl-validator
  • camel-yaml-dsl-validator-maven-plugin
Modules with tests skipped (29)
  • apache-camel
  • camel-allcomponents
  • camel-catalog
  • camel-catalog-console
  • camel-catalog-lucene
  • camel-catalog-maven
  • camel-catalog-suggest
  • camel-componentdsl
  • camel-csimple-maven-plugin
  • 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

All tested modules (47 modules)
  • Camel :: AI :: A2A
  • Camel :: All Components Sync point
  • Camel :: Assembly
  • Camel :: Catalog :: CSimple Maven Plugin (deprecated)
  • Camel :: Catalog :: Camel Catalog
  • Camel :: Catalog :: Camel Report Maven Plugin
  • Camel :: Catalog :: Camel Route Parser
  • Camel :: Catalog :: Console
  • Camel :: Catalog :: Dummy Component
  • Camel :: Catalog :: Lucene (deprecated)
  • Camel :: Catalog :: Maven
  • Camel :: Catalog :: Suggest
  • Camel :: Component DSL
  • Camel :: Coverage
  • Camel :: Docs
  • Camel :: Endpoint DSL
  • Camel :: Endpoint DSL :: Support
  • Camel :: Integration Tests
  • Camel :: JBang :: Core
  • Camel :: JBang :: Integration tests
  • Camel :: JBang :: MCP
  • Camel :: JBang :: Main
  • Camel :: JBang :: Plugin :: Edit
  • Camel :: JBang :: Plugin :: Generate
  • Camel :: JBang :: Plugin :: Kubernetes
  • Camel :: JBang :: Plugin :: MCP
  • Camel :: JBang :: Plugin :: Route Parser
  • Camel :: JBang :: Plugin :: TUI
  • Camel :: JBang :: Plugin :: Testing
  • Camel :: JBang :: Plugin :: Validate
  • Camel :: JSon Path
  • Camel :: Kamelet Main
  • Camel :: Knative HTTP
  • Camel :: Launcher
  • Camel :: Launcher :: Container
  • Camel :: Micrometer :: Prometheus
  • Camel :: OAuth
  • Camel :: Observability Services
  • Camel :: OpenAPI :: Validator
  • Camel :: Platform HTTP :: Main
  • Camel :: Platform HTTP :: Vert.x
  • Camel :: REST OpenApi
  • Camel :: YAML DSL
  • Camel :: YAML DSL :: Deserializers
  • Camel :: YAML DSL :: Maven Plugins
  • Camel :: YAML DSL :: Validator
  • Camel :: YAML DSL :: Validator Maven Plugin

⚙️ View full build and test results

@oscerd oscerd left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fix is correct — DefaultRestOpenapiProcessorStrategy holds per-consumer mutable state (uris, missingOperation, producerCache), and on main a single auto-created instance was shared across every endpoint; since ServiceHelper.initService is idempotent, a second consumer's re-init was skipped and uris accumulated (last-writer-wins cross-talk). Creating a fresh instance per endpoint (sharing only an explicitly user-supplied one) is the right fix, and each per-endpoint strategy is init/started/stopped by its owning processor.

One thing before merge: the multi-consumer cross-talk this fixes ships with no regression test — two rest().openApi() consumers asserting their URIs/config don't bleed into each other is exactly the scenario that silently regressed, and it's straightforward to unit-test. Also note the per-endpoint strategies only actually get stopped once #24782 lands (this PR adds no stop path on its own), so the two are best merged together.

Reviewed with Claude Code on behalf of Andrea Cosentino. This review was generated by an AI agent and may contain inaccuracies; please verify all suggestions before applying.

@davsclaus davsclaus added this to the 4.22.0 milestone Jul 16, 2026
@davsclaus davsclaus self-assigned this Jul 16, 2026
@davsclaus davsclaus added the bug Something isn't working label Jul 16, 2026
@davsclaus
davsclaus merged commit 10744f8 into main Jul 16, 2026
5 checks passed
@davsclaus
davsclaus deleted the fix/CAMEL-24117 branch July 16, 2026 13:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants