[ 
https://issues.apache.org/jira/browse/CAMEL-14610?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18101527#comment-18101527
 ] 

Omar Atie edited comment on CAMEL-14610 at 8/4/26 3:14 AM:
-----------------------------------------------------------

Can I work on the above [~davsclaus] , I have updated this Jira ticket with 
details ?


was (Author: JIRAUSER313980):
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)

Reply via email to