[
https://issues.apache.org/jira/browse/CAMEL-14610?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18101527#comment-18101527
]
Omar Atie commented on CAMEL-14610:
-----------------------------------
Can I work on the above ? [~davsclaus]
> Create a camel-asyncapi component
> ----------------------------------
>
> Key: CAMEL-14610
> URL: https://issues.apache.org/jira/browse/CAMEL-14610
> Project: Camel
> Issue Type: New Feature
> Reporter: Luca Burgazzoli
> Priority: Major
> Fix For: 4.x
>
>
> We should create a an AsyncAPI ([https://www.asyncapi.com/] ) component,
> similar to the OpenAPI one
> I'd like to propose a new component for contract-first integration with
> *AsyncAPI* (https://www.asyncapi.com/), the event-driven analogue of OpenAPI.
> Camel can integrate with Kafka, AMQP, JMS, MQTT, and other messaging systems
> today through dedicated components (camel-kafka, camel-amqp, camel-jms,
> camel-paho-mqtt, etc.), but routes are configured imperatively. Teams that
> standardize on AsyncAPI specifications currently translate channel/operation
> definitions by hand into Camel endpoint URIs, headers, serializers, and
> topic/queue names. There is no first-class, spec-driven component equivalent
> to xref:camel-rest-openapi[camel-rest-openapi] for asynchronous APIs.
> The idea is a *camel-rest-asyncapi* component (name TBD: camel-asyncapi /
> rest-asyncapi) that reads an AsyncAPI document and configures Camel producers
> and consumers from channel operations — similar to how camel-rest-openapi
> reads OpenAPI and delegates to HTTP-based RestProducerFactory /
> RestOpenApiConsumerFactory implementations.
> rest-asyncapi:orders.asyncapi.yaml#publishOrderCreated
> This follows the pattern already used by camel-rest-openapi (contract-first
> spec → Camel routes → delegate transport component), which is the closest
> analogue in the catalog.
> h2. *Why a dedicated component (vs plain kafka/amqp/jms routes)*
> - *Contract-first development* — channel names, message schemas, and
> operation bindings live in AsyncAPI; routes reference operationId/channel
> instead of hard-coded topic names.
> - *Multi-protocol portability* — the same AsyncAPI document can target
> Kafka, AMQP/RabbitMQ, JMS, MQTT, etc. via protocol bindings and a pluggable
> delegate, instead of rewriting routes per broker.
> - *Reduced drift* — message payload shapes, headers, and content-type come
> from the spec (with optional validation), aligned with OpenAPI request
> validation in rest-openapi.
> - *Consistent Rest DSL entry point* — integrate with Camel Rest DSL /
> contract-first route style already familiar to OpenAPI users.
> - *Documentation & catalog* — auto-generated component docs and metadata
> from the spec, same as other Camel components.
> h2. *Design (initial proposal)*
> - *Both producer and consumer* (like camel-rest-openapi): publish/subscribe
> operations from the AsyncAPI channels section.
> - *URI format:* \{{rest-asyncapi:[specificationPath#]operationId}} (or
> \{{asyncapi:...}} — to be aligned with rest-openapi naming).
> - *Spec loading:* same ResourceHelper patterns as rest-openapi
> (\{{classpath:}}, \{{file:}}, \{{http://}}, \{{ref:}}, \{{bean:}}). Support
> AsyncAPI 2.x and 3.x (exact version matrix TBD).
> - *Delegation model:* resolve a single delegate component implementing a
> new SPI (e.g. \{{AsyncApiProducerFactory}} / \{{AsyncApiConsumerFactory}}),
> analogous to \{{RestProducerFactory}} / \{{RestOpenApiConsumerFactory}}.
> - *Known delegate candidates (phase 1):*
> ** camel-kafka (Kafka bindings)
> ** camel-amqp or camel-spring-rabbitmq (AMQP/RabbitMQ bindings)
> ** (phase 2) camel-jms, camel-paho-mqtt, camel-nats, etc.
> - *Bindings:* honor AsyncAPI protocol bindings where possible (e.g. Kafka
> \{{groupId}}, \{{clientId}}, topic; AMQP \{{queue}}, \{{exchange}}).
> - *Message mapping:* map AsyncAPI message payload to/from Camel Message
> body; optional schema validation (JSON Schema / Avro — TBD).
> - *Tests:* contract-first unit tests with sample AsyncAPI fixtures (Kafka +
> AMQP); Testcontainers where applicable; AssertJ assertions; no
> \{{Thread.sleep()}}.
> - *Docs:* component page, upgrade-guide entry, catalog regeneration.
> h2. *Use Cases*
> {*}Use Case 1: Contract-first Kafka producer from AsyncAPI\{*}
> Publish order events to a Kafka topic defined in AsyncAPI without hard-coding
> topic name or schema in the route.
> {code:java}
> from("direct:newOrder")
> .marshal().json(JsonLibrary.Jackson)
> .to("rest-asyncapi:orders.asyncapi.yaml#publishOrderCreated");
> {code}
> {*}Use Case 2: Contract-first Kafka consumer\{*}
> Consume user-signed-up events from a channel defined in the spec; delegate to
> kafka consumer with groupId from Kafka bindings.
> {code:java}
> from("rest-asyncapi:users.asyncapi.yaml#onUserSignedUp?consumerComponentName=kafka")
> .to("direct:provisionAccount");
> {code}
> {*}Use Case 3: Same spec, different broker (AMQP)\{*}
> Swap transport by changing delegate component — route logic stays tied to
> operationId.
> {code:java}
> from("rest-asyncapi:orders.asyncapi.yaml#publishOrderCreated?componentName=amqp")
> .log("Published via AMQP: ${body}");
> {code}
> {*}Use Case 4: Rest DSL contract-first (mirrors OpenAPI style)\{*}
> Define async API in Rest DSL from the specification document.
> {code:java}
> rest().asyncApi("inventory.asyncapi.yaml");
> from("rest-asyncapi:inventory.asyncapi.yaml#onStockLow")
> .to("direct:reorder");
> {code}
> {*}Use Case 5: Request/message validation against spec\{*}
> Reject malformed payloads before business logic (similar to rest-openapi
> request validation).
> {code:java}
> from("rest-asyncapi:payments.asyncapi.yaml#onPaymentReceived?messageValidationEnabled=true")
> .to("direct:processPayment");
> {code}
> {*}Use Case 6: Multi-channel fan-out from a single integration flow\{*}
> Route one domain event to multiple AsyncAPI operations/channels defined in
> the same spec.
> {code:java}
> from("direct:orderPlaced")
> .multicast()
> .to("rest-asyncapi:orders.asyncapi.yaml#publishOrderCreated",
> "rest-asyncapi:analytics.asyncapi.yaml#trackOrderEvent")
> .end();
> {code}
> {*}Use Case 7: JBang / YAML route with external spec\{*}
> Use AsyncAPI file on classpath in a YAML route without Java boilerplate.
> {code:yaml}
> - route:
> from:
> uri: rest-asyncapi:classpath:events.asyncapi.yaml#onMetricIngested
> parameters:
> consumerComponentName: kafka
> steps:
> - to: direct:aggregateMetrics
> {code}
> h2. *Proposed URI / component options (initial)*
> - \{{specificationPath}} — path/URL to AsyncAPI document (default:
> \{{asyncapi.yaml}} or \{{asyncapi.json}})
> - \{{operationId}} — operation identifier from the spec (URI fragment)
> - \{{componentName}} — delegate messaging component (kafka, amqp, …);
> classpath lookup if omitted
> - \{{consumerComponentName}} — delegate for consumer routes (like
> rest-openapi)
> - \{{host}} / \{{servers}} override — override server URLs from spec when
> environments differ
> - \{{messageValidationEnabled}} — validate message body against AsyncAPI
> message schema (default: false)
> - \{{bindingOverride.*}} — optional overrides for protocol bindings (e.g.
> Kafka groupId, topic)
> h2. *Proposed message headers (initial)*
> - \{{CamelAsyncApiOperationId}} — resolved operation
> - \{{CamelAsyncApiChannel}} — channel name
> - \{{CamelAsyncApiMessageName}} — message type from spec
> - \{{CamelAsyncApiBindingProtocol}} — kafka | amqp | jms | mqtt | …
> - \{{CamelAsyncApiSchemaValidated}} — (out) validation result when enabled
> h2. *Reference implementation notes*
> - Primary reference: \{{components/camel-rest-openapi}} (spec parsing,
> delegate SPI, consumer/producer split, validation hook).
> - Supporting modules: \{{components/camel-openapi-java}} patterns for spec
> loading/processing may inform AsyncAPI parser integration.
> - AsyncAPI ecosystem: official bindings for Kafka, AMQP, MQTT, JMS —
> https://github.com/asyncapi/bindings
> - Code generation exists (AsyncAPI Generator Java templates) but is
> *codegen*, not runtime routing; this component fills the *runtime
> contract-first* gap in Camel.
> h2. *Out of scope (initial MVP)*
> - Full Avro/Protobuf schema registry auto-configuration (bindings are often
> insufficient — see community experience with Spring Kafka/SCS)
> - WebSocket/Socket.IO bindings (could be phase 2)
> - Replacing AsyncAPI Generator — this complements codegen with live routing
> h2. *Deliverables*
> - [ ] New module \{{components/camel-rest-asyncapi}} (name TBD)
> - [ ] SPI for AsyncAPI delegate factories (producer + consumer)
> - [ ] Kafka delegate (phase 1)
> - [ ] AMQP delegate (phase 1 or 1.1)
> - [ ] Sample AsyncAPI fixtures + unit tests
> - [ ] Component documentation + upgrade-guide entry
> - [ ] Register in MojoHelper / catalog / nav
> I'm happy to implement this following the camel-rest-openapi and
> camel-clickhouse layout, with Testcontainers-based tests where applicable,
> AssertJ assertions, and docs. Feedback on naming (camel-asyncapi vs
> camel-rest-asyncapi), MVP protocol set, and URI format is welcome.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)